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

arigo at codespeak.net arigo at codespeak.net
Wed Nov 17 11:58:02 CET 2010


Author: arigo
Date: Wed Nov 17 11:58:00 2010
New Revision: 79183

Modified:
   pypy/branch/jit-free/pypy/rpython/lltypesystem/llmemory.py
   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/support.py
   pypy/branch/jit-free/pypy/rpython/memory/test/test_gc.py
Log:
Merge r79174-r79182 from trunk.


Modified: pypy/branch/jit-free/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/lltypesystem/llmemory.py	Wed Nov 17 11:58:00 2010
@@ -766,8 +766,10 @@
         return '<%s>' % (self,)
     def __str__(self):
         return 'gctransformed_wref(%s)' % (self._ptr,)
-    def _normalizedcontainer(self):
-        return self._ptr._obj
+    def _normalizedcontainer(self, check=True):
+        return self._ptr._getobj(check=check)._normalizedcontainer(check=check)
+    def _was_freed(self):
+        return self._ptr._was_freed()
 
 # ____________________________________________________________
 

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	Wed Nov 17 11:58:00 2010
@@ -922,7 +922,7 @@
         #
         # Now all live nursery objects should be out.  Update the
         # young weakrefs' targets.
-        if self.young_objects_with_weakrefs.length() > 0:
+        if self.young_objects_with_weakrefs.non_empty():
             self.invalidate_young_weakrefs()
         #
         # Clear this mapping.
@@ -1156,6 +1156,10 @@
         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
@@ -1165,10 +1169,6 @@
         #
         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	Wed Nov 17 11:58:00 2010
@@ -266,10 +266,10 @@
         if self.run_finalizers.non_empty():
             self.update_run_finalizers()
         scan = self.scan_copied(scan)
-        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()
+        if self.objects_with_finalizers.non_empty():
+            scan = self.deal_with_objects_with_finalizers(scan)
         self.update_objects_with_id()
         self.finished_full_collect()
         self.debug_check_consistency()

Modified: pypy/branch/jit-free/pypy/rpython/memory/support.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/memory/support.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/memory/support.py	Wed Nov 17 11:58:00 2010
@@ -112,7 +112,7 @@
                 cur = next
             free_non_gc_object(self)
 
-        def length(self):
+        def _length_estimate(self):
             chunk = self.chunk
             count = self.used_in_last_chunk
             while chunk:
@@ -135,7 +135,7 @@
         foreach._annspecialcase_ = 'specialize:arg(1)'
 
         def stack2dict(self):
-            result = AddressDict(self.length())
+            result = AddressDict(self._length_estimate())
             self.foreach(_add_in_dict, result)
             return result
 

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	Wed Nov 17 11:58:00 2010
@@ -278,6 +278,80 @@
         res = self.interpret(f, [])
         assert res
 
+    def test_bug_1(self):
+        import weakref
+        class B(object):
+            pass
+        def g():
+            b = B()
+            llop.gc__collect(lltype.Void)    # force 'b' to be old
+            ref = weakref.ref(B())
+            b.ref = ref
+            return ref
+        def f():
+            ref = g()
+            llop.gc__collect(lltype.Void)
+            llop.gc__collect(lltype.Void)
+            result = (ref() is None)
+            return result
+        res = self.interpret(f, [])
+        assert res
+
+    def test_cycle_with_weakref_and_del(self):
+        import weakref, gc
+        class A(object):
+            count = 0
+        a = A()
+        class B(object):
+            def __del__(self):
+                # when __del__ is called, the weakref should have been cleared
+                if self.ref() is None:
+                    a.count += 10  # ok
+                else:
+                    a.count = 666  # not ok
+        class C(object):
+            pass
+        def g():
+            c = C()
+            c.b = B()
+            ref = weakref.ref(c)
+            c.b.ref = ref
+            return ref
+        def f():
+            ref = g()
+            llop.gc__collect(lltype.Void)
+            llop.gc__collect(lltype.Void)
+            result = a.count + (ref() is None)
+            return result
+        res = self.interpret(f, [])
+        assert res == 11
+
+    def test_weakref_to_object_with_finalizer_ordering(self):
+        import weakref, gc
+        class A(object):
+            count = 0
+        a = A()
+        class B(object):
+            def __del__(self):
+                # when __del__ is called, the weakref should have been cleared
+                if self.ref() is None:
+                    a.count += 10  # ok
+                else:
+                    a.count = 666  # not ok
+        def g():
+            b = B()
+            ref = weakref.ref(b)
+            b.ref = ref
+            return ref
+        def f():
+            ref = g()
+            llop.gc__collect(lltype.Void)
+            llop.gc__collect(lltype.Void)
+            result = a.count + (ref() is None)
+            return result
+        res = self.interpret(f, [])
+        assert res == 11
+
     def test_id(self):
         class A(object):
             pass
@@ -657,6 +731,9 @@
     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