Author: Armin Rigo <[email protected]>
Branch: gc-del
Changeset: r62807:40023a14239a
Date: 2013-03-26 14:51 +0100
http://bitbucket.org/pypy/pypy/changeset/40023a14239a/
Log: A (probable?) fix for the last remaining XXX about finalizers in the
MiniMark GC
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -1978,6 +1978,9 @@
def _follow_references_from_young_object_with_finalizer(self):
self.record_duplicates = True
pending = self.old_objects_pointing_to_young
+ while self.old_objects_with_cards_set.non_empty():
+ pending.append(self.old_objects_with_cards_set.pop())
+ #
while pending.non_empty():
obj = pending.pop()
#debug_print("popping", obj)
@@ -1989,16 +1992,24 @@
pending.append(obj)
pending.append(NULL) # marker
#
+ if self.header(obj).tid & GCFLAG_CARDS_SET != 0:
+ self.old_objects_with_cards_set.append(obj)
+ self.collect_cardrefs_to_nursery()
+ #
if self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS == 0:
self.header(obj).tid |= GCFLAG_TRACK_YOUNG_PTRS
self.trace_and_drag_out_of_nursery(obj)
+ while self.old_objects_with_cards_set.non_empty():
+ pending.append(self.old_objects_with_cards_set.pop())
#
else:
# seen a NULL marker
obj = pending.pop()
#debug_print("adding to scheduled", obj)
self.finalizers_scheduled.append(obj)
- assert not self.old_objects_with_cards_set.non_empty(), "XXX"
+ #
+ ll_assert(not self.old_objects_with_cards_set.non_empty(),
+ "with_finalizer: old_objects_with_cards_set should be empty")
self.record_duplicates = False
@staticmethod
diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py
--- a/rpython/memory/test/test_gc.py
+++ b/rpython/memory/test/test_gc.py
@@ -1059,6 +1059,34 @@
class TestMiniMarkGCCardMarking(TestMiniMarkGC):
GC_PARAMS = {'card_page_indices': 4}
+ def test_finalizer_with_card_marks_array(self):
+ class B(object):
+ pass
+ b = B()
+ b.num_finalized = 0
+ class A(object):
+ def __init__(self, id, next):
+ self.id = id
+ self.next = next
+ rgc.register_finalizer(self.finalizer)
+ def finalizer(self):
+ assert b.num_finalized == self.id
+ b.num_finalized += 1
+ def allocate(x):
+ lst = [None] * 10
+ a0 = A(0, lst)
+ a1 = A(1, None)
+ lst[6] = a1
+ keepalive_until_here(a0)
+ def f(x):
+ allocate(x)
+ llop.gc__collect(lltype.Void)
+ llop.gc__collect(lltype.Void)
+ return b.num_finalized
+ res = self.interpret(f, [2])
+ assert res == 2
+
+
class TestMiniMarkGCLargeNursery(TestMiniMarkGC):
GC_PARAMS = {'nursery_size': 16384*WORD}
def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit