Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80193:7dce6c22637b
Date: 2015-10-14 09:36 +0200
http://bitbucket.org/pypy/pypy/changeset/7dce6c22637b/
Log: Collecting the O list
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -52,23 +52,55 @@
return p
def _collect():
- "NOT_RPYTHON: for tests only"
- global _p_list
- wrlist = []
- newlist = []
+ """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.
+ """
+ global _p_list, _o_list
+ wr_p_list = []
+ new_p_list = []
for ob in _p_list:
assert ob.ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
if ob.ob_refcnt == REFCNT_FROM_PYPY_OBJECT:
- wrlist.append(weakref.ref(ob))
+ wr_p_list.append(weakref.ref(ob))
else:
- newlist.append(ob)
- _p_list = newlist
- del ob
+ new_p_list.append(ob)
+ ob = None
+ _p_list = Ellipsis
+ #
+ wr_o_list = []
+ for ob in _o_list:
+ assert ob.ob_pypy_link
+ p = rgc.try_cast_gcref_to_instance(object, ob.ob_pypy_link)
+ assert p is not None
+ ob.ob_pypy_link = lltype.nullptr(llmemory.GCREF.TO)
+ wr_o_list.append((ob, weakref.ref(p)))
+ p = None
+ _o_list = Ellipsis
+ #
rgc.collect() # forces the cycles to be resolved and the weakrefs to die
- for wr in wrlist:
+ rgc.collect()
+ rgc.collect()
+ #
+ _p_list = new_p_list
+ for wr in wr_p_list:
ob = wr()
if ob is not None:
- newlist.append(ob)
+ _p_list.append(ob)
+ #
+ dealloc = []
+ _o_list = []
+ for ob, wr in wr_o_list:
+ p = wr()
+ if p is not None:
+ ob.ob_pypy_link = rgc.cast_instance_to_gcref(p)
+ _o_list.append(ob)
+ else:
+ assert ob.ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
+ ob.ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
+ if ob.ob_refcnt == 0:
+ dealloc.append(ob)
+ return dealloc
# ____________________________________________________________
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
@@ -38,7 +38,7 @@
assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == p
- def test_collect_dies(self):
+ def test_collect_p_dies(self):
p = W_Root(42)
ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
track_allocation=False)
@@ -52,7 +52,7 @@
assert wr_ob() is None
assert wr_p() is None
- def test_collect_keepalive_pyobject(self):
+ def test_collect_p_keepalive_pyobject(self):
p = W_Root(42)
ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
track_allocation=False)
@@ -70,7 +70,7 @@
assert rawrefcount.to_obj(W_Root, ob) == p
assert rawrefcount.from_obj(PyObjectS, p) == ob
- def test_collect_keepalive_w_root(self):
+ def test_collect_p_keepalive_w_root(self):
p = W_Root(42)
ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
track_allocation=False)
@@ -84,3 +84,55 @@
assert rawrefcount._p_list == [ob]
assert rawrefcount.to_obj(W_Root, ob) == p
assert rawrefcount.from_obj(PyObjectS, p) == ob
+
+ def test_collect_o_dies(self):
+ p = W_Root(42)
+ ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+ track_allocation=False)
+ rawrefcount.create_link_to_pypy(p, ob)
+ assert rawrefcount._o_list == [ob]
+ wr_ob = weakref.ref(ob)
+ wr_p = weakref.ref(p)
+ del ob, p
+ dealloc = rawrefcount._collect()
+ ob = wr_ob()
+ assert ob is not None
+ assert dealloc == [ob]
+ assert rawrefcount._o_list == []
+ assert wr_p() is None
+
+ def test_collect_o_keepalive_pyobject(self):
+ p = W_Root(42)
+ ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+ track_allocation=False)
+ p._rawrefcount = ob
+ rawrefcount.create_link_to_pypy(p, ob)
+ assert rawrefcount._o_list == [ob]
+ wr_ob = weakref.ref(ob)
+ wr_p = weakref.ref(p)
+ ob.ob_refcnt += 1 # <=
+ del p
+ dealloc = rawrefcount._collect()
+ assert dealloc == []
+ p = wr_p()
+ assert p is None # was unlinked
+ assert ob.ob_refcnt == 1 # != REFCNT_FROM_PYPY_OBJECT + 1
+ assert rawrefcount._o_list == []
+ assert rawrefcount.to_obj(W_Root, ob) == None
+
+ def test_collect_o_keepalive_w_root(self):
+ p = W_Root(42)
+ ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
+ track_allocation=False)
+ p._rawrefcount = ob
+ rawrefcount.create_link_to_pypy(p, ob)
+ assert rawrefcount._o_list == [ob]
+ wr_ob = weakref.ref(ob)
+ del ob # p remains
+ dealloc = rawrefcount._collect()
+ assert dealloc == []
+ ob = wr_ob()
+ assert ob is not None
+ assert rawrefcount._o_list == [ob]
+ assert rawrefcount.to_obj(W_Root, ob) == p
+ assert p._rawrefcount == ob
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit