[pypy-svn] r53862 - in pypy/branch/jit-hotpath/pypy/jit: codegen rainbow rainbow/test timeshifter

antocuni at codespeak.net antocuni at codespeak.net
Fri Apr 18 18:30:04 CEST 2008


Author: antocuni
Date: Fri Apr 18 18:30:00 2008
New Revision: 53862

Modified:
   pypy/branch/jit-hotpath/pypy/jit/codegen/model.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py
   pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py
   pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py
Log:
implement oosend of external methods to red variables, e.g. all the
methods of ootype.String.  This let test_green_char_at_merge pass.




Modified: pypy/branch/jit-hotpath/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/codegen/model.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/model.py	Fri Apr 18 18:30:00 2008
@@ -88,6 +88,7 @@
 ##     def genop_malloc_fixedsize(self, alloctoken):
 ##     def genop_malloc_varsize(self, varsizealloctoken, gv_size):
 ##     def genop_call(self, sigtoken, gv_fnptr, args_gv):
+##     def genop_oosend(self, methtoken, gv_self, args_gv):
 ##     def genop_same_as(self, gv_x):
 ##     def genop_debug_pdb(self):    # may take an args_gv later
 ##     def genop_cast_int_to_ptr(self, kind, gv_int)
@@ -475,6 +476,9 @@
     def genop_call(self, sigtoken, gv_fnptr, args_gv):
         return dummy_var
 
+    def genop_oosend(self, methtoken, gv_obj, args_gv):
+        return dummy_var
+
     def genop_same_as(self, gv_x):
         return dummy_var
 

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py	Fri Apr 18 18:30:00 2008
@@ -166,6 +166,14 @@
         self.calldesc = CallDesc(codewriter.RGenOp, codewriter.exceptiondesc,
                                  lltype.typeOf(fnptr), colororder)
 
+class MethodDesc(object):
+
+    def __init__(self, RGenOp, SELFTYPE, methname):
+        _, meth = SELFTYPE._lookup(methname)
+        METH = ootype.typeOf(meth)
+        self.methtoken = RGenOp.methToken(SELFTYPE, methname)
+        self.redboxbuilder = rvalue.ll_redboxbuilder(METH.RESULT)
+
 
 class BytecodeWriter(object):
 
@@ -236,6 +244,7 @@
         self.indirectcalldescs = []
         self.metacalldescs = []
         self.strings = []
+        self.methdescs = []
         self.is_portal = is_portal
         # mapping constant -> index in constants
         self.const_positions = {}
@@ -275,6 +284,8 @@
         self.indirectcalldesc_positions = {}
         # mapping string to index
         self.string_positions = {}
+        # mapping methdesc to index
+        self.methdesc_positions = {}
 
         self.graph = graph
         self.mergepoint_set = {}
@@ -306,6 +317,7 @@
                           self.sharelist("metacalldescs"),
                           self.sharelist("indirectcalldescs"),
                           self.sharelist("strings"),
+                          self.sharelist("methdescs"),
                           self.is_portal,
                           owncalldesc,
                           gv_ownfnptr)
@@ -835,6 +847,16 @@
         self.string_positions[s] = result
         return result
 
+    def methdesc_position(self, TYPE, name):
+        key = (TYPE, name)
+        if key in self.methdesc_positions:
+            return self.methdesc_positions[tok]
+        result = len(self.methdescs)
+        desc = MethodDesc(self.RGenOp, TYPE, name)
+        self.methdescs.append(desc)
+        self.methdesc_positions[key] = result
+        return result
+
     def interiordesc(self, op, PTRTYPE, nb_offsets):
         path = []
         CONTAINER = PTRTYPE.TO
@@ -1649,9 +1671,11 @@
         name = op.args[0].value
         opargs = op.args[1:]
         SELFTYPE = opargs[0].concretetype
+        has_result = (self.varcolor(op.result) != "gray" and
+                      op.result.concretetype != lltype.Void)
+
         if SELFTYPE.oopspec_name is not None:
             # we are calling a method like List.ll_getitem or so
-            hasresult = op.result.concretetype != lltype.Void
             _, meth = SELFTYPE._lookup(name)
             oopspecdescindex = self.oopspecdesc_position('send', meth, withexc)
             oopspecdesc = self.oopspecdescs[oopspecdescindex]
@@ -1664,43 +1688,47 @@
             hs_self = self.hannotator.binding(opargs[0])
             deepfrozen = hs_self.deepfrozen
 
-            self.emit("red_oopspec_call%s_%s" % ("_noresult" * (not hasresult),
+            self.emit("red_oopspec_call%s_%s" % ("_noresult" * (not has_result),
                                                  len(args)))
             self.emit(oopspecdescindex)
             self.emit(deepfrozen)
             self.emit(*args)
             return
 
-        # normal oosend
-        # XXX: share code with serialize_op_indirect_call
-        has_result = (self.varcolor(op.result) != "gray" and
-                      op.result.concretetype != lltype.Void)
+        # real oosend, either red or const
         assert not self.hannotator.policy.hotpath
-        emitted_args = []
-        for v in op.args[1:]:
-            if v.concretetype == lltype.Void:
-                continue
-            emitted_args.append(self.serialize_oparg("red", v))
 
+        if kind == "residual":
+            # oosend to an external method (e.g. ootype.String.*)
+            emitted_args = []
+            for v in op.args[1:]:
+                if v.concretetype == lltype.Void:
+                    continue
+                emitted_args.append(self.serialize_oparg("red", v))
+            self.emit("external_oosend")
+            self.emit(len(emitted_args))
+            self.emit(*emitted_args)
+            methdescindex = self.methdesc_position(SELFTYPE, name)
+            self.emit(methdescindex)
+            self.emit(has_result)
+        else:
+            # normal oosend
+            graph2tsgraph = dict(self.graphs_from(op))
+            self.fill_methodcodes(SELFTYPE, name, graph2tsgraph)
+            args = graph2tsgraph.values()[0].getargs()
+            emitted_args = self.args_of_call(op.args[1:], args)
+            self.emit("red_oosend")
+            self.emit(*emitted_args)
+            methnameindex = self.string_position(name)
+            self.emit(methnameindex)
 
         if has_result:
             self.register_redvar(op.result)
 
-        graph2tsgraph = dict(self.graphs_from(op))
-        #type2graph = self.collect_graphs_and_types(op, graph2tsgraph)
-        self.fill_methodcodes(SELFTYPE, name, graph2tsgraph)
-        args = graph2tsgraph.values()[0].getargs()
-        emitted_args = self.args_of_call(op.args[1:], args)
-        self.emit("red_oosend")
-        self.emit(*emitted_args)
-        #setdescindex = self.oosenddesc_position(type2graph)
-        #self.emit(setdescindex)
-        methnameindex = self.string_position(name)
-        self.emit(methnameindex)
         if kind == "yellow":
             self.emit("yellow_retrieve_result_as_red")
             self.emit(self.type_position(op.result.concretetype))
-        elif kind in ("gray", "red"):
+        elif kind in ("gray", "red", "residual"):
             pass
         else:
             assert 0, "unknown call kind %s" % (kind, )

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py	Fri Apr 18 18:30:00 2008
@@ -38,8 +38,8 @@
                  interiordescs, exceptioninstances, oopspecdescs,
                  promotiondescs, called_bytecodes, num_mergepoints,
                  graph_color, calldescs, metacalldescs,
-                 indirectcalldescs, strings, is_portal, owncalldesc,
-                 gv_ownfnptr):
+                 indirectcalldescs, strings, methdescs, is_portal,
+                 owncalldesc, gv_ownfnptr):
         # XXX quite a lot of lists of descs here...  At least we
         # share identical lists between the numberous prebuilt
         # JitCode instances.
@@ -63,6 +63,7 @@
         self.metacalldescs = metacalldescs
         self.indirectcalldescs = indirectcalldescs
         self.strings = strings
+        self.methdescs = methdescs
         self.is_portal = is_portal
         self.owncalldesc = owncalldesc
         self.gv_ownfnptr = gv_ownfnptr
