[pypy-svn] r51846 - in pypy/branch/jit-refactoring/pypy/jit: rainbow rainbow/test timeshifter

cfbolz at codespeak.net cfbolz at codespeak.net
Mon Feb 25 13:36:08 CET 2008


Author: cfbolz
Date: Mon Feb 25 13:36:07 2008
New Revision: 51846

Modified:
   pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
   pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py
   pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
Log:
implement residual red calls


Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py	Mon Feb 25 13:36:07 2008
@@ -1,6 +1,7 @@
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.objspace.flow import model as flowmodel
+from pypy.rpython.annlowlevel import cachedtype
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.hintannotator.model import originalconcretetype
 from pypy.jit.hintannotator import model as hintmodel
@@ -11,6 +12,49 @@
 from pypy.translator.backendopt.removenoops import remove_same_as
 
 
+class CallDesc:
+    __metaclass__ = cachedtype
+
+    def __init__(self, RGenOp, FUNCTYPE, voidargs=()):
+        self.sigtoken = RGenOp.sigToken(FUNCTYPE.TO)
+        self.result_kind = RGenOp.kindToken(FUNCTYPE.TO.RESULT)
+        # xxx what if the result is virtualizable?
+        self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.TO.RESULT)
+        whatever_return_value = FUNCTYPE.TO.RESULT._defl()
+        numargs = len(FUNCTYPE.TO.ARGS)
+        argiter = unrolling_iterable(FUNCTYPE.TO.ARGS)
+        def green_call(interpreter, fnptr_gv, greenargs):
+            fnptr = fnptr_gv.revealconst(FUNCTYPE)
+            assert len(greenargs) + len(voidargs) == numargs 
+            args = ()
+            j = 0
+            k = 0
+            for ARG in argiter:
+                if ARG == lltype.Void:
+                    arg = voidargs[k]
+                    # XXX terrible hack
+                    if not we_are_translated():
+                        arg._TYPE = lltype.Void
+                    args += (arg, )
+                    k += 1
+                else:
+                    genconst = greenargs[j]
+                    arg = genconst.revealconst(ARG)
+                    args += (arg, )
+                    j += 1
+            rgenop = interpreter.jitstate.curbuilder.rgenop
+            try:
+                result = rgenop.genconst(fnptr(*args))
+            except Exception, e:
+                XXX # set exception
+                return rgenop.genconst(whatever_return_value)
+            interpreter.green_result(result)
+        self.green_call = green_call
+
+    def _freeze_(self):
+        return True
+
+
 class BytecodeWriter(object):
     def __init__(self, t, hannotator, RGenOp):
         self.translator = t
@@ -50,7 +94,7 @@
         self.called_bytecodes = []
         self.num_local_mergepoints = 0
         self.graph_color = self.graph_calling_color(graph)
-        self.nonrainbow_functions = []
+        self.calldescs = []
         self.is_portal = is_portal
         # mapping constant -> index in constants
         self.const_positions = {}
@@ -81,7 +125,7 @@
         # mapping graphs to index
         self.graph_positions = {}
         # mapping fnobjs to index
-        self.nonrainbow_positions = {}
+        self.calldesc_positions = {}
 
         self.graph = graph
         self.mergepoint_set = {}
@@ -105,7 +149,7 @@
                           self.called_bytecodes,
                           self.num_local_mergepoints,
                           self.graph_color,
-                          self.nonrainbow_functions,
+                          self.calldescs,
                           self.is_portal)
         if is_portal:
             self.finish_all_graphs()
@@ -347,8 +391,8 @@
     def redvar_position(self, arg):
         return self.redvar_positions[arg]
 
-    def register_greenvar(self, arg, where=None):
-        assert isinstance(arg, flowmodel.Variable)
+    def register_greenvar(self, arg, where=None, check=True):
+        assert isinstance(arg, flowmodel.Variable) or not check
         if where is None:
             where = self.free_green[self.current_block]
             self.free_green[self.current_block] += 1
@@ -444,41 +488,14 @@
         self.graph_positions[graph] = index
         return index
 
