[pypy-commit] pypy default: cffi callbacks performance: rweaklist instead of rweakvaluedictionary
arigo
noreply at buildbot.pypy.org
Fri Oct 9 17:56:21 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r80089:178e16fc3032
Date: 2015-10-09 15:20 +0200
http://bitbucket.org/pypy/pypy/changeset/178e16fc3032/
Log: cffi callbacks performance: rweaklist instead of
rweakvaluedictionary
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -3,12 +3,12 @@
"""
import sys, os
-from rpython.rlib import clibffi, rweakref, jit, jit_libffi
-from rpython.rlib.objectmodel import compute_unique_id, keepalive_until_here
+from rpython.rlib import clibffi, jit, jit_libffi
+from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.interpreter.error import OperationError, oefmt
-from pypy.module._cffi_backend import cerrno, misc
+from pypy.module._cffi_backend import cerrno, misc, handle
from pypy.module._cffi_backend.cdataobj import W_CData
from pypy.module._cffi_backend.ctypefunc import SIZE_OF_FFI_ARG, W_CTypeFunc
from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveSigned
@@ -64,8 +64,14 @@
convert_from_object_fficallback(fresult, self._closure.ll_error,
w_error)
#
- self.unique_id = compute_unique_id(self)
- global_callback_mapping.set(self.unique_id, self)
+ # We must setup the GIL here, in case the callback is invoked in
+ # some other non-Pythonic thread. This is the same as cffi on
+ # CPython.
+ if space.config.translation.thread:
+ from pypy.module.thread.os_thread import setup_threads
+ setup_threads(space)
+ #
+ handle_index = handle.get_handles(space).reserve_next_handle_index()
#
cif_descr = self.getfunctype().cif_descr
if not cif_descr:
@@ -74,7 +80,7 @@
"return type or with '...'", self.getfunctype().name)
with self as ptr:
closure_ptr = rffi.cast(clibffi.FFI_CLOSUREP, ptr)
- unique_id = rffi.cast(rffi.VOIDP, self.unique_id)
+ unique_id = rffi.cast(rffi.VOIDP, handle_index)
res = clibffi.c_ffi_prep_closure(closure_ptr, cif_descr.cif,
invoke_callback,
unique_id)
@@ -82,12 +88,8 @@
raise OperationError(space.w_SystemError,
space.wrap("libffi failed to build this callback"))
#
- # We must setup the GIL here, in case the callback is invoked in
- # some other non-Pythonic thread. This is the same as cffi on
- # CPython.
- if space.config.translation.thread:
- from pypy.module.thread.os_thread import setup_threads
- setup_threads(space)
+ _current_space.space = space
+ handle.get_handles(space).store_handle(handle_index, self)
def _repr_extra(self):
space = self.space
@@ -127,9 +129,6 @@
keepalive_until_here(self) # to keep self._closure.ll_error alive
-global_callback_mapping = rweakref.RWeakValueDictionary(int, W_CDataCallback)
-
-
def convert_from_object_fficallback(fresult, ll_res, w_res):
space = fresult.space
small_result = fresult.size < SIZE_OF_FFI_ARG
@@ -213,6 +212,12 @@
except OperationError, e:
_handle_applevel_exception(callback, e, ll_res, extra_line)
+class CurrentSpace:
+ def _cleanup_(self):
+ if hasattr(self, 'space'):
+ del self.space
+_current_space = CurrentSpace()
+
def _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
@@ -223,8 +228,9 @@
"""
ll_res = rffi.cast(rffi.CCHARP, ll_res)
unique_id = rffi.cast(lltype.Signed, ll_userdata)
- callback = global_callback_mapping.get(unique_id)
- if callback is None:
+ space = _current_space.space
+ callback = handle.get_handles(space).fetch_handle(unique_id)
+ if callback is None or not isinstance(callback, W_CDataCallback):
# oups!
try:
os.write(STDERR, "SystemError: invoking a callback "
@@ -237,7 +243,6 @@
return
#
must_leave = False
- space = callback.space
try:
must_leave = space.threadlocals.try_enter_thread(space)
py_invoke_callback(callback, ll_res, ll_args)
diff --git a/pypy/module/_cffi_backend/handle.py b/pypy/module/_cffi_backend/handle.py
--- a/pypy/module/_cffi_backend/handle.py
+++ b/pypy/module/_cffi_backend/handle.py
@@ -9,16 +9,16 @@
def __init__(self, space):
self.initialize()
-def get(space):
+def get_handles(space):
return space.fromcache(CffiHandles)
# ____________________________________________________________
def _newp_handle(space, w_ctype, w_x):
- index = get(space).reserve_next_handle_index()
+ index = get_handles(space).reserve_next_handle_index()
_cdata = rffi.cast(rffi.CCHARP, index + 1)
new_cdataobj = cdataobj.W_CDataHandle(space, _cdata, w_ctype, w_x)
- get(space).store_handle(index, new_cdataobj)
+ get_handles(space).store_handle(index, new_cdataobj)
return new_cdataobj
@unwrap_spec(w_ctype=ctypeobj.W_CType)
@@ -39,7 +39,7 @@
"new_handle(), got '%s'", ctype.name)
with w_cdata as ptr:
index = rffi.cast(lltype.Signed, ptr)
- original_cdataobj = get(space).fetch_handle(index - 1)
+ original_cdataobj = get_handles(space).fetch_handle(index - 1)
#
if isinstance(original_cdataobj, cdataobj.W_CDataHandle):
return original_cdataobj.w_keepalive
More information about the pypy-commit
mailing list