[pypy-commit] pypy default: merge heads
arigo
noreply at buildbot.pypy.org
Fri Jul 15 13:29:46 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r45617:315507ad0fc2
Date: 2011-07-15 13:28 +0200
http://bitbucket.org/pypy/pypy/changeset/315507ad0fc2/
Log: merge heads
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -34,6 +34,13 @@
the GC in very small programs. Defaults to 8
times the nursery.
+ PYPY_GC_LOSTCARD If between two minor collections we see more than
+ 'PYPY_GC_LOSTCARD * length' writes to the same array,
+ then give up card marking and use the fast write
+ barrier instead. Defaults to 0.3333 for now.
+ Avoid values lower than 0.125: it is the growth
+ factor of list.append().
+
PYPY_GC_DEBUG Enable extra checks around collections that are
too slow for normal use. Values are 0 (off),
1 (on major collections) or 2 (also on minor
@@ -198,6 +205,9 @@
# larger. A value of 0 disables card marking.
"card_page_indices": 128,
+ # See PYPY_GC_LOSTCARD.
+ "lost_card": 1.0 / 3.0,
+
# Objects whose total size is at least 'large_object' bytes are
# allocated out of the nursery immediately, as old objects. The
# minimal allocated size of the nursery is 2x the following
@@ -214,6 +224,7 @@
major_collection_threshold=2.5,
growth_rate_max=2.5, # for tests
card_page_indices=0,
+ lost_card=0.5,
large_object=8*WORD,
ArenaCollectionClass=None,
**kwds):
@@ -235,6 +246,7 @@
self.card_page_shift = 0
while (1 << self.card_page_shift) < self.card_page_indices:
self.card_page_shift += 1
+ self.lost_card = lost_card
#
# 'large_object' limit how big objects can be in the nursery, so
# it gives a lower bound on the allowed size of the nursery.
@@ -355,6 +367,10 @@
else:
self.max_delta = 0.125 * env.get_total_memory()
#
+ lost_card = env.read_float_from_env('PYPY_GC_LOSTCARD')
+ if lost_card > 0.0:
+ self.lost_card = lost_card
+ #
self.minor_collection() # to empty the nursery
llarena.arena_free(self.nursery)
self.nursery_size = newsize
@@ -649,7 +665,7 @@
#
else:
# Reserve N extra words containing card bits before the object.
- extra_words = self.card_marking_words_for_length(length)
+ extra_words = self.card_marking_words_for_length(length) + 1
cardheadersize = WORD * extra_words
extra_flags = GCFLAG_HAS_CARDS | GCFLAG_TRACK_YOUNG_PTRS
# note that if 'can_make_young', then card marking will only
@@ -675,11 +691,15 @@
raise MemoryError("cannot allocate large object")
#
# Reserve the card mark bits as a list of single bytes
- # (the loop is empty in C).
- i = 0
- while i < cardheadersize:
- llarena.arena_reserve(arena + i, llmemory.sizeof(lltype.Char))
- i += 1
+ # followed by a Signed (the loop is empty in C).
+ if cardheadersize > 0:
+ i = 0
+ while i < cardheadersize - WORD:
+ llarena.arena_reserve(arena + i,
+ llmemory.sizeof(lltype.Char))
+ i += 1
+ llarena.arena_reserve(arena + i,
+ llmemory.sizeof(lltype.Signed))
#
# Reserve the actual object. (This is also a no-op in C).
result = arena + cardheadersize
@@ -903,14 +923,11 @@
length = (obj + offset_to_length).signed[0]
extra_words = self.card_marking_words_for_length(length)
#
- size_gc_header = self.gcheaderbuilder.size_gc_header
- p = llarena.getfakearenaaddress(obj - size_gc_header)
i = extra_words * WORD
while i > 0:
- p -= 1
- ll_assert(p.char[0] == '\x00',
+ i -= 1
+ ll_assert(self.get_card(obj, i).char[0] == '\x00',
"the card marker bits are not cleared")
- i -= 1
# ----------
# Write barrier
@@ -1008,6 +1025,8 @@
self.prebuilt_root_objects.append(addr_array)
return
#
+ self.set_cards_flag(addr_array)
+ #
# 'addr_array' is a raw_malloc'ed array with card markers
# in front. Compute the index of the bit to set:
bitindex = index >> self.card_page_shift
@@ -1025,10 +1044,6 @@
# it seems more important that remember_young_pointer_from_array2()
# does not take 3 arguments).
addr_byte.char[0] = chr(byte | bitmask)
- #
- if objhdr.tid & GCFLAG_CARDS_SET == 0:
- self.objects_with_cards_set.append(addr_array)
- objhdr.tid |= GCFLAG_CARDS_SET
remember_young_pointer_from_array2._dont_inline_ = True
assert self.card_page_indices > 0
@@ -1057,6 +1072,8 @@
if not self.appears_to_be_young(newvalue):
return
#
+ self.set_cards_flag(addr_array)
+ #
# 'addr_array' is a raw_malloc'ed array with card markers
# in front. Compute the index of the bit to set:
bitindex = index >> self.card_page_shift
@@ -1069,10 +1086,6 @@
if byte & bitmask:
return
addr_byte.char[0] = chr(byte | bitmask)
- #
- if objhdr.tid & GCFLAG_CARDS_SET == 0:
- self.objects_with_cards_set.append(addr_array)
- objhdr.tid |= GCFLAG_CARDS_SET
return
#
# Logic for the no-cards case, put here to minimize the number
@@ -1090,11 +1103,36 @@
self.remember_young_pointer_from_array3 = (
remember_young_pointer_from_array3)
- def get_card(self, obj, byteindex):
+ def get_card_counter_addr(self, obj):
size_gc_header = self.gcheaderbuilder.size_gc_header
addr_byte = obj - size_gc_header
- return llarena.getfakearenaaddress(addr_byte) + (~byteindex)
+ return llarena.getfakearenaaddress(addr_byte) - WORD
+ def get_card(self, obj, byteindex):
+ return self.get_card_counter_addr(obj) + (~byteindex)
+
+ def set_cards_flag(self, obj):
+ hdr = self.header(obj)
+ if hdr.tid & GCFLAG_CARDS_SET == 0:
+ #
+ # first time we set a card bit in this object
+ self.header(obj).tid |= GCFLAG_CARDS_SET
+ self.objects_with_cards_set.append(obj)
+ #
+ # initialize the counter with the array length and self.lost_card
+ typeid = self.get_type_id(obj)
+ offset_to_length = self.varsize_offset_to_length(typeid)
+ length = (obj + offset_to_length).signed[0]
+ counter = int(length * self.lost_card)
+ self.get_card_counter_addr(obj).signed[0] = counter
+ else:
+ # decrement the counter and if zero is reached, give up on
+ # card marking (up to the next collection).
+ addr = self.get_card_counter_addr(obj)
+ addr.signed[0] -= 1
+ if addr.signed[0] < 0:
+ self.objects_pointing_to_young.append(obj)
+ hdr.tid &= ~GCFLAG_TRACK_YOUNG_PTRS
def assume_young_pointers(self, addr_struct):
"""Called occasionally by the JIT to mean ``assume that 'addr_struct'
@@ -1167,10 +1205,7 @@
addr_dstbyte.char[0] = chr(ord(addr_dstbyte.char[0]) | byte)
i += 1
#
- dest_hdr = self.header(dest_addr)
- if dest_hdr.tid & GCFLAG_CARDS_SET == 0:
- self.objects_with_cards_set.append(dest_addr)
- dest_hdr.tid |= GCFLAG_CARDS_SET
+ self.set_cards_flag(dest_addr)
# ----------
# Nursery collection
@@ -1264,6 +1299,7 @@
length = (obj + offset_to_length).signed[0]
bytes = self.card_marking_bytes_for_length(length)
p = llarena.getfakearenaaddress(obj - size_gc_header)
+ p -= WORD
#
# If the object doesn't have GCFLAG_TRACK_YOUNG_PTRS, then it
# means that it is in 'objects_pointing_to_young' and
@@ -1602,7 +1638,7 @@
"GCFLAG_HAS_CARDS but not has_gcptr_in_varsize")
offset_to_length = self.varsize_offset_to_length(typeid)
length = (obj + offset_to_length).signed[0]
- extra_words = self.card_marking_words_for_length(length)
+ extra_words = self.card_marking_words_for_length(length) + 1
arena -= extra_words * WORD
allocsize += extra_words * WORD
#
More information about the pypy-commit
mailing list