Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit