Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80296:759b503b97b9
Date: 2015-10-16 21:17 +0200
http://bitbucket.org/pypy/pypy/changeset/759b503b97b9/

Log:    in-progress

diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -18,13 +18,14 @@
     return res
 
 
-def init():
+def init(dealloc_callback=None):
     "NOT_RPYTHON: set up rawrefcount with the GC"
-    global _p_list, _o_list, _adr2pypy, _pypy2ob
+    global _p_list, _o_list, _adr2pypy, _pypy2ob, _dealloc_callback
     _p_list = []
     _o_list = []
     _adr2pypy = [None]
     _pypy2ob = {}
+    _dealloc_callback = dealloc_callback
 
 def create_link_pypy(p, ob):
     "NOT_RPYTHON: a link where the PyPy object contains some or all the data"
@@ -61,8 +62,8 @@
 
 def _collect():
     """NOT_RPYTHON: for tests only.  Emulates a GC collection.
-    Returns the list of ob's whose _Py_Dealloc() should be called,
-    from the O list.
+    Will invoke dealloc_callback() for all objects whose _Py_Dealloc()
+    should be called.
     """
     def detach(ob, wr_list):
         assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY
@@ -105,17 +106,18 @@
             return p
         else:
             ob.c_ob_pypy_link = 0
-            if ob.c_ob_refcnt == REFCNT_FROM_PYPY_DIRECT:
-                pass    # freed
-            elif ob.c_ob_refcnt > REFCNT_FROM_PYPY_DIRECT:
-                ob.c_ob_refcnt -= REFCNT_FROM_PYPY_DIRECT
+            if ob.c_ob_refcnt >= REFCNT_FROM_PYPY_DIRECT:
+                assert ob.c_ob_refcnt == REFCNT_FROM_PYPY_DIRECT
+                lltype.free(ob, flavor='raw')
             else:
+                assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY
+                assert ob.c_ob_refcnt < int(REFCNT_FROM_PYPY_DIRECT * 0.99)
                 ob.c_ob_refcnt -= REFCNT_FROM_PYPY
+                ob.c_ob_pypy_link = 0
                 if ob.c_ob_refcnt == 0:
-                    dealloc.append(ob)
+                    _dealloc_callback(ob)
             return None
 
-    dealloc = []
     _p_list = new_p_list
     for ob, wr in wr_p_list:
         p = attach(ob, wr, _p_list)
@@ -124,19 +126,20 @@
     _o_list = []
     for ob, wr in wr_o_list:
         attach(ob, wr, _o_list)
-    return dealloc
 
 # ____________________________________________________________
 
 class Entry(ExtRegistryEntry):
     _about_ = init
 
-    def compute_result_annotation(self):
-        pass
+    def compute_result_annotation(self, s_dealloc_callback):
+        from rpython.rtyper.llannotation import SomePtr
+        assert isinstance(s_dealloc_callback, SomePtr)   # ll-ptr-to-function
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
-        hop.genop('gc_rawrefcount_init', [])
+        [v_dealloc_callback] = hop.inputargs(hop.args_r[0].lowleveltype)
+        hop.genop('gc_rawrefcount_init', [v_dealloc_callback])
 
 class Entry(ExtRegistryEntry):
     _about_ = (create_link_pypy, create_link_pyobj)
