Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r59858:50c910edeafa
Date: 2013-01-07 23:07 +0100
http://bitbucket.org/pypy/pypy/changeset/50c910edeafa/

Log:    Test and fix for issue #1353: weakref to prebuilt object.

diff --git a/pypy/rpython/memory/gc/minimark.py 
b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -2000,6 +2000,17 @@
                     (obj + offset).address[0] = llmemory.NULL
                     continue    # no need to remember this weakref any longer
             #
+            elif self.header(pointing_to).tid & GCFLAG_NO_HEAP_PTRS:
+                # see test_weakref_to_prebuilt: it's not useful to put
+                # weakrefs into 'old_objects_with_weakrefs' if they point
+                # to a prebuilt object (they are immortal).  If moreover
+                # the 'pointing_to' prebuilt object still has the
+                # GCFLAG_NO_HEAP_PTRS flag, then it's even wrong, because
+                # 'pointing_to' will not get the GCFLAG_VISITED during
+                # the next major collection.  Solve this by not registering
+                # the weakref into 'old_objects_with_weakrefs'.
+                continue
+            #
             self.old_objects_with_weakrefs.append(obj)
 
     def invalidate_old_weakrefs(self):
@@ -2013,6 +2024,9 @@
                 continue # weakref itself dies
             offset = self.weakpointer_offset(self.get_type_id(obj))
             pointing_to = (obj + offset).address[0]
+            ll_assert((self.header(pointing_to).tid & GCFLAG_NO_HEAP_PTRS)
+                      == 0, "registered old weakref should not "
+                            "point to a NO_HEAP_PTRS obj")
             if self.header(pointing_to).tid & GCFLAG_VISITED:
                 new_with_weakref.append(obj)
             else:
diff --git a/pypy/rpython/memory/test/test_gc.py 
b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -557,6 +557,19 @@
         res = self.interpret(f, [20])  # for GenerationGC, enough for a minor 
collection
         assert res == True
 
+    def test_weakref_to_prebuilt(self):
+        import weakref
+        class A:
+            pass
+        a = A()
+        def f(x):
+            ref = weakref.ref(a)
+            assert ref() is a
+            llop.gc__collect(lltype.Void)
+            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
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to