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