Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r73842:9f2a008bc6aa
Date: 2014-10-08 19:09 +0200
http://bitbucket.org/pypy/pypy/changeset/9f2a008bc6aa/

Log:    Expose 'not_in_trace' to app-level

diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -7,6 +7,7 @@
     interpleveldefs = {
         'set_param':    'interp_jit.set_param',
         'residual_call': 'interp_jit.residual_call',
+        'not_from_assembler': 'interp_jit.W_NotFromAssembler',
         'set_compile_hook': 'interp_resop.set_compile_hook',
         'set_optimize_hook': 'interp_resop.set_optimize_hook',
         'set_abort_hook': 'interp_resop.set_abort_hook',
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
@@ -12,6 +12,9 @@
 from pypy.interpreter.pycode import CO_GENERATOR
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pyopcode import ExitFrame, Yield
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app
 from opcode import opmap
 
 
@@ -144,3 +147,30 @@
     '''For testing.  Invokes callable(...), but without letting
     the JIT follow the call.'''
     return space.call_args(w_callable, __args__)
+
+
+class W_NotFromAssembler(W_Root):
+    def __init__(self, space, w_callable):
+        self.space = space
+        self.w_callable = w_callable
+    def descr_call(self, __args__):
+        _call_not_in_trace(self.space, self.w_callable, __args__)
+
[email protected]_in_trace
+def _call_not_in_trace(space, w_callable, __args__):
+    space.call_args(w_callable, __args__)
+
+def not_from_assembler_new(space, w_subtype, w_callable):
+    return W_NotFromAssembler(space, w_callable)
+
+W_NotFromAssembler.typedef = TypeDef("not_from_assembler",
+    __doc__ = """\
+A decorator that returns a callable that invokes the original
+callable, but not from the JIT-produced assembler.  It is called
+from the interpreted mode, and from the JIT creation (pyjitpl) or
+exiting (blackhole) steps, but just not from the final assembler.
+""",
+    __new__ = interp2app(not_from_assembler_new),
+    __call__ = interp2app(W_NotFromAssembler.descr_call),
+)
+W_NotFromAssembler.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/pypyjit/test/test_jit_not_in_trace.py 
b/pypy/module/pypyjit/test/test_jit_not_in_trace.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test/test_jit_not_in_trace.py
@@ -0,0 +1,11 @@
+
+class AppTestJitNotInTrace(object):
+    spaceconfig = dict(usemodules=('pypyjit',))
+
+    def test_not_from_assembler(self):
+        import pypyjit
+        @pypyjit.not_from_assembler
+        def f(x, y):
+            return 42
+        r = f(3, 4)
+        assert r is None
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -194,6 +194,14 @@
         return func
     return decorator
 
+def not_in_trace(func):
+    """A decorator for a function with no return value.  It makes the
+    function call disappear from the jit traces. It is still called in
+    interpreted mode, and by the jit tracing and blackholing, but not
+    by the final assembler."""
+    func.oopspec = "jit.not_in_trace()"   # note that 'func' may take arguments
+    return func
+
 @oopspec("jit.isconstant(value)")
 def isconstant(value):
     """
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to