Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80192:015de8d029db
Date: 2015-10-14 09:15 +0200
http://bitbucket.org/pypy/pypy/changeset/015de8d029db/

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
@@ -1,6 +1,7 @@
 #
 #  See documentation in pypy/doc/discussion/rawrefcount.rst
 #
+import weakref
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rtyper.extregistry import ExtRegistryEntry
@@ -50,10 +51,24 @@
         assert p is not None
         return p
 
-def collect():
+def _collect():
     "NOT_RPYTHON: for tests only"
+    global _p_list
+    wrlist = []
+    newlist = []
     for ob in _p_list:
-        xxx
+        assert ob.ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
+        if ob.ob_refcnt == REFCNT_FROM_PYPY_OBJECT:
+            wrlist.append(weakref.ref(ob))
+        else:
+            newlist.append(ob)
+    _p_list = newlist
+    del ob
+    rgc.collect()  # forces the cycles to be resolved and the weakrefs to die
+    for wr in wrlist:
+        ob = wr()
+        if ob is not None:
+            newlist.append(ob)
 
 # ____________________________________________________________
 
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
@@ -1,3 +1,4 @@
+import weakref
 from rpython.rlib import rawrefcount
 from rpython.rtyper.lltypesystem import lltype, llmemory
 
@@ -11,22 +12,75 @@
 PyObject = lltype.Ptr(PyObjectS)
 
 
-def test_create_link_from_pypy():
-    p = W_Root(42)
-    ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                       track_allocation=False)
-    assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
-    assert rawrefcount.to_obj(W_Root, ob) == None
-    rawrefcount.create_link_from_pypy(p, ob)
-    assert rawrefcount.from_obj(PyObjectS, p) == ob
-    assert rawrefcount.to_obj(W_Root, ob) == p
+class TestRawRefCount:
 
-def test_create_link_to_pypy():
-    p = W_Root(42)
-    ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
-                       track_allocation=False)
-    assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
-    assert rawrefcount.to_obj(W_Root, ob) == None
-    rawrefcount.create_link_to_pypy(p, ob)
-    assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
-    assert rawrefcount.to_obj(W_Root, ob) == p
+    def setup_method(self, meth):
+        del rawrefcount._p_list[:]
+        del rawrefcount._o_list[:]
+
+    def test_create_link_from_pypy(self):
+        p = W_Root(42)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+                           track_allocation=False)
+        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.to_obj(W_Root, ob) == None
+        rawrefcount.create_link_from_pypy(p, ob)
+        assert rawrefcount.from_obj(PyObjectS, p) == ob
+        assert rawrefcount.to_obj(W_Root, ob) == p
+
+    def test_create_link_to_pypy(self):
+        p = W_Root(42)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+                           track_allocation=False)
+        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.to_obj(W_Root, ob) == None
+        rawrefcount.create_link_to_pypy(p, ob)
+        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.to_obj(W_Root, ob) == p
+
+    def test_collect_dies(self):
+        p = W_Root(42)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+                           track_allocation=False)
+        rawrefcount.create_link_from_pypy(p, ob)
+        assert rawrefcount._p_list == [ob]
+        wr_ob = weakref.ref(ob)
+        wr_p = weakref.ref(p)
+        del ob, p
+        rawrefcount._collect()
+        assert rawrefcount._p_list == []
+        assert wr_ob() is None
+        assert wr_p() is None
+
+    def test_collect_keepalive_pyobject(self):
+        p = W_Root(42)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+                           track_allocation=False)
+        rawrefcount.create_link_from_pypy(p, ob)
+        assert rawrefcount._p_list == [ob]
+        wr_ob = weakref.ref(ob)
+        wr_p = weakref.ref(p)
+        ob.ob_refcnt += 1      # <=
+        del ob, p
+        rawrefcount._collect()
+        ob = wr_ob()
+        p = wr_p()
+        assert ob is not None and p is not None
+        assert rawrefcount._p_list == [ob]
+        assert rawrefcount.to_obj(W_Root, ob) == p
+        assert rawrefcount.from_obj(PyObjectS, p) == ob
+
+    def test_collect_keepalive_w_root(self):
+        p = W_Root(42)
+        ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+                           track_allocation=False)
+        rawrefcount.create_link_from_pypy(p, ob)
+        assert rawrefcount._p_list == [ob]
+        wr_ob = weakref.ref(ob)
+        del ob       # p remains
+        rawrefcount._collect()
+        ob = wr_ob()
+        assert ob is not None
+        assert rawrefcount._p_list == [ob]
+        assert rawrefcount.to_obj(W_Root, ob) == p
+        assert rawrefcount.from_obj(PyObjectS, p) == ob
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to