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