Author: Armin Rigo <[email protected]>
Branch: cpyext-avoid-roundtrip
Changeset: r92550:087ef45836c2
Date: 2017-10-02 12:14 +0200
http://bitbucket.org/pypy/pypy/changeset/087ef45836c2/

Log:    (antocuni, arigo)

        Move subtype_dealloc to C. Lots of messes that might not be
        necessary any more thanks to d519061c7cf0.

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, space):
+def setup_init_functions(eci, prefix):
     # 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
@@ -1072,6 +1072,8 @@
         _reinit_tls()
     add_fork_hook('child', reinit_tls)
 
+
+def attach_c_functions(space, eci):
     state = space.fromcache(State)
     state.C._Py_Dealloc = rffi.llexternal('_Py_Dealloc',
                                          [PyObject], lltype.Void,
@@ -1080,6 +1082,10 @@
     _, state.C.set_marker = rffi.CExternVariable(
                    Py_ssize_t, '_pypy_rawrefcount_w_marker_deallocating',
                    eci, _nowrapper=True, c_type='Py_ssize_t')
+    # XXX meeeeeeeeessssss mmmmmmmmmmmmmmmeeeeeeeeeeeeeeeeeeeeeessssssssssss
+    state.C._PyPy_get_subtype_dealloc = rffi.llexternal(
+        '_PyPy_get_subtype_dealloc', [], rffi.VOIDP,
+        compilation_info=eci, _nowrapper=True)
 
 
 def init_function(func):
@@ -1150,6 +1156,7 @@
     space.fromcache(State).install_dll(eci)
     modulename = py.path.local(eci.libraries[-1])
 
+    attach_c_functions(space, eci)
     run_bootstrap_functions(space)
 
     # load the bridge, and init structure
@@ -1201,7 +1208,7 @@
                 ll2ctypes.lltype2ctypes(func.get_llhelper(space)),
                 ctypes.c_void_p)
 
-    setup_init_functions(eci, prefix, space)
+    setup_init_functions(eci, prefix)
     return modulename.new(ext='')
 
 def attach_recursively(space, static_pyobjs, static_objs_w, attached_objs, i):
@@ -1394,6 +1401,7 @@
                          source_dir / "missing.c",
                          source_dir / "pymem.c",
                          source_dir / "object.c",
+                         source_dir / "typeobject.c",
                          ]
 
 def build_eci(code, use_micronumpy=False, translating=False):
@@ -1488,6 +1496,7 @@
     eci = build_eci(code, use_micronumpy, translating=True)
     space.fromcache(State).install_dll(eci)
 
+    attach_c_functions(space, eci)
     run_bootstrap_functions(space)
 
     # emit uninitialized static data
@@ -1532,7 +1541,7 @@
                                         relax=True)
             deco(func.get_wrapper(space))
 
-    setup_init_functions(eci, prefix, space)
+    setup_init_functions(eci, prefix)
     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
@@ -335,6 +335,7 @@
 PyAPI_FUNC(int) PyPyType_Register(PyTypeObject *);
 #define PyObject_Length PyObject_Size
 #define _PyObject_GC_Del PyObject_GC_Del
+PyAPI_FUNC(void *) _PyPy_get_subtype_dealloc(void);
 
 
 #ifdef __cplusplus
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,7 +7,7 @@
 from pypy.module.cpyext.api import (
     cpython_api, bootstrap_function, PyObject, PyObjectP, ADDR,
     CANNOT_FAIL, Py_TPFLAGS_HEAPTYPE, PyTypeObjectPtr, is_PyObject,
-    PyVarObject, Py_ssize_t, init_function)
+    PyVarObject, Py_ssize_t, init_function, cts)
 from pypy.module.cpyext.state import State
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.objspace.std.objectobject import W_ObjectObject
@@ -27,8 +27,8 @@
     W_BaseObject = W_ObjectObject
 
     def get_dealloc(self, space):
-        from pypy.module.cpyext.typeobject import subtype_dealloc
-        return subtype_dealloc.api_func.get_llhelper(space)
+        state = space.fromcache(State)
+        return cts.cast('destructor', state.C._PyPy_get_subtype_dealloc())
 
     def allocate(self, space, w_type, itemcount=0, immortal=False):
         # typically called from PyType_GenericAlloc via typedescr.allocate
diff --git a/pypy/module/cpyext/src/typeobject.c 
b/pypy/module/cpyext/src/typeobject.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/src/typeobject.c
@@ -0,0 +1,35 @@
+#include "Python.h"
+
+static void subtype_dealloc(PyObject *obj)
+{
+    PyTypeObject *pto = obj->ob_type;
+    PyTypeObject *base = pto;
+    /* This wrapper is created on a specific type, call it w_A.
+       We wish to call the dealloc function from one of the base classes of 
w_A,
+       the first of which is not this function itself.
+       w_obj is an instance of w_A or one of its subclasses. So climb up the
+       inheritance chain until base.c_tp_dealloc is exactly this_func, and then
+       continue on up until they differ.
+       */
+    while (base->tp_dealloc != &subtype_dealloc)
+    {
+        base = base->tp_base;
+        assert(base);
+    }
+    while (base->tp_dealloc == &subtype_dealloc)
+    {
+        base = base->tp_base;
+        assert(base);
+    }
+    /* XXX call tp_del if necessary */
+    base->tp_dealloc(obj);
+    /* XXX cpy decrefs the pto here but we do it in the base-dealloc
+       hopefully this does not clash with the memory model assumed in
+       extension modules */
+}
+
+PyAPI_FUNC(void *)
+_PyPy_get_subtype_dealloc(void)
+{
+    return &subtype_dealloc;
+}
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
@@ -529,36 +529,6 @@
                    realize=type_realize,
                    dealloc=type_dealloc)
 
-@slot_function([PyObject], lltype.Void)
-def subtype_dealloc(space, obj):
-    pto = obj.c_ob_type
-    base = pto
-    this_func_ptr = llslot(space, subtype_dealloc)
-    w_obj = from_ref(space, rffi.cast(PyObject, base))
-    # This wrapper is created on a specific type, call it w_A.
-    # We wish to call the dealloc function from one of the base classes of w_A,
-    # the first of which is not this function itself.
-    # w_obj is an instance of w_A or one of its subclasses. So climb up the
-    # inheritance chain until base.c_tp_dealloc is exactly this_func, and then
-    # continue on up until they differ.
-    #print 'subtype_dealloc, start from', rffi.charp2str(base.c_tp_name)
-    while base.c_tp_dealloc != this_func_ptr:
-        base = base.c_tp_base
-        assert base
-        #print '                 ne move to', rffi.charp2str(base.c_tp_name)
-        w_obj = from_ref(space, rffi.cast(PyObject, base))
-    while base.c_tp_dealloc == this_func_ptr:
-        base = base.c_tp_base
-        assert base
-        #print '                 eq move to', rffi.charp2str(base.c_tp_name)
-        w_obj = from_ref(space, rffi.cast(PyObject, base))
-    #print '                   end with', rffi.charp2str(base.c_tp_name)
-    dealloc = base.c_tp_dealloc
-    # XXX call tp_del if necessary
-    generic_cpy_call(space, dealloc, obj)
-    # XXX cpy decrefs the pto here but we do it in the base-dealloc
-    # hopefully this does not clash with the memory model assumed in
-    # extension modules
 
 @slot_function([PyObject, Py_ssize_tP], lltype.Signed, error=CANNOT_FAIL)
 def bf_segcount(space, w_obj, ref):
@@ -764,7 +734,9 @@
         pto.c_tp_dealloc = pto.c_tp_base.c_tp_dealloc
         if not pto.c_tp_dealloc:
             # strange, but happens (ABCMeta)
-            pto.c_tp_dealloc = llslot(space, subtype_dealloc)
+            state = space.fromcache(State)
+            d = cts.cast('destructor', state.C._PyPy_get_subtype_dealloc())
+            pto.c_tp_dealloc = d
 
     if builder.cpyext_type_init is not None:
         builder.cpyext_type_init.append((pto, w_type))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to