Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit