Author: Armin Rigo <[email protected]>
Branch: cpyext-avoid-roundtrip
Changeset: r92534:10f2a25eb826
Date: 2017-10-01 18:16 +0200
http://bitbucket.org/pypy/pypy/changeset/10f2a25eb826/
Log: (antocuni, ronan, arigo)
Work work work until _Py_Dealloc() can be written in C
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
@@ -1038,7 +1038,7 @@
return wrapper_second_level
-def setup_init_functions(eci, prefix):
+def setup_init_functions(eci, prefix, space):
# jump through hoops to avoid releasing the GIL during initialization
# of the cpyext module. The C functions are called with no wrapper,
# but must not do anything like calling back PyType_Ready(). We
@@ -1055,6 +1055,7 @@
setdefenc = rffi.llexternal('_%s_setfilesystemdefaultencoding' % prefix,
[rffi.CCHARP], lltype.Void,
compilation_info=eci, _nowrapper=True)
+ @init_function
def init_types(space):
from pypy.module.cpyext.typeobject import py_type_ready
from pypy.module.sys.interp_encoding import getfilesystemencoding
@@ -1063,7 +1064,7 @@
py_type_ready(space, get_capsule_type())
s = space.text_w(getfilesystemencoding(space))
setdefenc(rffi.str2charp(s, track_allocation=False)) # "leaks"
- INIT_FUNCTIONS.append(init_types)
+
from pypy.module.posix.interp_posix import add_fork_hook
_reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [],
lltype.Void, compilation_info=eci)
@@ -1071,6 +1072,16 @@
_reinit_tls()
add_fork_hook('child', reinit_tls)
+ state = space.fromcache(State)
+ state.C._Py_Dealloc = rffi.llexternal('_Py_Dealloc',
+ [PyObject], lltype.Void,
+ compilation_info=eci,
+ _nowrapper=True)
+ _, state.C.set_marker = rffi.CExternVariable(
+ Py_ssize_t, '_pypy_rawrefcount_w_marker_deallocating',
+ eci, _nowrapper=True, c_type='Py_ssize_t')
+
+
def init_function(func):
INIT_FUNCTIONS.append(func)
return func
@@ -1190,7 +1201,7 @@
ll2ctypes.lltype2ctypes(func.get_llhelper(space)),
ctypes.c_void_p)
- setup_init_functions(eci, prefix)
+ setup_init_functions(eci, prefix, space)
return modulename.new(ext='')
def attach_recursively(space, static_pyobjs, static_objs_w, attached_objs, i):
@@ -1521,7 +1532,7 @@
relax=True)
deco(func.get_wrapper(space))
- setup_init_functions(eci, prefix)
+ setup_init_functions(eci, prefix, space)
trunk_include = pypydir.dirpath() / 'include'
copy_header_files(cts, trunk_include, use_micronumpy)
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
@@ -49,6 +49,8 @@
PyAPI_FUNC(void) Py_IncRef(PyObject *);
PyAPI_FUNC(void) Py_DecRef(PyObject *);
+extern Py_ssize_t _pypy_rawrefcount_w_marker_deallocating;
+PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
#define Py_CLEAR(op) \
do { \
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
@@ -7,15 +7,16 @@
from pypy.module.cpyext.api import (
cpython_api, bootstrap_function, PyObject, PyObjectP, ADDR,
CANNOT_FAIL, Py_TPFLAGS_HEAPTYPE, PyTypeObjectPtr, is_PyObject,
- PyVarObject)
+ PyVarObject, Py_ssize_t, init_function)
from pypy.module.cpyext.state import State
from pypy.objspace.std.typeobject import W_TypeObject
from pypy.objspace.std.objectobject import W_ObjectObject
-from rpython.rlib.objectmodel import specialize
+from rpython.rlib.objectmodel import specialize, we_are_translated
from rpython.rlib.objectmodel import keepalive_until_here
-from rpython.rtyper.annlowlevel import llhelper
+from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_base_ptr
from rpython.rlib import rawrefcount, jit
from rpython.rlib.debug import fatalerror
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
#________________________________________________________
@@ -316,6 +317,7 @@
@specialize.ll()
def decref(space, obj):
+ from pypy.module.cpyext.api import generic_cpy_call
if is_pyobj(obj):
obj = rffi.cast(PyObject, obj)
if obj:
@@ -323,7 +325,8 @@
assert obj.c_ob_pypy_link == 0 or obj.c_ob_refcnt >
rawrefcount.REFCNT_FROM_PYPY
obj.c_ob_refcnt -= 1
if obj.c_ob_refcnt == 0:
- _Py_Dealloc(space, obj)
+ state = space.fromcache(State)
+ generic_cpy_call(space, state.C._Py_Dealloc, obj)
#else:
# w_obj = rawrefcount.to_obj(W_Root, ref)
# if w_obj is not None:
@@ -331,7 +334,6 @@
else:
get_w_obj_and_decref(space, obj)
-
Py_IncRef = incref # XXX remove me and kill all the Py_IncRef usages from
RPython
Py_DecRef = decref # XXX remove me and kill all the Py_DecRef usages from
RPython
@@ -343,14 +345,12 @@
assert isinstance(w_type, W_TypeObject)
get_typedescr(w_type.layout.typedef).realize(space, obj)
-@cpython_api([PyObject], lltype.Void)
-def _Py_Dealloc(space, obj):
- from pypy.module.cpyext.api import generic_cpy_call
- pto = obj.c_ob_type
- #print >>sys.stderr, "Calling dealloc slot", pto.c_tp_dealloc, "of", obj, \
- # "'s type which is", rffi.charp2str(pto.c_tp_name)
- rawrefcount.mark_deallocating(w_marker_deallocating, obj)
- generic_cpy_call(space, pto.c_tp_dealloc, obj)
+@init_function
+def write_w_marker_deallocating(space):
+ if we_are_translated():
+ llptr = cast_instance_to_base_ptr(w_marker_deallocating)
+ state = space.fromcache(State)
+ state.C.set_marker(rffi.cast(Py_ssize_t, llptr))
@cpython_api([rffi.VOIDP], lltype.Signed, error=CANNOT_FAIL)
def _Py_HashPointer(space, ptr):
diff --git a/pypy/module/cpyext/src/object.c b/pypy/module/cpyext/src/object.c
--- a/pypy/module/cpyext/src/object.c
+++ b/pypy/module/cpyext/src/object.c
@@ -13,3 +13,13 @@
{
Py_XDECREF(o);
}
+
+Py_ssize_t _pypy_rawrefcount_w_marker_deallocating; /* set from pyobject.py */
+
+void _Py_Dealloc(PyObject *obj)
+{
+ PyTypeObject *pto = obj->ob_type;
+ /* this is the same as rawrefcount.mark_deallocating() */
+ obj->ob_pypy_link = _pypy_rawrefcount_w_marker_deallocating;
+ pto->tp_dealloc(obj);
+}
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -14,6 +14,7 @@
self.programname = lltype.nullptr(rffi.CCHARP.TO)
self.version = lltype.nullptr(rffi.CCHARP.TO)
self.builder = None
+ self.C = CNamespace()
def reset(self):
from pypy.module.cpyext.modsupport import PyMethodDef
@@ -168,6 +169,11 @@
return w_mod
+class CNamespace:
+ def _freeze_(self):
+ return True
+
+
def _rawrefcount_perform(space):
from pypy.module.cpyext.pyobject import PyObject, decref
while True:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit