1. Pypy
  2. Untitled project
  3. pypy

Commits

Armin Rigo  committed 50c910e

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

  • Participants
  • Parent commits efb9453
  • Branches default

Comments (0)

Files changed (2)

File pypy/rpython/memory/gc/minimark.py

View file
                     (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):
                 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:

File pypy/rpython/memory/test/test_gc.py

View file
         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