@@ -172,6 +173,10 @@
                     index = self.load_int()
                     string = self.getjitcode().strings[index]
                     args += (string, )
+                elif argspec == "methdesc":
+                    index = self.load_int()
+                    tok = self.getjitcode().methdescs[index]
+                    args += (tok, )
                 elif argspec == "oopspec":
                     oopspecindex = self.load_int()
                     oopspec = self.getjitcode().oopspecdescs[oopspecindex]
@@ -661,15 +666,6 @@
         self.run(self.jitstate, bytecode, greenargs, redargs,
                  start_bytecode_loop=False)
 
-    @arguments("green_varargs", "red_varargs", "string")
-    def opimpl_red_oosend(self, greenargs, redargs, methname):
-        selfbox = redargs[0]
-        vstruct = selfbox.content
-        assert isinstance(vstruct, rcontainer.VirtualStruct), 'TODO???'
-        bytecode = vstruct.typedesc.methodcodes[methname]
-        self.run(self.jitstate, bytecode, greenargs, redargs,
-                 start_bytecode_loop=False)
-
     @arguments(returns="green")
     def opimpl_yellow_retrieve_result(self):
         # XXX all this jitstate.greens business is a bit messy
@@ -1088,6 +1084,21 @@
         return rtimeshift.genptreq(self.jitstate, ptrbox1,
                                    ptrbox2, False)
 
+    @arguments("green_varargs", "red_varargs", "string")
+    def opimpl_red_oosend(self, greenargs, redargs, methname):
+        selfbox = redargs[0]
+        vstruct = selfbox.content
+        assert isinstance(vstruct, rcontainer.VirtualStruct), 'TODO???'
+        bytecode = vstruct.typedesc.methodcodes[methname]
+        self.run(self.jitstate, bytecode, greenargs, redargs,
+                 start_bytecode_loop=False)
+
+    @arguments("red_varargs", "methdesc", "bool")
+    def opimpl_external_oosend(self, redargs, methdesc, has_result):
+        result = rtimeshift.gen_external_oosend(self.jitstate, redargs,
+                                                methdesc)
+        if has_result:
+            self.red_result(result)
 
 class DebugTrace(object):
     def __init__(self, *args):

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py	Fri Apr 18 18:30:00 2008
@@ -2341,4 +2341,3 @@
     test_red_varsized_struct = _skip
     test_array_of_voids = _skip
     test_compile_time_const_tuple = _skip    # needs vdict
-    test_green_char_at_merge = _skip

Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py	Fri Apr 18 18:30:00 2008
@@ -902,7 +902,8 @@
                 self.ownbox.setgenvar_hint(gv, known_nonzero=True)
                 self.ownbox.content = None
                 return
-        debug_print(lltype.Void, "FORCE CONTAINER: "+ typedesc.TYPE._name)
+        name = getattr(typedesc.TYPE, '_name', str(typedesc.TYPE))
+        debug_print(lltype.Void, "FORCE CONTAINER: "+ name)
         #debug_pdb(lltype.Void)
         genvar = jitstate.ts.genop_malloc_fixedsize(builder, typedesc.alloctoken)
         # force the box pointing to this VirtualStruct

Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py	Fri Apr 18 18:30:00 2008
@@ -595,6 +595,14 @@
 ##def ll_gvar_from_constant(jitstate, ll_value):
 ##    return jitstate.curbuilder.rgenop.genconst(ll_value)
 
+def gen_external_oosend(jitstate, argboxes, methdesc):
+    builder = jitstate.curbuilder
+    selfbox = argboxes[0]
+    gv_selfbox = selfbox.getgenvar(jitstate)
+    args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes[1:]]
+    jitstate.prepare_for_residual_call() # XXX?
+    gv_result = builder.genop_oosend(methdesc.methtoken, gv_selfbox, args_gv)
+    return methdesc.redboxbuilder(gv_result)
 
 def gen_residual_call(jitstate, calldesc, funcbox, argboxes):
     builder = jitstate.curbuilder



More information about the Pypy-commit mailing list