[pypy-commit] pypy cpyext-gc-support-2: Test and fix for immortal objects on which we attach a pyobj

arigo pypy.commits at gmail.com
Fri Feb 19 12:09:23 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support-2
Changeset: r82325:1f5a3c24e736
Date: 2016-02-19 18:08 +0100
http://bitbucket.org/pypy/pypy/changeset/1f5a3c24e736/

Log:	Test and fix for immortal objects on which we attach a pyobj

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2973,9 +2973,13 @@
         self.rrc_o_list_old = new_o_list
 
     def _rrc_major_free(self, pyobject, surviving_list, surviving_dict):
+        # The pyobject survives if the corresponding obj survives.
+        # This is true if the obj has one of the following two flags:
+        #  * GCFLAG_VISITED: was seen during tracing
+        #  * GCFLAG_NO_HEAP_PTRS: immortal object never traced (so far)
         intobj = self._pyobj(pyobject).ob_pypy_link
         obj = llmemory.cast_int_to_adr(intobj)
-        if self.header(obj).tid & GCFLAG_VISITED:
+        if self.header(obj).tid & (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS):
             surviving_list.append(pyobject)
             if surviving_dict:
                 surviving_dict.insertclean(obj, pyobject)
diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py
--- a/rpython/memory/gc/test/test_rawrefcount.py
+++ b/rpython/memory/gc/test/test_rawrefcount.py
@@ -29,7 +29,7 @@
         assert count2 - count1 == expected_trigger
 
     def _rawrefcount_pair(self, intval, is_light=False, is_pyobj=False,
-                          create_old=False):
+                          create_old=False, create_immortal=False):
         if is_light:
             rc = REFCNT_FROM_PYPY_LIGHT
         else:
@@ -37,14 +37,19 @@
         self.trigger = []
         self.gc.rawrefcount_init(lambda: self.trigger.append(1))
         #
-        p1 = self.malloc(S)
+        if create_immortal:
+            p1 = lltype.malloc(S, immortal=True)
+        else:
+            p1 = self.malloc(S)
         p1.x = intval
-        if create_old:
+        if create_immortal:
+            self.consider_constant(p1)
+        elif create_old:
             self.stackroots.append(p1)
             self._collect(major=False)
             p1 = self.stackroots.pop()
         p1ref = lltype.cast_opaque_ptr(llmemory.GCREF, p1)
-        r1 = lltype.malloc(PYOBJ_HDR, flavor='raw')
+        r1 = lltype.malloc(PYOBJ_HDR, flavor='raw', immortal=create_immortal)
         r1.ob_refcnt = rc
         r1.ob_pypy_link = 0
         r1addr = llmemory.cast_ptr_to_adr(r1)
@@ -268,3 +273,10 @@
         self.test_pyobject_dies(old=True)
     def test_pyobject_survives_from_obj_old(self):
         self.test_pyobject_survives_from_obj(old=True)
+
+    def test_pyobject_attached_to_prebuilt_obj(self):
+        p1, p1ref, r1, r1addr, check_alive = (
+            self._rawrefcount_pair(42, create_immortal=True))
+        check_alive(0)
+        self._collect(major=True)
+        check_alive(0)


More information about the pypy-commit mailing list