Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80218:b20b38d7dd99
Date: 2015-10-14 21:57 +0200
http://bitbucket.org/pypy/pypy/changeset/b20b38d7dd99/
Log: Yay, the first test passes (in test_api)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -512,7 +512,7 @@
PyObjectStruct = lltype.ForwardReference()
PyObject = lltype.Ptr(PyObjectStruct)
PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyTypeObjectPtr),
- ("ob_pypy_link", llmemory.GCREF))
+ ("ob_pypy_link", lltype.Signed))
PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
cpython_struct('PyObject', PyObjectFields, PyObjectStruct)
PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
diff --git a/pypy/module/cpyext/include/object.h
b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -17,9 +17,9 @@
#define staticforward static
#define PyObject_HEAD \
- long ob_refcnt; \
- struct _typeobject *ob_type; \
- void *ob_pypy_link;
+ Py_ssize_t ob_refcnt; \
+ Py_ssize_t ob_pypy_link; \
+ struct _typeobject *ob_type;
#define PyObject_VAR_HEAD \
PyObject_HEAD \
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -286,13 +286,11 @@
state.py_objects_r2w[ptr] = w_obj
-NULL_GCREF = lltype.nullptr(llmemory.GCREF.TO)
-
def _create_pyobj_from_w_obj(w_obj):
# XXX temp, needs cases
ob = lltype.malloc(PyObject.TO, flavor='raw', track_allocation=False)
ob.c_ob_refcnt = 0
- ob.c_ob_pypy_link = NULL_GCREF
+ ob.c_ob_pypy_link = 0
# ob.c_ob_type = ...
rawrefcount.create_link_pypy(w_obj, ob)
return ob
@@ -309,7 +307,7 @@
return lltype.nullptr(PyObject.TO)
#if isinstance(w_obj, W_CPyExtPlaceHolderObject):
# xxx
- ob = rawrefcount.from_obj(PyObject.TO, w_obj)
+ ob = rawrefcount.from_obj(PyObject, w_obj)
if not ob:
ob = _create_pyobj_from_w_obj(w_obj)
return ob
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -12,16 +12,25 @@
REFCNT_FROM_PYPY_OBJECT = 80 # == 0x50
-_p_list = [] # not rpython
-_o_list = [] # not rpython
-_s_list = [] # not rpython
+def _reset_state():
+ global _p_list, _o_list, _s_list, _adr2pypy
+ _p_list = [] # not rpython
+ _o_list = [] # not rpython
+ _s_list = [] # not rpython
+ _adr2pypy = [None] # not rpython
+_reset_state()
+
+def _build_pypy_link(p):
+ res = len(_adr2pypy)
+ _adr2pypy.append(p)
+ return res
def create_link_pypy(p, ob):
"NOT_RPYTHON: a link where the PyPy object contains all the data"
assert not hasattr(p, '__rawrefcount')
assert not ob.c_ob_pypy_link
- ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+ ob.c_ob_pypy_link = _build_pypy_link(p)
ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
p.__rawrefcount = ob
_p_list.append(ob)
@@ -31,7 +40,7 @@
from_obj() will not work on this 'p'."""
assert not hasattr(p, '__rawrefcount')
assert not ob.c_ob_pypy_link
- ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+ 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)
@@ -41,28 +50,29 @@
from_obj() will not work on this 'p'."""
assert not hasattr(p, '__rawrefcount')
assert not ob.c_ob_pypy_link
- ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+ 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(OBTYPE, p):
+def from_obj(OB_PTR_TYPE, p):
"NOT_RPYTHON"
- null = lltype.nullptr(OBTYPE)
+ null = lltype.nullptr(OB_PTR_TYPE.TO)
ob = getattr(p, '__rawrefcount', null)
- assert lltype.typeOf(ob) == lltype.Ptr(OBTYPE)
+ assert lltype.typeOf(ob) == OB_PTR_TYPE
return ob
@specialize.arg(0)
def to_obj(Class, ob):
- pypy_gcref = ob.c_ob_pypy_link
+ link = ob.c_ob_pypy_link
if we_are_translated():
+ pypy_gcref = lltype.cast_int_to_ptr(llmemory.GCREF, link)
return annlowlevel.cast_gcref_to_instance(Class, pypy_gcref)
else:
- if not pypy_gcref:
+ if link == 0:
return None
- p = rgc.try_cast_gcref_to_instance(Class, pypy_gcref)
- assert p is not None
+ p = _adr2pypy[link]
+ assert isinstance(p, Class)
return p
def _collect():
@@ -73,9 +83,9 @@
def detach(ob, wr_list):
assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
assert ob.c_ob_pypy_link
- p = rgc.try_cast_gcref_to_instance(object, ob.c_ob_pypy_link)
+ p = _adr2pypy[ob.c_ob_pypy_link]
assert p is not None
- ob.c_ob_pypy_link = lltype.nullptr(llmemory.GCREF.TO)
+ _adr2pypy[ob.c_ob_pypy_link] = None
wr_list.append((ob, weakref.ref(p)))
global _p_list, _o_list, _s_list
@@ -85,7 +95,7 @@
if ob.c_ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
new_p_list.append(ob)
else:
- wr_p_list.append(weakref.ref(ob))
+ detach(ob, wr_p_list)
ob = None
_p_list = Ellipsis
@@ -112,18 +122,19 @@
assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
p = wr()
if p is not None:
- ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+ assert ob.c_ob_pypy_link
+ _adr2pypy[ob.c_ob_pypy_link] = p
final_list.append(ob)
else:
ob.c_ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
- if ob.c_ob_refcnt == 0:
+ ob.c_ob_pypy_link = 0
+ if ob.c_ob_refcnt == 0 and dealloc is not None:
dealloc.append(ob)
_p_list = new_p_list
- for wr in wr_p_list:
- ob = wr()
- if ob is not None:
- _p_list.append(ob)
+ dealloc = None
+ for ob, wr in wr_p_list:
+ attach(ob, wr, _p_list)
#
dealloc = []
_s_list = new_s_list
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
@@ -8,45 +8,43 @@
PyObjectS = lltype.Struct('PyObjectS',
('c_ob_refcnt', lltype.Signed),
- ('c_ob_pypy_link', llmemory.GCREF))
+ ('c_ob_pypy_link', lltype.Signed))
PyObject = lltype.Ptr(PyObjectS)
class TestRawRefCount:
def setup_method(self, meth):
- del rawrefcount._p_list[:]
- del rawrefcount._o_list[:]
- del rawrefcount._s_list[:]
+ rawrefcount._reset_state()
def test_create_link_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.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == None
rawrefcount.create_link_pypy(p, ob)
- assert rawrefcount.from_obj(PyObjectS, p) == ob
+ assert rawrefcount.from_obj(PyObject, p) == ob
assert rawrefcount.to_obj(W_Root, ob) == p
def test_create_link_pyobj(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.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == None
rawrefcount.create_link_pyobj(p, ob)
- assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+ assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == p
def test_create_link_shared(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.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == None
rawrefcount.create_link_shared(p, ob)
- assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+ assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
assert rawrefcount.to_obj(W_Root, ob) == p
def test_collect_p_dies(self):
@@ -79,7 +77,7 @@
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
+ assert rawrefcount.from_obj(PyObject, p) == ob
def test_collect_p_keepalive_w_root(self):
p = W_Root(42)
@@ -94,7 +92,7 @@
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
+ assert rawrefcount.from_obj(PyObject, p) == ob
def test_collect_o_dies(self):
p = W_Root(42)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit