Author: Maciej Fijalkowski <[email protected]>
Branch: better-jit-hooks
Changeset: r51051:e7ce390271a7
Date: 2012-01-06 00:43 +0200
http://bitbucket.org/pypy/pypy/changeset/e7ce390271a7/

Log:    fix pypyjit module, more work tomorrow

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,8 +7,8 @@
     interpleveldefs = {
         'set_param':    'interp_jit.set_param',
         'residual_call': 'interp_jit.residual_call',
-        'set_compile_hook': 'interp_jit.set_compile_hook',
-        'set_abort_hook': 'interp_jit.set_abort_hook',
+        'set_compile_hook': 'interp_resop.set_compile_hook',
+        'set_abort_hook': 'interp_resop.set_abort_hook',
         'DebugMergePoint': 'interp_resop.W_DebugMergePoint',
     }
 
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
@@ -14,7 +14,6 @@
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pyopcode import ExitFrame
 from opcode import opmap
-from pypy.rlib.nonconst import NonConstant
 
 PyFrame._virtualizable2_ = ['last_instr', 'pycode',
                             'valuestackdepth', 'locals_stack_w[*]',
@@ -167,48 +166,3 @@
     '''For testing.  Invokes callable(...), but without letting
     the JIT follow the call.'''
     return space.call_args(w_callable, __args__)
-
-class Cache(object):
-    in_recursion = False
-
-    def __init__(self, space):
-        self.w_compile_hook = space.w_None
-        self.w_abort_hook = space.w_None
-
-def set_compile_hook(space, w_hook):
-    """ set_compile_hook(hook)
-
-    Set a compiling hook that will be called each time a loop is compiled.
-    The hook will be called with the following signature:
-    hook(merge_point_type, loop_type, greenkey or guard_number, operations)
-
-    for now merge point type is always `main`
-
-    loop_type can be either `loop` `entry_bridge` or `bridge`
-    in case loop is not `bridge`, greenkey will be a set of constants
-    for jit merge point. in case it's `main` it'll be a tuple
-    (code, offset, is_being_profiled)
-
-    Note that jit hook is not reentrant. It means that if the code
-    inside the jit hook is itself jitted, it will get compiled, but the
-    jit hook won't be called for that.
-
-    XXX write down what else
-    """
-    cache = space.fromcache(Cache)
-    cache.w_compile_hook = w_hook
-    cache.in_recursion = NonConstant(False)
-    return space.w_None
-
-def set_abort_hook(space, w_hook):
-    """ set_abort_hook(hook)
-
-    Set a hook (callable) that will be called each time there is tracing
-    aborted due to some reason. The hook will be called with string describing
-    the reason as an argument
-    """
-    cache = space.fromcache(Cache)
-    cache.w_abort_hook = w_hook
-    cache.in_recursion = NonConstant(False)
-    return space.w_None
-    
diff --git a/pypy/module/pypyjit/interp_resop.py 
b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -7,8 +7,76 @@
 from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
 from pypy.rpython.lltypesystem.rclass import OBJECT
 from pypy.jit.metainterp.resoperation import rop
+from pypy.rlib.nonconst import NonConstant
 
-def wrap_oplist(space, logops, operations):
+
+class Cache(object):
+    in_recursion = False
+
+    def __init__(self, space):
+        self.w_compile_hook = space.w_None
+        self.w_abort_hook = space.w_None
+
+def wrap_greenkey(space, jitdriver, greenkey):
+    if jitdriver.name == 'pypyjit':
+        next_instr = greenkey[0].getint()
+        is_being_profiled = greenkey[1].getint()
+        ll_code = lltype.cast_opaque_ptr(lltype.Ptr(OBJECT),
+                                         greenkey[2].getref_base())
+        pycode = cast_base_ptr_to_instance(PyCode, ll_code)
+        return space.newtuple([space.wrap(pycode), space.wrap(next_instr),
+                               space.newbool(is_being_profiled)])
+    else:
+        return space.wrap('who knows?')
+
+def set_compile_hook(space, w_hook):
+    """ set_compile_hook(hook)
+
+    Set a compiling hook that will be called each time a loop is compiled.
+    The hook will be called with the following signature:
+    hook(jitdriver_name, loop_type, greenkey or guard_number, operations,
+         assembler_addr, assembler_length)
+
+    jitdriver_name is the name of this particular jitdriver, 'pypyjit' is
+    the main interpreter loop
+
+    loop_type can be either `loop` `entry_bridge` or `bridge`
+    in case loop is not `bridge`, greenkey will be a tuple of constants
+    or a string describing it.
+
+    for the interpreter loop` it'll be a tuple
+    (code, offset, is_being_profiled)
+
+    assembler_addr is an integer describing where assembler starts,
+    can be accessed via ctypes, assembler_lenght is the lenght of compiled
+    asm
+
+    Note that jit hook is not reentrant. It means that if the code
+    inside the jit hook is itself jitted, it will get compiled, but the
+    jit hook won't be called for that.
+    """
+    cache = space.fromcache(Cache)
+    cache.w_compile_hook = w_hook
+    cache.in_recursion = NonConstant(False)
+    return space.w_None
+
+def set_abort_hook(space, w_hook):
+    """ set_abort_hook(hook)
+
+    Set a hook (callable) that will be called each time there is tracing
+    aborted due to some reason.
+
+    The hook will be called as in: hook(jitdriver_name, greenkey, reason)
+
+    Where reason is the reason for abort, see documentation for 
set_compile_hook
+    for descriptions of other arguments.
+    """
+    cache = space.fromcache(Cache)
+    cache.w_abort_hook = w_hook
+    cache.in_recursion = NonConstant(False)
+    return space.w_None
+
+def wrap_oplist(space, logops, operations, ops_offset):
     list_w = []
     for op in operations:
         if op.getopnum() == rop.DEBUG_MERGE_POINT:
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -1,10 +1,8 @@
 from pypy.jit.codewriter.policy import JitPolicy
 from pypy.rlib.jit import JitPortal
-from pypy.module.pypyjit.interp_jit import Cache
 from pypy.interpreter.error import OperationError
 from pypy.jit.metainterp.jitprof import counter_names
-from pypy.module.pypyjit.interp_resop import wrap_oplist
-from pypy.interpreter.pycode import PyCode
+from pypy.module.pypyjit.interp_resop import wrap_oplist, Cache, wrap_greenkey
 
 class PyPyPortal(JitPortal):
     def on_abort(self, reason, jitdriver, greenkey):
@@ -16,52 +14,43 @@
             cache.in_recursion = True
             try:
                 space.call_function(cache.w_abort_hook,
+                                    space.wrap(jitdriver.name),
+                                    wrap_greenkey(space, jitdriver, greenkey),
                                     space.wrap(counter_names[reason]))
             except OperationError, e:
                 e.write_unraisable(space, "jit hook ", cache.w_abort_hook)
             cache.in_recursion = False
 
     def on_compile(self, jitdriver, logger, looptoken, operations, type,
-                   greenkey, asmstart, asmlen):
-        from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
+                   greenkey, ops_offset, asmstart, asmlen):
+        self._compile_hook(jitdriver, logger, operations, type,
+                           ops_offset, asmstart, asmlen,
+                           wrap_greenkey(self.space, jitdriver, greenkey))
 
