[pypy-svn] r49204 - in pypy/dist/pypy/rpython/memory: gc test

arigo at codespeak.net arigo at codespeak.net
Thu Nov 29 14:46:16 CET 2007


Author: arigo
Date: Thu Nov 29 14:46:14 2007
New Revision: 49204

Modified:
   pypy/dist/pypy/rpython/memory/gc/base.py
   pypy/dist/pypy/rpython/memory/gc/generation.py
   pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
Test and fix for a weakref bug in the GenerationGC.


Modified: pypy/dist/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/base.py	Thu Nov 29 14:46:14 2007
@@ -167,6 +167,8 @@
             if not target:
                 freeentry = i
             else:
+                debug_assert(self.get_type_id(llmemory.cast_ptr_to_adr(target))
+                             > 0, "bogus weakref in compute_id()")
                 # record this entry in the dict
                 adr = llmemory.cast_ptr_to_adr(target)
                 self.object_id_dict[adr] = i

Modified: pypy/dist/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/generation.py	Thu Nov 29 14:46:14 2007
@@ -293,9 +293,10 @@
                 if self.is_forwarded(pointing_to):
                     (obj + offset).address[0] = self.get_forwarding_address(
                         pointing_to)
-                    self.objects_with_weakrefs.append(obj)
                 else:
                     (obj + offset).address[0] = NULL
+                    continue    # no need to remember this weakref any longer
+            self.objects_with_weakrefs.append(obj)
 
     def write_barrier(self, oldvalue, newvalue, addr_struct):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:

Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gc.py	Thu Nov 29 14:46:14 2007
@@ -327,6 +327,29 @@
         res = self.interpret(f, [20])  # for GenerationGC, enough for a minor collection
         assert res == 20 + 20
 
+    def test_young_weakref_to_old_object(self):
+        import weakref
+        class A:
+            pass
+        def f(x):
+            a = A()
+            llop.gc__collect(lltype.Void)
+            # 'a' is old, 'ref' is young
+            ref = weakref.ref(a)
+            # now trigger a minor collection
+            all = [None] * x
+            i = 0
+            while i < x:
+                all[i] = [i] * i
+                i += 1
+            # now 'a' is old, but 'ref' did not move
+            assert ref() is a
+            llop.gc__collect(lltype.Void)
+            # now both 'a' and 'ref' have moved
+            return ref() is a
+        res = self.interpret(f, [20])  # for GenerationGC, enough for a minor collection
+        assert res == True
+
     def test_many_weakrefs(self):
         # test for the case where allocating the weakref itself triggers
         # a collection


More information about the pypy-svn mailing list