-    def nonrainbow_position(self, fnptr, *voidargs):
-        fn = fnptr._obj
-        key = fn, voidargs
-        if key in self.nonrainbow_positions:
-            return self.nonrainbow_positions[key]
-        FUNCTYPE = lltype.typeOf(fn)
-        argiter = unrolling_iterable(FUNCTYPE.ARGS)
-        numargs = len(FUNCTYPE.ARGS)
-        def call_normal_function(interpreter, greenargs):
-            assert len(greenargs) + len(voidargs) == numargs 
-            args = ()
-            j = 0
-            k = 0
-            for ARG in argiter:
-                if ARG == lltype.Void:
-                    arg = voidargs[k]
-                    # XXX terrible hack
-                    if not we_are_translated():
-                        arg._TYPE = lltype.Void
-                    args += (arg, )
-                    k += 1
-                else:
-                    genconst = greenargs[j]
-                    arg = genconst.revealconst(ARG)
-                    args += (arg, )
-                    j += 1
-            rgenop = interpreter.jitstate.curbuilder.rgenop
-            try:
-                result = rgenop.genconst(fnptr(*args))
-            except Exception, e:
-                XXX # need to create a default result and set exception
-            interpreter.green_result(result)
-        result = len(self.nonrainbow_functions)
-        self.nonrainbow_functions.append(call_normal_function)
-        self.nonrainbow_positions[key] = result
+    def calldesc_position(self, FUNCTYPE, *voidargs):
+        key = FUNCTYPE, voidargs
+        if key in self.calldesc_positions:
+            return self.calldesc_positions[key]
+        result = len(self.calldescs)
+        self.calldescs.append(
+            CallDesc(self.RGenOp, FUNCTYPE, voidargs))
+        self.calldesc_positions[key] = result
         return result
 
     def interiordesc(self, op, PTRTYPE, nb_offsets):
@@ -584,12 +601,12 @@
         pass
 
     def serialize_op_direct_call(self, op):
-        kind, exc = self.guess_call_kind(op)
-        print op, kind, exc
+        kind, withexc = self.guess_call_kind(op)
+        print op, kind, withexc
         if kind == "oopspec":
             from pypy.jit.timeshifter.oop import Index
             fnobj = op.args[0].value._obj
-            oopspecdescindex = self.oopspecdesc_position(fnobj, exc)
+            oopspecdescindex = self.oopspecdesc_position(fnobj, withexc)
             oopspecdesc = self.oopspecdescs[oopspecdescindex]
             opargs = op.args[1:]
             args_v = []
@@ -627,19 +644,42 @@
         elif kind == "green":
             voidargs = [const.value for const in op.args[1:]
                             if const.concretetype == lltype.Void]
-            pos = self.nonrainbow_position(op.args[0].value, *voidargs)
+            fnptr = op.args[0]
+            pos = self.calldesc_position(lltype.typeOf(fnptr.value), *voidargs)
+            func = self.serialize_oparg("green", fnptr)
             emitted_args = []
             for v in op.args[1:]:
                 if v.concretetype != lltype.Void:
                     emitted_args.append(self.serialize_oparg("green", v))
             self.emit("green_direct_call")
+            self.emit(func, pos)
             self.emit(len(emitted_args))
             self.emit(*emitted_args)
-            self.emit(pos)
             self.register_greenvar(op.result)
             return
         elif kind == "residual":
-            XXX
+            fnptr = op.args[0]
+            pos = self.calldesc_position(lltype.typeOf(fnptr.value))
+            func = self.serialize_oparg("red", fnptr)
+            emitted_args = []
+            for v in op.args[1:]:
+                emitted_args.append(self.serialize_oparg("red", v))
+            self.emit("red_residual_direct_call")
+            self.emit(func, pos, withexc, len(emitted_args), *emitted_args)
+            self.register_redvar(op.result)
+            pos = self.register_redvar(("residual_flags_red", op.args[0]))
+            self.emit("promote")
+            self.emit(pos)
+            self.emit(self.promotiondesc_position(lltype.Signed))
+            self.register_greenvar(("residual_flags_green", op.args[0]), check=False)
+            self.emit("residual_fetch", True, pos)
+            return
+        elif kind == "rpyexc_raise":
+            emitted_args = []
+            for v in op.args[1:]:
+                emitted_args.append(self.serialize_oparg("red", v))
+            self.emit("setexception", *emitted_args)
+            return
         targets = dict(self.graphs_from(op))
         assert len(targets) == 1
         targetgraph, = targets.values()
@@ -703,7 +743,7 @@
         pass
 
     def serialize_op_getfield(self, op):
-        assert self.opcolor(op) == "red"
+        color = self.opcolor(op)
         args = op.args
         if args[0] == self.exceptiondesc.cexcdata:
             # reading one of the exception boxes (exc_type or exc_value)
@@ -731,9 +771,11 @@
         fielddescindex = self.fielddesc_position(PTRTYPE.TO, fieldname)
         if fielddescindex == -1:   # Void field
             return