+    def on_compile_bridge(self, jitdriver, logger, orig_looptoken, operations,
+                          n, ops_offset, asmstart, asmlen):
+        self._compile_hook(jitdriver, logger, operations, 'bridge',
+                           ops_offset, asmstart, asmlen,
+                           self.space.wrap(n))
+
+    def _compile_hook(self, jitdriver, logger, operations, type,
+                      ops_offset, asmstart, asmlen, w_arg):
         space = self.space
         cache = space.fromcache(Cache)
         if cache.in_recursion:
             return
         if space.is_true(cache.w_compile_hook):
             logops = logger._make_log_operations()
-            list_w = wrap_oplist(space, logops, operations)
-            pycode = cast_base_ptr_to_instance(PyCode, ll_pycode)
+            list_w = wrap_oplist(space, logops, operations, ops_offset)
             cache.in_recursion = True
             try:
                 space.call_function(cache.w_compile_hook,
-                                    space.wrap('main'),
+                                    space.wrap(jitdriver.name),
                                     space.wrap(type),
-                                    space.newtuple([pycode,
-                                    space.wrap(next_instr),
-                                    space.wrap(is_being_profiled)]),
-                                    space.newlist(list_w))
-            except OperationError, e:
-                e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
-            cache.in_recursion = False
-
-    def on_compile_bridge(self, jitdriver, logger, orig_looptoken, operations,
-                          n, asm, asmlen):
-        space = self.space
-        cache = space.fromcache(Cache)
-        if cache.in_recursion:
-            return
-        if space.is_true(cache.w_compile_hook):
-            logops = logger._make_log_operations()
-            list_w = wrap_oplist(space, logops, operations)
-            cache.in_recursion = True
-            try:
-                space.call_function(cache.w_compile_hook,
-                                    space.wrap('main'),
-                                    space.wrap('bridge'),
-                                    space.wrap(n),
-                                    space.newlist(list_w))
+                                    w_arg,
+                                    space.newlist(list_w),
+                                    space.wrap(asmstart),
+                                    space.wrap(asmlen))
             except OperationError, e:
                 e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
             cache.in_recursion = False
