Author: Armin Rigo <ar...@tunes.org> Branch: array-overallocation-in-nursery Changeset: r67811:e83aae23c574 Date: 2013-11-03 12:57 +0100 http://bitbucket.org/pypy/pypy/changeset/e83aae23c574/
Log: Test and fix diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -1495,8 +1495,8 @@ # Get the number of card marker bytes in the header. typeid = self.get_type_id(obj) offset_to_length = self.varsize_offset_to_length(typeid) - length = (obj + offset_to_length).signed[0] - bytes = self.card_marking_bytes_for_length(length) + allocated_length = (obj + offset_to_length).signed[0] + bytes = self.card_marking_bytes_for_length(allocated_length) p = llarena.getfakearenaaddress(obj - size_gc_header) # # If the object doesn't have GCFLAG_TRACK_YOUNG_PTRS, then it @@ -1514,6 +1514,9 @@ else: # Walk the bytes encoding the card marker bits, and for # each bit set, call trace_and_drag_out_of_nursery_partial(). + offset_to_used_length = self.varsize_offset_to_used_length( + typeid) + used_length = (obj + offset_to_used_length).signed[0] interval_start = 0 while bytes > 0: p -= 1 @@ -1526,10 +1529,10 @@ interval_stop = interval_start + self.card_page_indices # if cardbyte & 1: - if interval_stop > length: - interval_stop = length - ll_assert(cardbyte <= 1 and bytes == 0, - "premature end of object") + if interval_stop > used_length: + interval_stop = used_length + if interval_stop <= interval_start: + break self.trace_and_drag_out_of_nursery_partial( obj, interval_start, interval_stop) # diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py --- a/rpython/memory/test/snippet.py +++ b/rpython/memory/test/snippet.py @@ -161,6 +161,46 @@ res = self.run('from_objwithfinalizer_to_youngobj') assert res == 1 + def define_overallocated_items_not_kept_alive(cls): + from rpython.rtyper.annlowlevel import cast_instance_to_gcref + from rpython.rtyper.lltypesystem import llmemory + class B: + count = 0 + class A: + def __del__(self): + self.b.count += 1 + ARRAY1 = lltype.GcArray(llmemory.GCREF, hints={'overallocated': True}) + #ARRAY2 = lltype.GcArray(('a', llmemory.GCREF), ('n', lltype.Signed), + # hints={'overallocated': True}) + + def make(b): + a1 = lltype.malloc(ARRAY1, 10) + #a2 = lltype.malloc(ARRAY2, 10) + a1.used_length = 10 + #a2.used_length = 10 + i = 0 + while i < 10: + a = A() + a.b = b + a1[i] = cast_instance_to_gcref(a) + #a2[i].a = cast_instance_to_gcref(a) + i += 1 + return a1 + + def f(): + b = B() + a1 = make(b) + a1.used_length = 0 + #a2.used_length = 0 + llop.gc__collect(lltype.Void) + return b.count + return f + + def test_overallocated_items_not_kept_alive(self): + res = self.run('overallocated_items_not_kept_alive') + assert res == 10 + + class SemiSpaceGCTests(SemiSpaceGCTestDefines): # xxx messy @@ -172,5 +212,8 @@ elif name == 'from_objwithfinalizer_to_youngobj': func = self.define_from_objwithfinalizer_to_youngobj() return self.interpret(func, []) + elif name == 'overallocated_items_not_kept_alive': + func = self.define_overallocated_items_not_kept_alive() + return self.interpret(func, []) else: assert 0, "don't know what to do with that" _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit