Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r84481:039421226913
Date: 2016-05-16 15:27 +0200
http://bitbucket.org/pypy/pypy/changeset/039421226913/

Log:    Don't pass around a string when we're outside the scope of "function
        with the GIL". Instead, we can pass around a raw pointer to an array
        of chars.

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
@@ -732,6 +732,7 @@
 
 class WrapperGen(object):
     wrapper_second_level = None
+    A = lltype.Array(lltype.Char)
 
     def __init__(self, space, signature):
         self.space = space
@@ -744,9 +745,13 @@
         wrapper_second_level = self.wrapper_second_level
 
         name = callable.__name__
+        pname = lltype.malloc(self.A, len(name), flavor='raw', immortal=True)
+        for i in range(len(name)):
+            pname[i] = name[i]
+
         def wrapper(*args):
             # no GC here, not even any GC object
-            return wrapper_second_level(callable, name, *args)
+            return wrapper_second_level(callable, pname, *args)
 
         wrapper.__name__ = "wrapper for %r" % (callable, )
         return wrapper
@@ -754,22 +759,31 @@
 
 
 @dont_inline
+def _unpack_name(pname):
+    return ''.join([pname[i] for i in range(len(pname))])
+
+@dont_inline
 def deadlock_error(funcname):
+    funcname = _unpack_name(funcname)
     fatalerror_notb("GIL deadlock detected when a CPython C extension "
                     "module calls '%s'" % (funcname,))
 
 @dont_inline
 def no_gil_error(funcname):
+    funcname = _unpack_name(funcname)
     fatalerror_notb("GIL not held when a CPython C extension "
                     "module calls '%s'" % (funcname,))
 
 @dont_inline
 def not_supposed_to_fail(funcname):
-    raise SystemError("The function '%s' was not supposed to fail"
-                      % (funcname,))
+    funcname = _unpack_name(funcname)
+    print "Error in cpyext, CPython compatibility layer:"
+    print "The function", funcname, "was not supposed to fail"
+    raise SystemError
 
 @dont_inline
 def unexpected_exception(funcname, e, tb):
+    funcname = _unpack_name(funcname)
     print 'Fatal error in cpyext, CPython compatibility layer, 
calling',funcname
     print 'Either report a bug or consider not using this particular extension'
     if not we_are_translated():
@@ -808,9 +822,8 @@
     def invalid(err):
         "NOT_RPYTHON: translation-time crash if this ends up being called"
         raise ValueError(err)
-    invalid.__name__ = 'invalid_%s' % name
 
-    def wrapper_second_level(callable, name, *args):
+    def wrapper_second_level(callable, pname, *args):
         from pypy.module.cpyext.pyobject import make_ref, from_ref, is_pyobj
         from pypy.module.cpyext.pyobject import as_pyobj
         # we hope that malloc removal removes the newtuple() that is
@@ -821,7 +834,7 @@
         _gil_auto = (gil_auto_workaround and cpyext_glob_tid_ptr[0] != tid)
         if gil_acquire or _gil_auto:
             if cpyext_glob_tid_ptr[0] == tid:
-                deadlock_error(name)
+                deadlock_error(pname)
             rgil.acquire()
             assert cpyext_glob_tid_ptr[0] == 0
         elif pygilstate_ensure:
@@ -834,7 +847,7 @@
                 args += (pystate.PyGILState_UNLOCKED,)
         else:
             if cpyext_glob_tid_ptr[0] != tid:
-                no_gil_error(name)
+                no_gil_error(pname)
             cpyext_glob_tid_ptr[0] = 0
 
         rffi.stackcounter.stacks_counter += 1
@@ -884,7 +897,7 @@
 
             if failed:
                 if error_value is CANNOT_FAIL:
-                    raise not_supposed_to_fail(name)
+                    raise not_supposed_to_fail(pname)
                 retval = error_value
 
             elif is_PyObject(restype):
@@ -904,7 +917,7 @@
                 retval = rffi.cast(restype, result)
 
         except Exception as e:
-            unexpected_exception(name, e, tb)
+            unexpected_exception(pname, e, tb)
             return fatal_value
 
         assert lltype.typeOf(retval) == restype
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -65,6 +65,7 @@
     if ob is None:
         return lltype.nullptr(OB_PTR_TYPE.TO)
     assert lltype.typeOf(ob) == OB_PTR_TYPE
+    assert ob
     return ob
 
 def to_obj(Class, ob):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to