Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support-2
Changeset: r81956:20a0b177ddae
Date: 2016-01-26 23:10 +0100
http://bitbucket.org/pypy/pypy/changeset/20a0b177ddae/
Log: in-progress
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
@@ -37,6 +37,7 @@
from py.builtin import BaseException
from rpython.tool.sourcetools import func_with_new_name
from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rlib import rawrefcount
DEBUG_WRAPPER = True
@@ -825,14 +826,6 @@
outputfilename=str(udir / "module_cache" / "pypyapi"))
modulename = py.path.local(eci.libraries[-1])
- run_bootstrap_functions(space)
-
- # load the bridge, and init structure
- import ctypes
- bridge = ctypes.CDLL(str(modulename), mode=ctypes.RTLD_GLOBAL)
-
- space.fromcache(State).install_dll(eci)
-
def dealloc_trigger():
print 'dealloc_trigger...'
while True:
@@ -845,6 +838,14 @@
return "RETRY"
rawrefcount.init(dealloc_trigger)
+ run_bootstrap_functions(space)
+
+ # load the bridge, and init structure
+ import ctypes
+ bridge = ctypes.CDLL(str(modulename), mode=ctypes.RTLD_GLOBAL)
+
+ space.fromcache(State).install_dll(eci)
+
# populate static data
for name, (typ, expr) in GLOBALS.iteritems():
from pypy.module import cpyext # for the eval() below
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
@@ -13,6 +13,8 @@
from rpython.rlib.objectmodel import specialize, we_are_translated
from rpython.rlib.rweakref import RWeakKeyDictionary
from rpython.rtyper.annlowlevel import llhelper
+from rpython.rlib import rawrefcount
+
#________________________________________________________
# type description
@@ -31,12 +33,13 @@
# similar to PyType_GenericAlloc?
# except that it's not related to any pypy object.
- pytype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type))
+ pytype = get_pyobj_and_incref(space, w_type)
+ pytype = rffi.cast(PyTypeObjectPtr, pytype)
+ assert pytype
# Don't increase refcount for non-heaptypes
- if pytype:
- flags = rffi.cast(lltype.Signed, pytype.c_tp_flags)
- if not flags & Py_TPFLAGS_HEAPTYPE:
- Py_DecRef(space, w_type)
+ flags = rffi.cast(lltype.Signed, pytype.c_tp_flags)
+ if not flags & Py_TPFLAGS_HEAPTYPE:
+ Py_DecRef(space, w_type)
if pytype:
size = pytype.c_tp_basicsize
@@ -158,19 +161,18 @@
#state = space.fromcache(RefcountState)
w_type = space.type(w_obj)
if w_type.is_cpytype():
- py_obj = state.get_from_lifeline(w_obj)
+ ZZZ # py_obj = state.get_from_lifeline(w_obj)
if py_obj:
Py_IncRef(space, py_obj)
return py_obj
typedescr = get_typedescr(w_obj.typedef)
py_obj = typedescr.allocate(space, w_type, itemcount=itemcount)
- if w_type.is_cpytype():
- state.set_lifeline(w_obj, py_obj)
+ track_reference(space, py_obj, w_obj)
typedescr.attach(space, py_obj, w_obj)
return py_obj
-def track_reference(space, py_obj, w_obj, replace=False):
+def track_reference(space, py_obj, w_obj):
"""
Ties together a PyObject and an interpreter object.
"""
@@ -181,8 +183,6 @@
debug_refcount("MAKREF", py_obj, w_obj)
assert w_obj
assert py_obj
- if not replace:
- assert w_obj not in state.py_objects_w2r
rawrefcount.create_link_pypy(py_obj, w_obj)
def make_ref(space, w_obj):
@@ -239,14 +239,17 @@
"""
Returns a 'PyObject *' representing the given intepreter object.
This doesn't give a new reference, but the returned 'PyObject *'
- is valid at least as long as 'w_obj' is. To be safe, you should
- use keepalive_until_here(w_obj) some time later.
-
- NOTE: get_pyobj_and_incref() is safer.
+ is valid at least as long as 'w_obj' is. **To be safe, you should
+ use keepalive_until_here(w_obj) some time later.** In case of
+ doubt, use the safer get_pyobj_and_incref().
"""
if w_obj is not None:
assert not is_pyobj(w_obj)
- return XXXXXXXXXXX
+ py_obj = rawrefcount.from_obj(PyObject, w_obj)
+ if not py_obj:
+ py_obj = create_ref(space, w_obj)
+ #track_reference(space, py_obj, w_obj) -- included with
create_ref()
+ return py_obj
else:
return lltype.nullptr(PyObject.TO)
as_pyobj._always_inline_ = 'try'
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -311,54 +311,12 @@
realize=type_realize,
dealloc=type_dealloc)
- # some types are difficult to create because of cycles.
- # - object.ob_type = type
- # - type.ob_type = type
- # - tuple.ob_type = type
- # - type.tp_base = object
- # - tuple.tp_base = object
- # - type.tp_bases is a tuple
- # - object.tp_bases is a tuple
- # - tuple.tp_bases is a tuple
-
- # we create the types manually here
+ # we create the type "type" manually here, because of the cycle
+ # through its 'c_ob_type' field
py_type = _type_alloc(space, lltype.nullptr(PyTypeObject))
- py_object = _type_alloc(space, lltype.nullptr(PyTypeObject))
- py_tuple = _type_alloc(space, lltype.nullptr(PyTypeObject))
- py_str = _type_alloc(space, lltype.nullptr(PyTypeObject))
- ...
-
- py_type = create_ref(space, space.w_type)
- py_object = create_ref(space, space.w_object)
- py_tuple = create_ref(space, space.w_tuple)
- py_str = create_ref(space, space.w_str)
- # XXX py_str is not initialized here correctly, because we are
- # not tracking it, it gets an empty c_ob_type from py_basestring
-
- # form cycles
- pto_type = rffi.cast(PyTypeObjectPtr, py_type)
- py_type.c_ob_type = pto_type
- py_object.c_ob_type = pto_type
- py_tuple.c_ob_type = pto_type
-
- pto_object = rffi.cast(PyTypeObjectPtr, py_object)
- pto_type.c_tp_base = pto_object
- pto_tuple = rffi.cast(PyTypeObjectPtr, py_tuple)
- pto_tuple.c_tp_base = pto_object
-
- pto_type.c_tp_bases.c_ob_type = pto_tuple
- pto_object.c_tp_bases.c_ob_type = pto_tuple
- pto_tuple.c_tp_bases.c_ob_type = pto_tuple
-
- for typ in (py_type, py_object, py_tuple, py_str):
- heaptype = rffi.cast(PyHeapTypeObject, typ)
- heaptype.c_ht_name.c_ob_type = pto_type
-
- # Restore the mapping
- track_reference(space, py_type, space.w_type, replace=True)
- track_reference(space, py_object, space.w_object, replace=True)
- track_reference(space, py_tuple, space.w_tuple, replace=True)
- track_reference(space, py_str, space.w_str, replace=True)
+ py_type.c_ob_type = rffi.cast(PyTypeObjectPtr, py_type)
+ track_reference(space, py_type, space.w_type)
+ type_attach(space, py_type, space.w_type)
@cpython_api([PyObject], lltype.Void, external=False)
@@ -510,7 +468,7 @@
if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE:
w_typename = space.getattr(w_type, space.wrap('__name__'))
heaptype = rffi.cast(PyHeapTypeObject, pto)
- heaptype.c_ht_name = make_ref(space, w_typename)
+ heaptype.c_ht_name = get_pyobj_and_incref(space, w_typename)
from pypy.module.cpyext.stringobject import PyString_AsString
pto.c_tp_name = PyString_AsString(space, heaptype.c_ht_name)
else:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit