[pypy-commit] pypy cpyext-gc-support: Emulation: works also with objects with __slots__
arigo
noreply at buildbot.pypy.org
Wed Oct 14 16:15:11 EDT 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80219:7988b2e5327d
Date: 2015-10-14 22:12 +0200
http://bitbucket.org/pypy/pypy/changeset/7988b2e5327d/
Log: Emulation: works also with objects with __slots__
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -13,11 +13,12 @@
def _reset_state():
- global _p_list, _o_list, _s_list, _adr2pypy
+ global _p_list, _o_list, _s_list, _adr2pypy, _pypy2ob
_p_list = [] # not rpython
_o_list = [] # not rpython
_s_list = [] # not rpython
_adr2pypy = [None] # not rpython
+ _pypy2ob = {} # not rpython
_reset_state()
def _build_pypy_link(p):
@@ -28,37 +29,36 @@
def create_link_pypy(p, ob):
"NOT_RPYTHON: a link where the PyPy object contains all the data"
- assert not hasattr(p, '__rawrefcount')
+ assert p not in _pypy2ob
assert not ob.c_ob_pypy_link
ob.c_ob_pypy_link = _build_pypy_link(p)
ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
- p.__rawrefcount = ob
+ _pypy2ob[p] = ob
_p_list.append(ob)
def create_link_pyobj(p, ob):
"""NOT_RPYTHON: a link where the PyObject contains all the data.
from_obj() will not work on this 'p'."""
- assert not hasattr(p, '__rawrefcount')
+ assert p not in _pypy2ob
assert not ob.c_ob_pypy_link
ob.c_ob_pypy_link = _build_pypy_link(p)
ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
- p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
_o_list.append(ob)
def create_link_shared(p, ob):
"""NOT_RPYTHON: a link where both p and ob contain some data.
from_obj() will not work on this 'p'."""
- assert not hasattr(p, '__rawrefcount')
+ assert p not in _pypy2ob
assert not ob.c_ob_pypy_link
ob.c_ob_pypy_link = _build_pypy_link(p)
ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
- p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
_s_list.append(ob)
def from_obj(OB_PTR_TYPE, p):
"NOT_RPYTHON"
- null = lltype.nullptr(OB_PTR_TYPE.TO)
- ob = getattr(p, '__rawrefcount', null)
+ ob = _pypy2ob.get(p)
+ if ob is None:
+ return lltype.nullptr(OB_PTR_TYPE.TO)
assert lltype.typeOf(ob) == OB_PTR_TYPE
return ob
@@ -87,6 +87,7 @@
assert p is not None
_adr2pypy[ob.c_ob_pypy_link] = None
wr_list.append((ob, weakref.ref(p)))
+ return p
global _p_list, _o_list, _s_list
wr_p_list = []
@@ -95,7 +96,9 @@
if ob.c_ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
new_p_list.append(ob)
else:
- detach(ob, wr_p_list)
+ p = detach(ob, wr_p_list)
+ del _pypy2ob[p]
+ del p
ob = None
_p_list = Ellipsis
@@ -125,16 +128,20 @@
assert ob.c_ob_pypy_link
_adr2pypy[ob.c_ob_pypy_link] = p
final_list.append(ob)
+ return p
else:
ob.c_ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
ob.c_ob_pypy_link = 0
if ob.c_ob_refcnt == 0 and dealloc is not None:
dealloc.append(ob)
+ return None
_p_list = new_p_list
dealloc = None
for ob, wr in wr_p_list:
- attach(ob, wr, _p_list)
+ p = attach(ob, wr, _p_list)
+ if p:
+ _pypy2ob[p] = ob
#
dealloc = []
_s_list = new_s_list
More information about the pypy-commit
mailing list