[pypy-commit] pypy default: Backout 4543677d758a and abc993e8d795, removing PYPY_GC_LOSTCARD
arigo
noreply at buildbot.pypy.org
Sat Jul 23 22:32:51 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r45915:8fb98ebfdeb3
Date: 2011-07-23 16:19 +0200
http://bitbucket.org/pypy/pypy/changeset/8fb98ebfdeb3/
Log: Backout 4543677d758a and abc993e8d795, removing PYPY_GC_LOSTCARD
again. Will try another approach: inlining the write barrier logic
for GCFLAG_HAS_CARDS in the jit backend code.
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,13 +34,6 @@
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
@@ -205,9 +198,6 @@
# 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
@@ -224,7 +214,6 @@
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):
@@ -246,7 +235,6 @@
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.
@@ -367,10 +355,6 @@
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
@@ -665,7 +649,7 @@
#
else:
# Reserve N extra words containing card bits before the object.
- extra_words = self.card_marking_words_for_length(length) + 1
+ extra_words = self.card_marking_words_for_length(length)
cardheadersize = WORD * extra_words
extra_flags = GCFLAG_HAS_CARDS | GCFLAG_TRACK_YOUNG_PTRS
# note that if 'can_make_young', then card marking will only
@@ -691,15 +675,11 @@
raise MemoryError("cannot allocate large object")
#
# Reserve the card mark bits as a list of single bytes
- # followed by a Signed (the loop is empty in C).
- if cardheadersize > 0:
+ # (the loop is empty in C).
i = 0
- while i < cardheadersize - WORD:
- llarena.arena_reserve(arena + i,
- llmemory.sizeof(lltype.Char))
+ while i < cardheadersize:
+ 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
@@ -923,11 +903,14 @@
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',
+ "the card marker bits are not cleared")
i -= 1
- ll_assert(self.get_card(obj, i).char[0] == '\x00',
- "the card marker bits are not cleared")
# ----------
# Write barrier
@@ -1025,8 +1008,6 @@
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
@@ -1044,6 +1025,10 @@
# 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
@@ -1072,8 +1057,6 @@
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
@@ -1086,6 +1069,10 @@
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
@@ -1103,36 +1090,11 @@
self.remember_young_pointer_from_array3 = (
remember_young_pointer_from_array3)
- def get_card_counter_addr(self, obj):
+ def get_card(self, obj, byteindex):
size_gc_header = self.gcheaderbuilder.size_gc_header
addr_byte = obj - size_gc_header
- return llarena.getfakearenaaddress(addr_byte) - WORD
+ return llarena.getfakearenaaddress(addr_byte) + (~byteindex)
- 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'
@@ -1205,7 +1167,10 @@
addr_dstbyte.char[0] = chr(ord(addr_dstbyte.char[0]) | byte)
i += 1
#
- self.set_cards_flag(dest_addr)
+ 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
# ----------
# Nursery collection
@@ -1299,7 +1264,6 @@
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
@@ -1638,7 +1602,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) + 1
+ extra_words = self.card_marking_words_for_length(length)
arena -= extra_words * WORD
allocsize += extra_words * WORD
#
More information about the pypy-commit
mailing list