[pypy-commit] pypy rawrefcount-review: Factor out all interpreter-dependent behaviour into a few GC methods

rlamy pypy.commits at gmail.com
Mon Mar 7 13:41:34 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rawrefcount-review
Changeset: r82864:7daebe814a60
Date: 2016-03-06 00:27 +0000
http://bitbucket.org/pypy/pypy/changeset/7daebe814a60/

Log:	Factor out all interpreter-dependent behaviour into a few GC methods

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
@@ -2775,6 +2775,26 @@
         int_gcobj = self._pyobj(adr_rawobj).ob_pypy_link
         return llmemory.cast_int_to_adr(int_gcobj)
 
+    def _rrc_has_untracked_referents(self, raw_obj):
+        from rpython.rlib.rawrefcount import (
+            REFCNT_FROM_PYPY, REFCNT_FROM_PYPY_LIGHT)
+        rc = self._pyobj(raw_obj).ob_refcnt
+        return rc != REFCNT_FROM_PYPY and rc != REFCNT_FROM_PYPY_LIGHT
+
+    def _rrc_unlink(self, adr_rawobj):
+        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY
+        RC_MASK = REFCNT_FROM_PYPY - 1
+        rawobj = self._pyobj(adr_rawobj)
+        rawobj.ob_refcnt &= RC_MASK
+        rawobj.ob_pypy_link = 0
+
+    def _rrc_is_light(self, adr_rawobj):
+        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT
+        return self._pyobj(adr_rawobj).ob_refcnt >= REFCNT_FROM_PYPY_LIGHT
+
+    def _rrc_dealloc_light(self, adr_rawobj):
+        lltype.free(self._pyobj(adr_rawobj), flavor='raw')
+
     def rawrefcount_init(self, dealloc_trigger_callback):
         # see pypy/doc/discussion/rawrefcount.rst
         if not self.rrc_enabled:
@@ -2844,7 +2864,6 @@
             return self.rrc_dealloc_pending.pop()
         return llmemory.NULL
 
-
     def rrc_invoke_callback(self):
         if self.rrc_enabled and self.rrc_dealloc_pending.non_empty():
             self.rrc_dealloc_trigger_callback()
@@ -2857,13 +2876,7 @@
                                       self.rrc_singleaddr)
 
     def _rrc_minor_trace(self, pyobject, singleaddr):
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT
-        #
-        rc = self._pyobj(pyobject).ob_refcnt
-        if rc == REFCNT_FROM_PYPY or rc == REFCNT_FROM_PYPY_LIGHT:
-            pass     # the corresponding object may die
-        else:
+        if self._rrc_has_untracked_referents(pyobject):
             # force the corresponding object to be alive
             singleaddr.address[0] = self._rrc_get_gc_partner(pyobject)
             self._trace_drag_out(singleaddr, llmemory.NULL)
@@ -2915,40 +2928,20 @@
             self._rrc_free(pyobject)
 
     def _rrc_free(self, pyobject):
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT
-        #
-        rc = self._pyobj(pyobject).ob_refcnt
-        if rc >= REFCNT_FROM_PYPY_LIGHT:
-            rc -= REFCNT_FROM_PYPY_LIGHT
-            if rc == 0:
-                lltype.free(self._pyobj(pyobject), flavor='raw')
-            else:
-                # can only occur if LIGHT is used in create_link_pyobj()
-                self._pyobj(pyobject).ob_refcnt = rc
-                self._pyobj(pyobject).ob_pypy_link = 0
+        if self._rrc_has_untracked_referents(pyobject):
+            self._rrc_unlink(pyobject)
+        elif self._rrc_is_light(pyobject):
+            self._rrc_dealloc_light(pyobject)
         else:
-            ll_assert(rc >= REFCNT_FROM_PYPY, "refcount underflow?")
-            ll_assert(rc < int(REFCNT_FROM_PYPY_LIGHT * 0.99),
-                      "refcount underflow from REFCNT_FROM_PYPY_LIGHT?")
-            rc -= REFCNT_FROM_PYPY
-            self._pyobj(pyobject).ob_refcnt = rc
-            self._pyobj(pyobject).ob_pypy_link = 0
-            if rc == 0:
-                self.rrc_dealloc_pending.append(pyobject)
+            self._rrc_unlink(pyobject)
+            self.rrc_dealloc_pending.append(pyobject)
     _rrc_free._always_inline_ = True
 
     def rrc_major_collection_trace(self):
         self.rrc_p_list_old.foreach(self._rrc_major_trace, None)
 
     def _rrc_major_trace(self, pyobject, ignore):
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY
-        from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT
-        #
-        rc = self._pyobj(pyobject).ob_refcnt
-        if rc == REFCNT_FROM_PYPY or rc == REFCNT_FROM_PYPY_LIGHT:
-            pass     # the corresponding object may die
-        else:
+        if self._rrc_has_untracked_referents(pyobject):
             # force the corresponding object to be alive
             obj = self._rrc_get_gc_partner(pyobject)
             self.objects_to_trace.append(obj)


More information about the pypy-commit mailing list