diff --git a/pypy/module/pypyjit/test/test_jit_hook.py 
b/pypy/module/pypyjit/test/test_jit_hook.py
--- a/pypy/module/pypyjit/test/test_jit_hook.py
+++ b/pypy/module/pypyjit/test/test_jit_hook.py
@@ -44,11 +44,13 @@
         greenkey = [ConstInt(0), ConstInt(0), ConstPtr(code_gcref)]
 
         def interp_on_compile():
-            pypyjitdriver.on_compile(logger, JitCellToken(), oplist, 'loop',
-                                     0, False, ll_code)
+            pypy_portal.on_compile(pypyjitdriver, logger, JitCellToken(),
+                                   oplist, 'loop', greenkey, {}, 0, 0)
 
         def interp_on_compile_bridge():
-            pypyjitdriver.on_compile_bridge(logger, JitCellToken(), oplist, 0)
+            pypy_portal.on_compile_bridge(pypyjitdriver, logger,
+                                            JitCellToken(), oplist, 0,
+                                            {}, 0, 0)
 
         def interp_on_abort():
             pypy_portal.on_abort(ABORT_TOO_LONG, pypyjitdriver, greenkey)
@@ -61,21 +63,21 @@
         import pypyjit
         all = []
 
-        def hook(*args):
-            assert args[0] == 'main'
-            assert args[1] in ['loop', 'bridge']
-            all.append(args[2:])
+        def hook(name, looptype, tuple_or_guard_no, ops, asmstart, asmlen):
+            all.append((name, looptype, tuple_or_guard_no, ops))
         
         self.on_compile()
         pypyjit.set_compile_hook(hook)
         assert not all
         self.on_compile()
         assert len(all) == 1
-        assert all[0][0][0].co_name == 'f'
-        assert all[0][0][1] == 0
-        assert all[0][0][2] == False
-        assert len(all[0][1]) == 3
-        assert 'int_add' in all[0][1][0]
+        elem = all[0]
+        assert elem[0] == 'pypyjit'
+        assert elem[2][0].co_name == 'f'
+        assert elem[2][1] == 0
+        assert elem[2][2] == False
+        assert len(elem[3]) == 3
+        assert 'int_add' in elem[3][0]
         self.on_compile_bridge()
         assert len(all) == 2
         pypyjit.set_compile_hook(None)
@@ -136,9 +138,9 @@
         import pypyjit
         l = []
 
-        def hook(reason):
-            l.append(reason)
+        def hook(jitdriver_name, greenkey, reason):
+            l.append((jitdriver_name, reason))
         
         pypyjit.set_abort_hook(hook)
         self.on_abort()
-        assert l == ['ABORT_TOO_LONG']
+        assert l == [('pypyjit', 'ABORT_TOO_LONG')]
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to