Commits

Maciej Fijalkowski committed 4c1b9df

add some jit hooks, a bit ugly but works

Comments (0)

Files changed (5)

pypy/interpreter/eval.py

 This module defines the abstract base classes that support execution:
 Code and Frame.
 """
-from pypy.rlib import jit
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import Wrappable
 

pypy/jit/metainterp/test/test_jitportal.py

 
 from pypy.rlib.jit import JitDriver, JitPortal
+from pypy.rlib import jit_hooks
 from pypy.jit.metainterp.test.support import LLJitMixin
 from pypy.jit.codewriter.policy import JitPolicy
 from pypy.jit.metainterp.jitprof import ABORT_FORCE_QUASIIMMUT
+from pypy.jit.metainterp.resoperation import rop
 
 class TestJitPortal(LLJitMixin):
     def test_abort_quasi_immut(self):
         self.meta_interp(loop, [1, 10], policy=JitPolicy(MyJitPortal()))
         assert sorted(called.keys()) == ['bridge', (10, 1, "loop")]
 
+    def test_resop_interface(self):
+        driver = JitDriver(greens = [], reds = ['i'])
+
+        def loop(i):
+            while i > 0:
+                driver.jit_merge_point(i=i)
+                i -= 1
+
+        def main():
+            loop(1)
+            op = jit_hooks.resop_new(rop.INT_ADD,
+                                     [jit_hooks.boxint_new(3),
+                                      jit_hooks.boxint_new(4)],
+                                     jit_hooks.boxint_new(1))
+            return jit_hooks.resop_opnum(op)
+
+        res = self.meta_interp(main, [])
+        assert res == rop.INT_ADD

pypy/jit/metainterp/warmspot.py

     return ll_meta_interp(function, args, backendopt=backendopt,
                           translate_support_code=True, **kwds)
 
-def _find_jit_marker(graphs, marker_name):
+def _find_jit_marker(graphs, marker_name, check_driver=True):
     results = []
     for graph in graphs:
         for block in graph.iterblocks():
                 op = block.operations[i]
                 if (op.opname == 'jit_marker' and
                     op.args[0].value == marker_name and
-                    (op.args[1].value is None or
-                    op.args[1].value.active)):   # the jitdriver
+                    (not check_driver or op.args[1].value is None or
+                     op.args[1].value.active)):   # the jitdriver
                     results.append((graph, block, i))
     return results
 
         "found several jit_merge_points in the same graph")
     return results
 
+def find_access_helpers(graphs):
+    return _find_jit_marker(graphs, 'access_helper', False)
+
 def locate_jit_merge_point(graph):
     [(graph, block, pos)] = find_jit_merge_points([graph])
     return block, pos, block.operations[pos]
         verbose = False # not self.cpu.translate_support_code
         self.codewriter.make_jitcodes(verbose=verbose)
         self.rewrite_can_enter_jits()
+        self.rewrite_access_helpers()
         self.rewrite_set_param()
         self.rewrite_force_virtual(vrefinfo)
         self.rewrite_force_quasi_immutable()
         graph = self.annhelper.getgraph(func, args_s, s_result)
         return self.annhelper.graph2delayed(graph, FUNC)
 
+    def rewrite_access_helpers(self):
+        ah = find_access_helpers(self.translator.graphs)
+        for graph, block, index in ah:
+            op = block.operations[index]
+            self.rewrite_access_helper(op)
+
+    def rewrite_access_helper(self, op):
+        ARGS = [arg.concretetype for arg in op.args[2:]]
+        RESULT = op.result.concretetype
+        ptr = self.helper_func(lltype.Ptr(lltype.FuncType(ARGS, RESULT)),
+                               op.args[1].value)
+        op.opname = 'direct_call'
+        op.args = [Constant(ptr, lltype.Void)] + op.args[2:]
+
     def rewrite_jit_merge_points(self, policy):
         for jd in self.jitdrivers_sd:
             self.rewrite_jit_merge_point(jd, policy)
         assert isinstance(s_inst, annmodel.SomeInstance)
 
     def specialize_call(self, hop):
-        from pypy.rpython.lltypesystem import lltype, rclass
+        from pypy.rpython.lltypesystem import rclass, lltype
+        
         classrepr = rclass.get_type_repr(hop.rtyper)
 
         hop.exception_cannot_occur()

pypy/rlib/jit_hooks.py

+
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.annotation import model as annmodel
+from pypy.rpython.lltypesystem import llmemory, lltype
+from pypy.rpython.lltypesystem import rclass
+from pypy.rpython.annlowlevel import cast_instance_to_base_ptr,\
+     cast_base_ptr_to_instance
+
+def register_helper(helper, s_result):
+    
+    class Entry(ExtRegistryEntry):
+        _about_ = helper
+
+        def compute_result_annotation(self, *args):
+            return s_result
+
+        def specialize_call(self, hop):
+            from pypy.rpython.lltypesystem import lltype
+
+            c_func = hop.inputconst(lltype.Void, helper)
+            c_name = hop.inputconst(lltype.Void, 'access_helper')
+            args_v = [hop.inputarg(arg, arg=i)
+                      for i, arg in enumerate(hop.args_r)]
+            return hop.genop('jit_marker', [c_name, c_func] + args_v,
+                             resulttype=hop.r_result)
+
+def _cast_to_box(llref):
+    from pypy.jit.metainterp.history import AbstractValue
+
+    ptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, llref)
+    return cast_base_ptr_to_instance(AbstractValue, ptr)
+
+def resop_new(no, llargs, llres):
+    from pypy.jit.metainterp.history import ResOperation
+
+    args = [_cast_to_box(llarg) for llarg in llargs]
+    res = _cast_to_box(llres)
+    rop = ResOperation(no, args, res)
+    return lltype.cast_opaque_ptr(llmemory.GCREF,
+                                  cast_instance_to_base_ptr(rop))
+
+register_helper(resop_new, annmodel.SomePtr(llmemory.GCREF))
+
+def boxint_new(no):
+    from pypy.jit.metainterp.history import BoxInt
+    return lltype.cast_opaque_ptr(llmemory.GCREF,
+                                  cast_instance_to_base_ptr(BoxInt(no)))
+
+register_helper(boxint_new, annmodel.SomePtr(llmemory.GCREF))
+
+def resop_opnum(llop):
+    from pypy.jit.metainterp.resoperation import AbstractResOp
+    
+    opptr = lltype.cast_opaque_ptr(rclass.OBJECTPTR, llop)
+    op = cast_base_ptr_to_instance(AbstractResOp, opptr)
+    return op.getopnum()
+
+register_helper(resop_opnum, annmodel.SomeInteger())