diff --git a/rpython/rlib/test/test_rawrefcount.py 
b/rpython/rlib/test/test_rawrefcount.py
--- a/rpython/rlib/test/test_rawrefcount.py
+++ b/rpython/rlib/test/test_rawrefcount.py
@@ -20,8 +20,7 @@
 
     def test_create_link_pypy(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == None
         rawrefcount.create_link_pypy(p, ob)
@@ -29,11 +28,11 @@
         ob.c_ob_refcnt += REFCNT_FROM_PYPY_DIRECT
         assert rawrefcount.from_obj(PyObject, p) == ob
         assert rawrefcount.to_obj(W_Root, ob) == p
+        lltype.free(ob, flavor='raw')
 
     def test_create_link_pyobj(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == None
         rawrefcount.create_link_pyobj(p, ob)
@@ -41,11 +40,11 @@
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
         assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == p
+        lltype.free(ob, flavor='raw')
 
     def test_collect_p_dies(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY_DIRECT
         assert rawrefcount._p_list == [ob]
@@ -59,8 +58,7 @@
 
     def test_collect_p_keepalive_pyobject(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY_DIRECT
         assert rawrefcount._p_list == [ob]
@@ -75,11 +73,11 @@
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
         assert rawrefcount.from_obj(PyObject, p) == ob
+        lltype.free(ob, flavor='raw')
 
     def test_collect_p_keepalive_w_root(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY_DIRECT
         assert rawrefcount._p_list == [ob]
@@ -91,28 +89,31 @@
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
         assert rawrefcount.from_obj(PyObject, p) == ob
+        lltype.free(ob, flavor='raw')
 
     def test_collect_o_dies(self):
+        dealloc = []; rawrefcount.init(dealloc.append)
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         rawrefcount.create_link_pyobj(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
         assert rawrefcount._o_list == [ob]
         wr_ob = weakref.ref(ob)
         wr_p = weakref.ref(p)
         del ob, p
-        dealloc = rawrefcount._collect()
+        rawrefcount._collect()
         ob = wr_ob()
         assert ob is not None
         assert dealloc == [ob]
         assert rawrefcount._o_list == []
         assert wr_p() is None
+        assert ob.c_ob_refcnt == 0
+        assert ob.c_ob_pypy_link == 0
+        lltype.free(ob, flavor='raw')
 
     def test_collect_o_keepalive_pyobject(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         p.pyobj = ob
         rawrefcount.create_link_pyobj(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
@@ -121,53 +122,54 @@
         wr_p = weakref.ref(p)
         ob.c_ob_refcnt += 1      # <=
         del p
-        dealloc = rawrefcount._collect()
-        assert dealloc == []
+        rawrefcount._collect()
         p = wr_p()
         assert p is None            # was unlinked
         assert ob.c_ob_refcnt == 1    # != REFCNT_FROM_PYPY_OBJECT + 1
         assert rawrefcount._o_list == []
         assert rawrefcount.to_obj(W_Root, ob) == None
+        lltype.free(ob, flavor='raw')
 
     def test_collect_o_keepalive_w_root(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         p.pyobj = ob
         rawrefcount.create_link_pyobj(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
         assert rawrefcount._o_list == [ob]
         wr_ob = weakref.ref(ob)
         del ob       # p remains
-        dealloc = rawrefcount._collect()
-        assert dealloc == []
+        rawrefcount._collect()
         ob = wr_ob()
         assert ob is not None
         assert rawrefcount._o_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
         assert p.pyobj == ob
+        lltype.free(ob, flavor='raw')
 
     def test_collect_s_dies(self):
+        dealloc = []; rawrefcount.init(dealloc.append)
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
         assert rawrefcount._p_list == [ob]
         wr_ob = weakref.ref(ob)
         wr_p = weakref.ref(p)
         del ob, p
-        dealloc = rawrefcount._collect()
+        rawrefcount._collect()
         ob = wr_ob()
         assert ob is not None
         assert dealloc == [ob]
         assert rawrefcount._p_list == []
         assert wr_p() is None
+        assert ob.c_ob_refcnt == 0
+        assert ob.c_ob_pypy_link == 0
+        lltype.free(ob, flavor='raw')
 
     def test_collect_s_keepalive_pyobject(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         p.pyobj = ob
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
@@ -182,20 +184,20 @@
         assert ob is not None and p is not None
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
+        lltype.free(ob, flavor='raw')
 
     def test_collect_s_keepalive_w_root(self):
         p = W_Root(42)
-        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                           track_allocation=False)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
         p.pyobj = ob
         rawrefcount.create_link_pypy(p, ob)
         ob.c_ob_refcnt += REFCNT_FROM_PYPY
         assert rawrefcount._p_list == [ob]
         wr_ob = weakref.ref(ob)
         del ob       # p remains
-        dealloc = rawrefcount._collect()
-        assert dealloc == []
+        rawrefcount._collect()
         ob = wr_ob()
         assert ob is not None
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
+        lltype.free(ob, flavor='raw')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to