[pypy-commit] pypy default: Kill callback_hook. Replace it with a simpler and more explicit solution, which is to decorate
arigo
noreply at buildbot.pypy.org
Sun Jan 13 16:37:26 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r60030:6ce8443ec9eb
Date: 2013-01-13 15:33 +0100
http://bitbucket.org/pypy/pypy/changeset/6ce8443ec9eb/
Log: Kill callback_hook. Replace it with a simpler and more explicit
solution, which is to decorate explicitly the callbacks that you
want the JIT to treat specially.
Btw, another potential use of this would be to have the JIT see some
function which is deep inside @dont_look_inside code, but which
causes more app-level Python code to be invoked. This can be
useful, to let the JIT see a bit more than just the app-level Python
code (e.g. the wrapping of arguments).
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -536,44 +536,6 @@
self.check_trace_count(1)
- def test_callback_jit_merge_point(self):
- from pypy.rlib.objectmodel import register_around_callback_hook
- from pypy.rpython.lltypesystem import lltype, rffi
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
-
- callback_jit_driver = JitDriver(greens = ['name'], reds = 'auto')
-
- def callback_merge_point(name):
- callback_jit_driver.jit_merge_point(name=name)
-
- @callback_jit_driver.inline(callback_merge_point)
- def callback_hook(name):
- pass
-
- def callback(a, b):
- if a > b:
- return 1
- return -1
-
- CB_TP = rffi.CCallback([lltype.Signed, lltype.Signed], lltype.Signed)
- eci = ExternalCompilationInfo(includes=['stdlib.h'])
- qsort = rffi.llexternal('qsort',
- [rffi.VOIDP, lltype.Signed, lltype.Signed,
- CB_TP], lltype.Void, compilation_info=eci)
- ARR = rffi.CArray(lltype.Signed)
-
- def main():
- register_around_callback_hook(callback_hook)
- raw = lltype.malloc(ARR, 10, flavor='raw')
- for i in range(10):
- raw[i] = 10 - i
- qsort(raw, 10, rffi.sizeof(lltype.Signed), callback)
- lltype.free(raw, flavor='raw')
-
- self.meta_interp(main, [])
- self.check_trace_count(1)
-
-
class TestLLWarmspot(WarmspotTests, LLJitMixin):
CPUClass = runner.LLGraphCPU
type_system = 'lltype'
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
@@ -152,6 +152,7 @@
STDERR = 2
+ at jit.jit_callback("CFFI")
def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
@@ -201,4 +202,3 @@
callback.write_error_return_value(ll_res)
if ec is not None:
cerrno.restore_errno_from(ec)
-invoke_callback._callback_hook_ = "CFFI"
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -2,7 +2,7 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError
-from pypy.rlib import rgc
+from pypy.rlib import rgc, jit
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.tool import rffi_platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -288,6 +288,7 @@
post_code = ''
src = py.code.Source("""
+ @jit.jit_callback('XML:%(name)s')
def %(name)s_callback(%(first_arg)s, %(args)s):
id = rffi.cast(lltype.Signed, %(ll_id)s)
userdata = global_storage.get_object(id)
@@ -312,7 +313,6 @@
""" % locals())
exec str(src)
- callback._callback_hook_ = "XML_" + name
c_name = 'XML_Set' + name
callback_type = lltype.Ptr(lltype.FuncType(
@@ -341,7 +341,6 @@
else:
result = 1
return rffi.cast(rffi.INT, result)
-UnknownEncodingHandlerData_callback._callback_hook_ = None # no jit needed
callback_type = lltype.Ptr(lltype.FuncType(
[rffi.VOIDP, rffi.CCHARP, XML_Encoding_Ptr], rffi.INT))
XML_SetUnknownEncodingHandler = expat_external(
diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -6,7 +6,7 @@
from pypy.tool.pairtype import extendabletype
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
-from pypy.rlib import jit, objectmodel
+from pypy.rlib import jit
from pypy.rlib.jit import current_trace_length, unroll_parameters
import pypy.interpreter.pyopcode # for side-effects
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -97,15 +97,6 @@
is_being_profiled=self.is_being_profiled)
return jumpto
-callback_jit_driver = JitDriver(greens = ['name'], reds = 'auto')
-
-def callback_merge_point(name):
- callback_jit_driver.jit_merge_point(name=name)
-
- at callback_jit_driver.inline(callback_merge_point)
-def callback_hook(name):
- pass
-
def _get_adapted_tick_counter():
# Normally, the tick counter is decremented by 100 for every
# Python opcode. Here, to better support JIT compilation of
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -421,6 +421,7 @@
hints={'callback':True}))
+ at jit.jit_callback("CLIBFFI")
def ll_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
@@ -431,7 +432,6 @@
"""
userdata = rffi.cast(USERDATA_P, ll_userdata)
userdata.callback(ll_args, ll_res, userdata)
-ll_callback._callback_hook_ = "CLIBFFI"
class StackCheckError(ValueError):
message = None
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -302,6 +302,32 @@
pass
+def jit_callback(name):
+ """Use as a decorator for C callback functions, to insert a
+ jitdriver.jit_merge_point() at the start. Only for callbacks
+ that typically invoke more app-level Python code.
+ """
+ def decorate(func):
+ from pypy.tool.sourcetools import compile2
+ #
+ def get_printable_location():
+ return name
+ jitdriver = JitDriver(get_printable_location=get_printable_location,
+ greens=[], reds='auto', name=name)
+ #
+ args = ','.join(['a%d' % i for i in range(func.func_code.co_argcount)])
+ source = """def callback_with_jitdriver(%(args)s):
+ jitdriver.jit_merge_point()
+ return real_callback(%(args)s)""" % locals()
+ miniglobals = {
+ 'jitdriver': jitdriver,
+ 'real_callback': func,
+ }
+ exec compile2(source) in miniglobals
+ return miniglobals['callback_with_jitdriver']
+ return decorate
+
+
# ____________________________________________________________
# VRefs
@@ -458,9 +484,8 @@
self.autoreds = True
self.reds = []
self.numreds = None # see warmspot.autodetect_jit_markers_redvars
- for hook in (get_jitcell_at, set_jitcell_at, get_printable_location,
- confirm_enter_jit):
- assert hook is None, "reds='auto' is not compatible with JitDriver hooks"
+ assert confirm_enter_jit is None, (
+ "reds='auto' is not compatible with confirm_enter_jit")
else:
if reds is not None:
self.reds = reds
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -595,16 +595,6 @@
llhelper(rffi.AroundFnPtr, before)
llhelper(rffi.AroundFnPtr, after)
-def register_around_callback_hook(hook):
- """ Register a hook that's called before a callback from C calls RPython.
- Primary usage is for JIT to have 'started from' hook.
- """
- from pypy.rpython.lltypesystem import rffi
- from pypy.rpython.annlowlevel import llhelper
-
- rffi.aroundstate.callback_hook = hook
- llhelper(rffi.CallbackHookPtr, hook)
-
def is_in_callback():
from pypy.rpython.lltypesystem import rffi
return rffi.stackcounter.stacks_counter > 1
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -1,6 +1,6 @@
import py
from pypy.annotation import model as annmodel
-from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import ll2ctypes
from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
from pypy.rpython.lltypesystem.llmemory import itemoffsetof, raw_memcopy
@@ -13,7 +13,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.tool.rfficache import platform, sizeof_c_type
from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rpython.annlowlevel import llhelper, llstr
+from pypy.rpython.annlowlevel import llhelper
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, assert_str0
from pypy.rlib import jit
@@ -280,18 +280,7 @@
if callbackholder is not None:
callbackholder.callbacks[callable] = True
args = ', '.join(['a%d' % i for i in range(len(TP.TO.ARGS))])
- invoke_hook = getattr(callable, '_callback_hook_', None)
- assert invoke_hook is None or isinstance(invoke_hook, str)
-
source = py.code.Source(r"""
- def inner_wrapper(%(args)s):
- if invoke_hook is not None and aroundstate is not None:
- callback_hook = aroundstate.callback_hook
- if callback_hook:
- callback_hook(llstr(invoke_hook))
- return callable(%(args)s)
- inner_wrapper._never_inline_ = True
-
def wrapper(%(args)s): # no *args - no GIL for mallocing the tuple
llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
if aroundstate is not None:
@@ -301,7 +290,7 @@
# from now on we hold the GIL
stackcounter.stacks_counter += 1
try:
- result = inner_wrapper(%(args)s)
+ result = callable(%(args)s)
except Exception, e:
os.write(2,
"Warning: uncaught exception in callback: %%s %%s\n" %%
@@ -323,7 +312,6 @@
miniglobals = locals().copy()
miniglobals['Exception'] = Exception
miniglobals['os'] = os
- miniglobals['llstr'] = llstr
miniglobals['we_are_translated'] = we_are_translated
miniglobals['stackcounter'] = stackcounter
exec source.compile() in miniglobals
@@ -331,11 +319,8 @@
_make_wrapper_for._annspecialcase_ = 'specialize:memo'
AroundFnPtr = lltype.Ptr(lltype.FuncType([], lltype.Void))
-CallbackHookPtr = lltype.Ptr(lltype.FuncType([lltype.Ptr(rstr.STR)], lltype.Void))
class AroundState:
- callback_hook = None
-
def _cleanup_(self):
self.before = None # or a regular RPython function
self.after = None # or a regular RPython function
diff --git a/pypy/translator/goal/targetpypystandalone.py b/pypy/translator/goal/targetpypystandalone.py
--- a/pypy/translator/goal/targetpypystandalone.py
+++ b/pypy/translator/goal/targetpypystandalone.py
@@ -28,11 +28,6 @@
w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup))
withjit = space.config.objspace.usemodules.pypyjit
- if withjit:
- from pypy.module.pypyjit.interp_jit import callback_hook
- from pypy.rlib import objectmodel
- objectmodel.register_around_callback_hook(callback_hook)
-
def entry_point(argv):
if withjit:
from pypy.jit.backend.hlinfo import highleveljitinfo
More information about the pypy-commit
mailing list