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

Reply via email to