[pypy-svn] r79238 - in pypy/branch/jit-free/pypy/rpython/memory: gc test

arigo at codespeak.net arigo at codespeak.net
Thu Nov 18 13:34:45 CET 2010


Author: arigo
Date: Thu Nov 18 13:34:43 2010
New Revision: 79238

Modified:
   pypy/branch/jit-free/pypy/rpython/memory/gc/minimark.py
   pypy/branch/jit-free/pypy/rpython/memory/gc/semispace.py
   pypy/branch/jit-free/pypy/rpython/memory/test/test_gc.py
Log:
Merge r79183:79237 from trunk.


Modified: pypy/branch/jit-free/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/memory/gc/minimark.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/memory/gc/minimark.py	Thu Nov 18 13:34:43 2010
@@ -1156,10 +1156,6 @@
         self.collect_roots()
         self.visit_all_objects()
         #
-        # Weakref support: clear the weak pointers to dying objects
-        if self.old_objects_with_weakrefs.non_empty():
-            self.invalidate_old_weakrefs()
-        #
         # Finalizer support: adds the flag GCFLAG_VISITED to all objects
         # with a finalizer and all objects reachable from there (and also
         # moves some objects from 'objects_with_finalizers' to
@@ -1169,6 +1165,10 @@
         #
         self.objects_to_trace.delete()
         #
+        # Weakref support: clear the weak pointers to dying objects
+        if self.old_objects_with_weakrefs.non_empty():
+            self.invalidate_old_weakrefs()
+        #
         # Walk all rawmalloced objects and free the ones that don't
         # have the GCFLAG_VISITED flag.
         self.free_unvisited_rawmalloc_objects()

Modified: pypy/branch/jit-free/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/memory/gc/semispace.py	Thu Nov 18 13:34:43 2010
@@ -266,10 +266,10 @@
         if self.run_finalizers.non_empty():
             self.update_run_finalizers()
         scan = self.scan_copied(scan)
-        if self.objects_with_weakrefs.non_empty():
-            self.invalidate_weakrefs()
         if self.objects_with_finalizers.non_empty():
             scan = self.deal_with_objects_with_finalizers(scan)
+        if self.objects_with_weakrefs.non_empty():
+            self.invalidate_weakrefs()
         self.update_objects_with_id()
         self.finished_full_collect()
         self.debug_check_consistency()

Modified: pypy/branch/jit-free/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/memory/test/test_gc.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/memory/test/test_gc.py	Thu Nov 18 13:34:43 2010
@@ -304,7 +304,7 @@
         a = A()
         class B(object):
             def __del__(self):
-                # when __del__ is called, the weakref should have been cleared
+                # when __del__ is called, the weakref to c should be dead
                 if self.ref() is None:
                     a.count += 10  # ok
                 else:
@@ -333,8 +333,10 @@
         a = A()
         class B(object):
             def __del__(self):
-                # when __del__ is called, the weakref should have been cleared
-                if self.ref() is None:
+                # when __del__ is called, the weakref to myself is still valid
+                # in RPython (at least with most GCs; this test might be
+                # skipped for specific GCs)
+                if self.ref() is self:
                     a.count += 10  # ok
                 else:
                     a.count = 666  # not ok
@@ -352,6 +354,29 @@
         res = self.interpret(f, [])
         assert res == 11
 
+    def test_weakref_bug_1(self):
+        import weakref
+        class A(object):
+            pass
+        class B(object):
+            def __del__(self):
+                self.wref().x += 1
+        def g(a):
+            b = B()
+            b.wref = weakref.ref(a)
+            # the only way to reach this weakref is via B, which is an
+            # object with finalizer (but the weakref itself points to
+            # a, which does not go away but will move during the next
+            # gc.collect)
+        def f():
+            a = A()
+            a.x = 10
+            g(a)
+            llop.gc__collect(lltype.Void)
+            return a.x
+        res = self.interpret(f, [])
+        assert res == 11
+
     def test_id(self):
         class A(object):
             pass
@@ -709,6 +734,9 @@
 class TestMarkSweepGC(GCTest):
     from pypy.rpython.memory.gc.marksweep import MarkSweepGC as GCClass
 
+    def test_weakref_to_object_with_finalizer_ordering(self):
+        py.test.skip("Does not work")
+
 class TestSemiSpaceGC(GCTest, snippet.SemiSpaceGCTests):
     from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass
     GC_CAN_MOVE = True
@@ -731,9 +759,6 @@
     def test_finalizer_order(self):
         py.test.skip("Not implemented yet")
 
-    def test_weakref_to_object_with_finalizer_ordering(self):
-        py.test.skip("Not implemented yet")
-
 class TestHybridGC(TestGenerationalGC):
     from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass
     GC_CAN_MALLOC_NONMOVABLE = True



More information about the Pypy-commit mailing list