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

Reply via email to