[pypy-svn] r55515 - in pypy/branch/oo-jit/pypy/jit: codegen/llgraph rainbow rainbow/test timeshifter

antocuni at codespeak.net antocuni at codespeak.net
Tue Jun 3 14:47:20 CEST 2008


Author: antocuni
Date: Tue Jun  3 14:47:18 2008
New Revision: 55515

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/llgraph/llimpl.py
   pypy/branch/oo-jit/pypy/jit/codegen/llgraph/rgenop.py
   pypy/branch/oo-jit/pypy/jit/rainbow/codewriter.py
   pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py
   pypy/branch/oo-jit/pypy/jit/rainbow/test/test_interpreter.py
   pypy/branch/oo-jit/pypy/jit/rainbow/test/test_portal.py
   pypy/branch/oo-jit/pypy/jit/timeshifter/rtimeshift.py
Log:
introduce a new rainbow bytecode for oosend whose receiver is a
virtual struct, and generate a residual oosend in the general case.
test_portal.test_method_call_nonpromote passes



Modified: pypy/branch/oo-jit/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/llgraph/llimpl.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/llgraph/llimpl.py	Tue Jun  3 14:47:18 2008
@@ -376,6 +376,13 @@
         vars_gv = [gv_ptr, gv_fieldname]
         return genop(block, "getfield", vars_gv, RESULTTYPE)
 
+def genoosend(block, gv_OBJTYPE, args_gv, gv_RESULT_TYPE):
+    OBJTYPE = _from_opaque(gv_OBJTYPE).value
+    gv_obj = args_gv[1]
+    gv_obj = cast(block, gv_OBJTYPE, gv_obj.v)
+    args_gv[1] = gv_obj
+    return genop(block, "oosend", args_gv, gv_RESULT_TYPE)
+
 def genoosetfield(block, gv_obj, gv_OBJTYPE, gv_fieldname, gv_value):
     v_obj = _from_opaque(gv_obj)
     gv_obj = cast(block, gv_OBJTYPE, gv_obj)

Modified: pypy/branch/oo-jit/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/llgraph/rgenop.py	Tue Jun  3 14:47:18 2008
@@ -170,12 +170,12 @@
             v = llimpl.genop(self.b, 'indirect_call', vars_gv, gv_RESULT.v)
         return LLVar(v)
 
-    def genop_oosend(self, (gv_methname, (ARGS_gv, gv_RESULT, _)), gv_self, args_gv):
+    def genop_oosend(self, (gv_TYPE, gv_methname, (ARGS_gv, gv_RESULT, _)), gv_self, args_gv):
         ll_assert(self.rgenop.currently_writing is self,
                      "genop_oosend: bad currently_writing")
         vars_gv = [gv_methname, gv_self]
         vars_gv += self._cast_args_gv(ARGS_gv, args_gv)
-        v = llimpl.genop(self.b, 'oosend', vars_gv, gv_RESULT.v)
+        v = llimpl.genoosend(self.b, gv_TYPE.v, vars_gv, gv_RESULT.v)
         return LLVar(v)
 
     def genop_getfield(self, (gv_name, gv_PTRTYPE, gv_FIELDTYPE), gv_ptr):
@@ -490,7 +490,7 @@
         _, meth = TYPE._lookup(methname)
         METH = ootype.typeOf(meth)
         gv_methname = LLConst(llimpl.constFieldName(methname))
-        return (gv_methname, RGenOp.sigToken(METH))
+        return (gv_TYPE(TYPE), gv_methname, RGenOp.sigToken(METH))
 
     constPrebuiltGlobal = genconst
 

Modified: pypy/branch/oo-jit/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/rainbow/codewriter.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/rainbow/codewriter.py	Tue Jun  3 14:47:18 2008
@@ -1539,7 +1539,7 @@
                     return 'green', self.can_raise(spaceop)
                 return 'oopspec', self.can_raise(spaceop)
             if not SELFTYPE._lookup_graphs(methname):
-                return 'builtin', self.can_raise(spaceop)
+                return 'residual', self.can_raise(spaceop)
             hs_self = self.hannotator.binding(spaceop.args[1])
             if hs_self.is_green():
                 return 'direct', self.can_raise(spaceop)
@@ -1767,7 +1767,7 @@
         if has_result:
             self.register_redvar(op.result)
 
-    def handle_builtin_oosend(self, op, withexc):
+    def handle_residual_oosend(self, op, withexc):
         SELFTYPE, name, opargs = self.decompose_oosend(op)
         has_result = self.has_result(op)
         emitted_args = []
@@ -1775,29 +1775,52 @@
             if v.concretetype == lltype.Void:
                 continue
             emitted_args.append(self.serialize_oparg("red", v))
-        self.emit("builtin_oosend")
+        self.emit_residual_oosend(SELFTYPE, name, emitted_args,
+                                  has_result)
+        if has_result:
+            self.register_redvar(op.result)
+
+    def emit_residual_oosend(self, SELFTYPE, name, emitted_args,
+                             has_result):
+        self.emit("residual_oosend")
         self.emit(len(emitted_args))
         self.emit(*emitted_args)
         methdescindex = self.methdesc_position(SELFTYPE, name)
         self.emit(methdescindex)
         self.emit(has_result)
-        if has_result:
-            self.register_redvar(op.result)
 
     def handle_red_oosend(self, op, withexc):
         SELFTYPE, name, opargs = self.decompose_oosend(op)
         has_result = self.has_result(op)
         graph2tsgraph = dict(self.graphs_from(op))
         self.fill_methodcodes(SELFTYPE, name, graph2tsgraph)