-        self.emit("red_getfield", index, fielddescindex, deepfrozen)
-        self.register_redvar(op.result)
-
+        self.emit("%s_getfield" % (color, ), index, fielddescindex, deepfrozen)
+        if color == "red":
+            self.register_redvar(op.result)
+        else:
+            self.register_greenvar(op.result)
 
     def serialize_op_setfield(self, op):
         args = op.args

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py	Mon Feb 25 13:36:07 2008
@@ -21,7 +21,7 @@
                  keydescs, structtypedescs, fielddescs, arrayfielddescs,
                  interiordescs, oopspecdescs, promotiondescs,
                  called_bytecodes, num_mergepoints,
-                 graph_color, nonrainbow_functions, is_portal):
+                 graph_color, calldescs, is_portal):
         self.name = name
         self.code = code
         self.constants = constants
@@ -37,7 +37,7 @@
         self.called_bytecodes = called_bytecodes
         self.num_mergepoints = num_mergepoints
         self.graph_color = graph_color
-        self.nonrainbow_functions = nonrainbow_functions
+        self.calldescs = calldescs
         self.is_portal = is_portal
 
     def _freeze_(self):
@@ -71,7 +71,6 @@
         if finaljitstate is not None:
             interpreter.finish_jitstate(interpreter.portalstate.sigtoken)
 
-
 def arguments(*argtypes, **kwargs):
     result = kwargs.pop("returns", None)
     assert not kwargs
@@ -107,9 +106,9 @@
                 elif argspec == "bytecode":
                     bytecodenum = self.load_2byte()
                     args += (self.frame.bytecode.called_bytecodes[bytecodenum], )
-                elif argspec == "nonrainbow_function":
+                elif argspec == "calldesc":
                     index = self.load_2byte()
-                    function = self.frame.bytecode.nonrainbow_functions[index]
+                    function = self.frame.bytecode.calldescs[index]
                     args += (function, )
                 elif argspec == "oopspec":
                     oopspecindex = self.load_2byte()
@@ -455,9 +454,9 @@
             self.frame.local_green)
         assert newjitstate is self.jitstate
 
-    @arguments("green_varargs", "nonrainbow_function")
-    def opimpl_green_direct_call(self, greenargs, function):
-        function(self, greenargs)
+    @arguments("green", "calldesc", "green_varargs")
+    def opimpl_green_direct_call(self, fnptr_gv, calldesc, greenargs):
+        calldesc.green_call(self, fnptr_gv, greenargs)
 
     @arguments("green_varargs", "red_varargs", "bytecode")
     def opimpl_yellow_direct_call(self, greenargs, redargs, targetbytecode):
@@ -493,6 +492,24 @@
     def opimpl_red_oopspec_call_3(self, oopspec, deepfrozen, arg1, arg2, arg3):
         return oopspec.ll_handler(self.jitstate, oopspec, deepfrozen, arg1, arg2, arg3)
 
+    @arguments("red", "calldesc", "bool", "red_varargs")
+    def opimpl_red_residual_direct_call(self, funcbox, calldesc, withexc, redargs):
+        result = rtimeshift.gen_residual_call(self.jitstate, calldesc,
+                                              funcbox, redargs)
+        self.red_result(result)
+        if withexc:
+            exceptiondesc = self.exceptiondesc
+        else:
+            exceptiondesc = None
+        flagbox = rtimeshift.after_residual_call(self.jitstate,
+                                                 exceptiondesc, True)
+        self.red_result(flagbox)
+
+    @arguments("bool", "red")
+    def opimpl_residual_fetch(self, check_forced, flagbox):
+        rtimeshift.residual_fetch(self.jitstate, self.exceptiondesc,
+                                  check_forced, flagbox)
+
 
     # exceptions
 
@@ -513,6 +530,10 @@
     def opimpl_write_excvalue(self, valuebox):
         rtimeshift.setexcvaluebox(self.jitstate, valuebox)
 
+    @arguments("red", "red")
+    def opimpl_setexception(self, typebox, valuebox):
+        rtimeshift.setexception(self.jitstate, typebox, valuebox)
+
     # structs and arrays
 
     @arguments("structtypedesc", returns="red")
@@ -536,6 +557,11 @@
         return rtimeshift.gengetfield(self.jitstate, deepfrozen, fielddesc,
                                       structbox)
 
