Commits

Alex Gaynor committed c6ea8ef Merge

(fijal mostly) Merged better-jit-hooks-2.

This exposes metadata about DebugMergePoints in jit hooks, specifically the current bytecode and the pycode object.

Comments (0)

Files changed (4)

pypy/module/pypyjit/__init__.py

         'set_optimize_hook': 'interp_resop.set_optimize_hook',
         'set_abort_hook': 'interp_resop.set_abort_hook',
         'ResOperation': 'interp_resop.WrappedOp',
+        'DebugMergePoint': 'interp_resop.DebugMergePoint',
         'Box': 'interp_resop.WrappedBox',
     }
 

pypy/module/pypyjit/interp_resop.py

 
-from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter.typedef import (TypeDef, GetSetProperty,
+     interp_attrproperty, interp_attrproperty_w)
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import unwrap_spec, interp2app, NoneNotWrapped
 from pypy.interpreter.pycode import PyCode
 from pypy.jit.metainterp.resoperation import rop, AbstractResOp
 from pypy.rlib.nonconst import NonConstant
 from pypy.rlib import jit_hooks
+from pypy.module.pypyjit.interp_jit import pypyjitdriver
 
 class Cache(object):
     in_recursion = False
 
 def wrap_oplist(space, logops, operations, ops_offset=None):
     l_w = []
+    jitdrivers_sd = logops.metainterp_sd.jitdrivers_sd
     for op in operations:
         if ops_offset is None:
             ofs = -1
         else:
             ofs = ops_offset.get(op, 0)
-        l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs,
-                             logops.repr_of_resop(op)))
+        if op.opnum == rop.DEBUG_MERGE_POINT:
+            jd_sd = jitdrivers_sd[op.getarg(0).getint()]
+            greenkey = op.getarglist()[2:]
+            repr = jd_sd.warmstate.get_location_str(greenkey)
+            w_greenkey = wrap_greenkey(space, jd_sd.jitdriver, greenkey, repr)
+            l_w.append(DebugMergePoint(space, jit_hooks._cast_to_gcref(op),
+                                       logops.repr_of_resop(op),
+                                       jd_sd.jitdriver.name,
+                                       w_greenkey))
+        else:
+            l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs,
+                                 logops.repr_of_resop(op)))
     return l_w
 
 class WrappedBox(Wrappable):
         llres = res.llbox
     return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr)
 
+@unwrap_spec(repr=str, jd_name=str)
+def descr_new_dmp(space, w_tp, w_args, repr, jd_name, w_greenkey):
+    args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
+            space.listview(w_args)]
+    num = rop.DEBUG_MERGE_POINT
+    return DebugMergePoint(space,
+                           jit_hooks.resop_new(num, args, jit_hooks.emptyval()),
+                           repr, jd_name, w_greenkey)
+
 class WrappedOp(Wrappable):
     """ A class representing a single ResOperation, wrapped nicely
     """
         box = space.interp_w(WrappedBox, w_box)
         jit_hooks.resop_setresult(self.op, box.llbox)
 
+class DebugMergePoint(WrappedOp):
+    def __init__(self, space, op, repr_of_resop, jd_name, w_greenkey):
+        WrappedOp.__init__(self, op, -1, repr_of_resop)
+        self.w_greenkey = w_greenkey
+        self.jd_name = jd_name
+
+    def get_pycode(self, space):
+        if self.jd_name == pypyjitdriver.name:
+            return space.getitem(self.w_greenkey, space.wrap(0))
+        raise OperationError(space.w_AttributeError, space.wrap("This DebugMergePoint doesn't belong to the main Python JitDriver"))
+
+    def get_bytecode_no(self, space):
+        if self.jd_name == pypyjitdriver.name:
+            return space.getitem(self.w_greenkey, space.wrap(1))
+        raise OperationError(space.w_AttributeError, space.wrap("This DebugMergePoint doesn't belong to the main Python JitDriver"))
+
+    def get_jitdriver_name(self, space):
+        return space.wrap(self.jd_name)
+
 WrappedOp.typedef = TypeDef(
     'ResOperation',
     __doc__ = WrappedOp.__doc__,
                             WrappedOp.descr_setresult)
 )
 WrappedOp.acceptable_as_base_class = False
+
+DebugMergePoint.typedef = TypeDef(
+    'DebugMergePoint', WrappedOp.typedef,
+    __new__ = interp2app(descr_new_dmp),
+    greenkey = interp_attrproperty_w("w_greenkey", cls=DebugMergePoint),
+    pycode = GetSetProperty(DebugMergePoint.get_pycode),
+    bytecode_no = GetSetProperty(DebugMergePoint.get_bytecode_no),
+    jitdriver_name = GetSetProperty(DebugMergePoint.get_jitdriver_name),
+)
+DebugMergePoint.acceptable_as_base_class = False
+
+

pypy/module/pypyjit/test/test_jit_hook.py

         cls.w_on_compile_bridge = space.wrap(interp2app(interp_on_compile_bridge))
         cls.w_on_abort = space.wrap(interp2app(interp_on_abort))
         cls.w_int_add_num = space.wrap(rop.INT_ADD)
+        cls.w_dmp_num = space.wrap(rop.DEBUG_MERGE_POINT)
         cls.w_on_optimize = space.wrap(interp2app(interp_on_optimize))
         cls.orig_oplist = oplist
 
         assert elem[2][2] == False
         assert len(elem[3]) == 4
         int_add = elem[3][0]
+        dmp = elem[3][1]
+        assert isinstance(dmp, pypyjit.DebugMergePoint)
+        assert dmp.pycode is self.f.func_code
+        assert dmp.greenkey == (self.f.func_code, 0, False)
         #assert int_add.name == 'int_add'
         assert int_add.num == self.int_add_num
         self.on_compile_bridge()
         assert op.getarg(0).getint() == 4
         op.result = box
         assert op.result.getint() == 1
+
+    def test_creation_dmp(self):
+        from pypyjit import DebugMergePoint, Box
+
+        def f():
+            pass
+
+        op = DebugMergePoint([Box(0)], 'repr', 'pypyjit', (f.func_code, 0, 0))
+        assert op.bytecode_no == 0
+        assert op.pycode is f.func_code
+        assert repr(op) == 'repr'
+        assert op.jitdriver_name == 'pypyjit'
+        assert op.num == self.dmp_num
+        op = DebugMergePoint([Box(0)], 'repr', 'notmain', ('str',))
+        raises(AttributeError, 'op.pycode')

pypy/rlib/jit_hooks.py

     from pypy.jit.metainterp.history import ResOperation
 
     args = [_cast_to_box(llargs[i]) for i in range(len(llargs))]
-    res = _cast_to_box(llres)
+    if llres:
+        res = _cast_to_box(llres)
+    else:
+        res = None
     return _cast_to_gcref(ResOperation(no, args, res))
 
 @register_helper(annmodel.SomePtr(llmemory.GCREF))