+
+        emitted_args = []
+        for v in op.args[1:]:
+            if v.concretetype == lltype.Void:
+                continue
+            emitted_args.append(self.serialize_oparg("red", v))
+
+        self.emit("goto_if_vstruct", emitted_args[0],
+                  tlabel(("virtual struct oosend", op)))
+        self.emit_residual_oosend(SELFTYPE, name, emitted_args,
+                                  has_result)
+        self.emit("goto", tlabel(("after oosend", op)))
+
+        # virtual struct case
+        self.emit(label(("virtual struct oosend", op)))
         args = graph2tsgraph.values()[0].getargs()
         emitted_args = self.args_of_call(op.args[1:], args)
-        self.emit("red_oosend")
+        self.emit("vstruct_oosend")
         self.emit(*emitted_args)
         methnameindex = self.string_position(name)
         self.emit(methnameindex)
+
         if has_result:
             self.register_redvar(op.result)
 
+        self.emit(label(("after oosend", op)))
+
     def handle_direct_oosend(self, op, withexc):
         SELFTYPE, name, opargs = self.decompose_oosend(op)
         has_result = self.has_result(op)

Modified: pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/rainbow/interpreter.py	Tue Jun  3 14:47:18 2008
@@ -1084,10 +1084,16 @@
         return rtimeshift.genptreq(self.jitstate, ptrbox1,
                                    ptrbox2, False)
 
+    @arguments("red", "jumptarget")
+    def opimpl_goto_if_vstruct(self, objbox, target):
+        if objbox.content is not None:
+            self.frame.pc = target
+
     @arguments("green_varargs", "red_varargs", "string")
-    def opimpl_red_oosend(self, greenargs, redargs, methname):
+    def opimpl_vstruct_oosend(self, greenargs, redargs, methname):
         selfbox = redargs[0]
         vstruct = selfbox.content
+        assert vstruct is not None
         assert isinstance(vstruct, rcontainer.VirtualStruct), 'TODO???'
         bytecode = vstruct.typedesc.methodcodes[methname]
         self.run(self.jitstate, bytecode, greenargs, redargs,
@@ -1104,8 +1110,8 @@
         methdesc.green_call(self, None, greenargs)
 
     @arguments("red_varargs", "methdesc", "bool")
-    def opimpl_builtin_oosend(self, redargs, methdesc, has_result):
-        result = rtimeshift.gen_external_oosend(self.jitstate, redargs,
+    def opimpl_residual_oosend(self, redargs, methdesc, has_result):
+        result = rtimeshift.gen_residual_oosend(self.jitstate, redargs,
                                                 methdesc)
         if has_result:
             self.red_result(result)

Modified: pypy/branch/oo-jit/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/rainbow/test/test_interpreter.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/rainbow/test/test_interpreter.py	Tue Jun  3 14:47:18 2008
@@ -1035,6 +1035,15 @@
         assert res == 42
         self.check_insns({'direct_call': 1})
 
+    def test_builtin_oosend_with_green_args(self):
+        def fn(ch1, ch2):
+            s = 'hello World'
+            ch3 = hint(ch2, concrete=True)
+            s = s.replace(ch1, ch3)
+            return s[6]
+        res = self.interpret(fn, ['W', 'w'], [])
+        assert res == 'w'
+
     def test_residual_red_call(self):
         def g(x):
             return x+1

Modified: pypy/branch/oo-jit/pypy/jit/rainbow/test/test_portal.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/rainbow/test/test_portal.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/rainbow/test/test_portal.py	Tue Jun  3 14:47:18 2008
@@ -221,11 +221,11 @@
 
         res = self.timeshift_from_portal(ll_main, ll_function, [5], policy=P_NOVIRTUAL)
         assert res == 10
-        self.check_insns(indirect_call=2)
+        self.check_method_calls(2)
 
         res = self.timeshift_from_portal(ll_main, ll_function, [0], policy=P_NOVIRTUAL)
         assert res == ord('2')
-        self.check_insns(indirect_call=2)
+        self.check_method_calls(2)
 
     def test_method_call_promote(self):
         class Base(object):
@@ -627,10 +627,12 @@
 class TestPortalOOType(BaseTestPortal):
     type_system = 'ootype'
 
+    def check_method_calls(self, n):
+        self.check_insns(oosend=2)
+
     def _skip(self):
         py.test.skip('in progress')
 
-    test_method_call_nonpromote = _skip
     test_method_call_promote = _skip
     test_float_promote = _skip
     test_isinstance = _skip
@@ -641,3 +643,5 @@
 class TestPortalLLType(BaseTestPortal):
     type_system = 'lltype'
 
+    def check_method_calls(self, n):
+        self.check_insns(indirect_call=2)

Modified: pypy/branch/oo-jit/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/timeshifter/rtimeshift.py	Tue Jun  3 14:47:18 2008
@@ -594,7 +594,7 @@
 ##def ll_gvar_from_constant(jitstate, ll_value):
 ##    return jitstate.curbuilder.rgenop.genconst(ll_value)
 
-def gen_external_oosend(jitstate, argboxes, methdesc):
+def gen_residual_oosend(jitstate, argboxes, methdesc):
     builder = jitstate.curbuilder
     selfbox = argboxes[0]
     gv_selfbox = selfbox.getgenvar(jitstate)



More information about the Pypy-commit mailing list