+    @arguments("red", "fielddesc", "bool", returns="green_from_red")
+    def opimpl_green_getfield(self, structbox, fielddesc, deepfrozen):
+        return rtimeshift.gengetfield(self.jitstate, deepfrozen, fielddesc,
+                                      structbox)
+
     @arguments("red", "fielddesc", "red")
     def opimpl_red_setfield(self, destbox, fielddesc, valuebox):
         rtimeshift.gensetfield(self.jitstate, fielddesc, destbox,

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py	Mon Feb 25 13:36:07 2008
@@ -198,7 +198,8 @@
         self.residual_graph = graph
         if conftest.option.view:
             graph.show()
-        llinterp = LLInterpreter(self.rtyper)
+        llinterp = LLInterpreter(
+            self.rtyper, exc_data_ptr=writer.exceptiondesc.exc_data_ptr)
         res = llinterp.eval_graph(graph, residualargs)
         return res
 
@@ -236,6 +237,8 @@
         assert count == expected_count
 
 class SimpleTests(InterpretationTest):
+    small = True
+
     def test_simple_fixed(self):
         py.test.skip("green return")
         def ll_function(x, y):
@@ -991,7 +994,6 @@
         self.check_insns({})
 
     def test_residual_red_call(self):
-        py.test.skip("needs promote")
         def g(x):
             return x+1
 
@@ -1003,7 +1005,6 @@
         self.check_insns(int_add=0)
 
     def test_residual_red_call_with_exc(self):
-        py.test.skip("needs promote")
         def h(x):
             if x > 0:
                 return x+1

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py	Mon Feb 25 13:36:07 2008
@@ -246,14 +246,15 @@
 
         writer, jitcode = self.serialize(ll_function, [int])
         assert jitcode.code == assemble(writer.interpreter,
-                                        "green_direct_call", 1, 0, 0,
+                                        "green_direct_call", -1, 0, 1, 0,
                                         "make_redbox", 1, 0,
                                         "make_new_redvars", 1, 0,
                                         "make_new_greenvars", 0,
                                         "red_return")
         assert jitcode.is_portal
         assert len(jitcode.called_bytecodes) == 0
-        assert len(jitcode.nonrainbow_functions) == 1
+        assert len(jitcode.calldescs) == 1
+        assert len(jitcode.constants) == 1
 
     def test_yellow_call(self):
         def ll_two(x):

Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/greenkey.py	Mon Feb 25 13:36:07 2008
@@ -19,15 +19,17 @@
             self.hash = lambda self: 0
             self.compare = lambda self, other: True
 
-        TARGETTYPES = []
-        for TYPE in TYPES:
+        index_TYPE = []
+        for i, TYPE in enumerate(TYPES):
             # XXX more cases?
             TARGET = lltype.Signed
-            if TYPE == lltype.Float:
+            if TYPE == lltype.Void:
+                continue
+            elif TYPE == lltype.Float:
                 TARGET = TYPE
-            TARGETTYPES.append(TARGET)
+            index_TYPE.append((i, TARGET))
 
-        iterator = unrolling_iterable(enumerate(TARGETTYPES))
+        iterator = unrolling_iterable(index_TYPE)
         length = len(TYPES)
         def greenhash(self):
             retval = 0x345678

Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/rtimeshift.py	Mon Feb 25 13:36:07 2008
@@ -566,37 +566,16 @@
 ##def ll_gvar_from_constant(jitstate, ll_value):
 ##    return jitstate.curbuilder.rgenop.genconst(ll_value)
 
-class CallDesc:
-    __metaclass__ = cachedtype
-
-    def __init__(self, RGenOp, FUNCTYPE):
-        self.sigtoken = RGenOp.sigToken(FUNCTYPE)
-        self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT)
-        # xxx what if the result is virtualizable?
-        self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT)
-        whatever_return_value = FUNCTYPE.RESULT._defl()
-        def green_call(jitstate, fnptr, *args):
-            try:
-                result = fnptr(*args)
-            except Exception, e:
-                jitstate.residual_exception(e)
-                result = whatever_return_value
-            return result
-        self.green_call = green_call
-
-    def _freeze_(self):
-        return True
 
-def gen_residual_call(jitstate, calldesc, funcbox):
+def gen_residual_call(jitstate, calldesc, funcbox, argboxes):
     builder = jitstate.curbuilder
     gv_funcbox = funcbox.getgenvar(jitstate)
-    argboxes = jitstate.frame.local_boxes
     args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes]
     jitstate.prepare_for_residual_call()
     gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv)
     return calldesc.redboxbuilder(calldesc.result_kind, gv_result)
 
-def ll_after_residual_call(jitstate, exceptiondesc, check_forced):
+def after_residual_call(jitstate, exceptiondesc, check_forced):
     builder = jitstate.curbuilder
     if check_forced:
         gv_flags = jitstate.check_forced_after_residual_call()



More information about the Pypy-commit mailing list