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

cfbolz at codespeak.net cfbolz at codespeak.net
Fri Feb 29 11:19:22 CET 2008


Author: cfbolz
Date: Fri Feb 29 11:19:22 2008
New Revision: 51938

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/portal.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_interpreter.py
   pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py
   pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py
Log:
some support for recursive portal 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	Fri Feb 29 11:19:22 2008
@@ -103,7 +103,9 @@
     def make_bytecode(self, graph, is_portal=True):
         remove_same_as(graph)
         if is_portal:
-            self.all_graphs[graph] = JitCode.__new__(JitCode)
+            bytecode = JitCode.__new__(JitCode)
+            bytecode.is_portal = True
+            self.all_graphs[graph] = bytecode
         self.seen_blocks = {}
         self.assembler = []
         self.constants = []
@@ -795,11 +797,17 @@
         assert len(targets) == 1
         targetgraph, = targets.values()
         graphindex = self.graph_position(targetgraph)
+        bytecode = self.all_graphs[targetgraph]
         args = targetgraph.getargs()
         emitted_args = self.args_of_call(op.args[1:], args)
-        self.emit("red_direct_call")
-        self.emit(*emitted_args)
-        self.emit(graphindex)
+
+        if bytecode.is_portal:
+            self.emit("portal_call", *emitted_args)
+        else:
+            self.emit("red_direct_call")
+            self.emit(*emitted_args)
+            self.emit(graphindex)
+
         if kind == "red":
             self.register_redvar(op.result)
         self.emit("red_after_direct_call")

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	Fri Feb 29 11:19:22 2008
@@ -17,6 +17,7 @@
     green vars are positive indexes
     green consts are negative indexes
     """
+    is_portal = False
 
     def __init__(self, name, code, constants, typekinds, redboxclasses,
                  keydescs, structtypedescs, fielddescs, arrayfielddescs,
@@ -487,6 +488,10 @@
             self.frame.local_green)
         assert newjitstate is self.jitstate
 
+    @arguments("green_varargs", "red_varargs")
+    def opimpl_portal_call(self, greenargs, redargs):
+        self.portalstate.portal_reentry(greenargs, redargs)
+
     @arguments("green", "calldesc", "green_varargs")
     def opimpl_green_direct_call(self, fnptr_gv, calldesc, greenargs):
         calldesc.green_call(self, fnptr_gv, greenargs)

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/portal.py	Fri Feb 29 11:19:22 2008
@@ -42,11 +42,11 @@
             concretetype = originalconcretetype(binding)
             if binding.is_green():
                 ORIGARGS.append(concretetype)
-                arg_spec = "green", None, None
+                arg_spec = "green", None, None, concretetype
             else:
                 argdesc = self.getportalargdesc(concretetype)
                 arg_spec = ("red", argdesc.residual_args_collector(),
-                            argdesc.arg_redbox_maker())
+                            argdesc.arg_redbox_maker(), concretetype)
                 ARGS.extend(argdesc.residual_argtypes())
             args_specification.append(arg_spec)
         self.args_specification = args_specification
@@ -124,7 +124,7 @@
         def make_key(self, *args):
             key = ()
             i = 0
-            for color, collect_residual_args, _ in args_specification:
+            for color, collect_residual_args, _, _ in args_specification:
                 if color == "green":
                     x = args[i]
                     if isinstance(lltype.typeOf(x), lltype.Ptr): 
@@ -133,10 +133,26 @@
                 i = i + 1
             return key
 
+        def make_key_from_genconsts(self, green_gv):
+            key = ()
+            i = 0
+            j = 0
+            for color, collect_residual_args, _, TYPE in args_specification:
+                if color == "green":
+                    genconst = green_gv[j]
+                    x = genconst.revealconst(TYPE)
+                    if isinstance(TYPE, lltype.Ptr): 
+                        x = llmemory.cast_ptr_to_adr(x)
+                    key = key + (x,)
+                    j += 1
+                i = i + 1
+            return key
+
+
         def make_residualargs(self, *args):
             residualargs = ()
             i = 0
-            for color, collect_residual_args, _ in args_specification:
+            for color, collect_residual_args, _, _ in args_specification:
                 if color != "green":
                     residualargs = residualargs + collect_residual_args(args[i])
                 i = i + 1
@@ -162,6 +178,48 @@
             else:
                 return fn(*residualargs)
 
+        def portal_reentry(self, greenargs, redargs):
+            jitstate = self.interpreter.jitstate
+            curbuilder = jitstate.curbuilder
+            rgenop = self.interpreter.rgenop
+            i = 0
+            cache = self.cache
+            key = self.make_key_from_genconsts(greenargs)
+            try:
+                gv_generated = cache[key]
+            except KeyError:
+                builder, gv_generated, inputargs_gv = rgenop.newgraph(sigtoken,
+                                                                      "generated")
+                self.cache[key] = gv_generated
+                top_jitstate = self.interpreter.fresh_jitstate(builder)
+                newredargs = ()
+                red_i = 0
+                for color, _, make_arg_redbox, _ in args_specification:
+                    if color == "red":
+                        box = make_arg_redbox(top_jitstate, inputargs_gv, red_i)
+                        red_i += make_arg_redbox.consumes
+                        newredargs += (box,)
+                newredargs = list(newredargs)
+
+                self.graph_compilation_queue.append(
+                    (top_jitstate, greenargs, newredargs))
+            residualargs_gv = [box.getgenvar(jitstate) for box in redargs]
+
+            gv_res = curbuilder.genop_call(sigtoken, gv_generated,
+                                           residualargs_gv)
+            self.interpreter.exceptiondesc.fetch_global_excdata(jitstate)
+
+            RESTYPE = RESIDUAL_FUNCTYPE.RESULT
+            reskind = rgenop.kindToken(RESTYPE)
+            boxbuilder = rvalue.ll_redboxbuilder(RESTYPE)
+
+            if RESTYPE == lltype.Void:
+                retbox = None
+            else:
+                retbox = boxbuilder(reskind, gv_res)
+            jitstate.returnbox = retbox
+            assert jitstate.next is None
+
 
         def compile(self, key, *args):
             portal_ts_args = ()
@@ -173,14 +231,12 @@
             greenargs = ()
             redargs = ()
             red_i = 0
-            for color, _, make_arg_redbox in args_specification:
+            for color, _, make_arg_redbox, _ in args_specification:
+                llvalue = args[0]
+                args = args[1:]
                 if color == "green":
-                    llvalue = args[0]
-                    args = args[1:]
                     greenargs += (rgenop.genconst(llvalue),)
                 else:
-                    llvalue = args[0]
-                    args = args[1:]
                     box = make_arg_redbox(top_jitstate, inputargs_gv, red_i)
                     red_i += make_arg_redbox.consumes
                     redargs += (box,)
@@ -196,7 +252,7 @@
         def readportal(self, *args):
             i = 0
             key = ()
-            for color, _, _ in args_specification:
+            for color, _, _, _ in args_specification:
                 if color == "green":
                     x = args[i]
                     if isinstance(lltype.typeOf(x), lltype.Ptr): 

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	Fri Feb 29 11:19:22 2008
@@ -554,12 +554,14 @@
         self.check_insns({'int_gt': 1})
 
     def test_recursive_call(self):
+        def indirection(n, fudge):
+            return ll_pseudo_factorial(n, fudge)
         def ll_pseudo_factorial(n, fudge):
             k = hint(n, concrete=True)
             if n <= 0:
                 return 1
             return n * ll_pseudo_factorial(n - 1, fudge + n) - fudge
-        res = self.interpret(ll_pseudo_factorial, [4, 2], [0])
+        res = self.interpret(indirection, [4, 2], [0])
         expected = ll_pseudo_factorial(4, 2)
         assert res == expected
         

Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_portal.py	Fri Feb 29 11:19:22 2008
@@ -424,3 +424,119 @@
         res = self.timeshift_from_portal(f, f, [15], policy=P_OOPSPEC)
         assert res == 15
 
+
+    def test_simple_recursive_portal_call(self):
+
+        def main(code, x):
+            return evaluate(code, x)
+
+        def evaluate(y, x):
+            hint(y, concrete=True)
+            if y <= 0:
+                return x
+            z = 1 + evaluate(y - 1, x)
+            return z
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 2])
+        assert res == 5
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 5])
+        assert res == 8
+
+        res = self.timeshift_from_portal(main, evaluate, [4, 7])
+        assert res == 11
+    
+
+    def test_simple_recursive_portal_call2(self):
+
+        def main(code, x):
+            return evaluate(code, x)
+
+        def evaluate(y, x):
+            hint(y, concrete=True)
+            if x <= 0:
+                return y
+            z = evaluate(y, x - 1) + 1
+            return z
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 2])
+        assert res == 5
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 5])
+        assert res == 8
+
+        res = self.timeshift_from_portal(main, evaluate, [4, 7])
+        assert res == 11
+    
+    def test_simple_recursive_portal_call_with_exc(self):
+
+        def main(code, x):
+            return evaluate(code, x)
+
+        class Bottom(Exception):
+            pass
+
+        def evaluate(y, x):
+            hint(y, concrete=True)
+            if y <= 0:
+                raise Bottom
+            try:
+                z = 1 + evaluate(y - 1, x)
+            except Bottom:
+                z = 1 + x
+            return z
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 2])
+        assert res == 5
+
+        res = self.timeshift_from_portal(main, evaluate, [3, 5])
+        assert res == 8
+
+        res = self.timeshift_from_portal(main, evaluate, [4, 7])
+        assert res == 11
+    
+
+    def test_portal_returns_none(self):
+        py.test.skip("portal returning None is not supported")
+        def g(x):
+            x = hint(x, promote=True)
+            if x == 42:
+                return None
+        def f(x):
+            return g(x)
+
+        res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
+
+    def test_portal_returns_none_with_origins(self):
+        py.test.skip("portal returning None is not supported")
+        def returnNone():
+            pass
+        def returnNone2():
+            pass
+        def g(x):
+            x = hint(x, promote=True)
+            if x == 42:
+                return returnNone()
+            return returnNone2()
+        def f(x):
+            return g(x)
+
+        res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
+
+    def test_recursive_portal_call(self):
+        py.test.skip("not working yet")
+        def indirection(green, red):
+            newgreen = hint((green + red) % 100, promote=True)
+            return portal(newgreen, red + 1)
+        def portal(green, red):
+            hint(None, global_merge_point=True)
+            green = abs(green)
+            red = abs(red)
+            hint(green, concrete=True)
+            if green > 42:
+                return 0
+            if red > 42:
+                return 1
+            return indirection(green, red)
+        res = self.timeshift_from_portal(portal, portal, [41, 1], policy=P_NOVIRTUAL)
+        assert res == 0

Modified: pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py	(original)
+++ pypy/branch/jit-refactoring/pypy/jit/timeshifter/test/test_portal.py	Fri Feb 29 11:19:22 2008
@@ -141,117 +141,3 @@
         return calls
         
 class TestPortal(PortalTest):
-    def test_simple_recursive_portal_call(self):
-
-        def main(code, x):
-            return evaluate(code, x)
-
-        def evaluate(y, x):
-            hint(y, concrete=True)
-            if y <= 0:
-                return x
-            z = 1 + evaluate(y - 1, x)
-            return z
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 2])
-        assert res == 5
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 5])
-        assert res == 8
-
-        res = self.timeshift_from_portal(main, evaluate, [4, 7])
-        assert res == 11
-    
-
-    def test_simple_recursive_portal_call2(self):
-
-        def main(code, x):
-            return evaluate(code, x)
-
-        def evaluate(y, x):
-            hint(y, concrete=True)
-            if x <= 0:
-                return y
-            z = evaluate(y, x - 1) + 1
-            return z
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 2])
-        assert res == 5
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 5])
-        assert res == 8
-
-        res = self.timeshift_from_portal(main, evaluate, [4, 7])
-        assert res == 11
-    
-    def test_simple_recursive_portal_call_with_exc(self):
-
-        def main(code, x):
-            return evaluate(code, x)
-
-        class Bottom(Exception):
-            pass
-
-        def evaluate(y, x):
-            hint(y, concrete=True)
-            if y <= 0:
-                raise Bottom
-            try:
-                z = 1 + evaluate(y - 1, x)
-            except Bottom:
-                z = 1 + x
-            return z
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 2])
-        assert res == 5
-
-        res = self.timeshift_from_portal(main, evaluate, [3, 5])
-        assert res == 8
-
-        res = self.timeshift_from_portal(main, evaluate, [4, 7])
-        assert res == 11
-    
-
-    def test_portal_returns_none(self):
-        py.test.skip("portal returning None is not supported")
-        def g(x):
-            x = hint(x, promote=True)
-            if x == 42:
-                return None
-        def f(x):
-            return g(x)
-
-        res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
-
-    def test_portal_returns_none_with_origins(self):
-        py.test.skip("portal returning None is not supported")
-        def returnNone():
-            pass
-        def returnNone2():
-            pass
-        def g(x):
-            x = hint(x, promote=True)
-            if x == 42:
-                return returnNone()
-            return returnNone2()
-        def f(x):
-            return g(x)
-
-        res = self.timeshift_from_portal(f, g, [42], policy=P_NOVIRTUAL)
-
-    def test_recursive_portal_call(self):
-        def indirection(green, red):
-            newgreen = hint((green + red) % 100, promote=True)
-            return portal(newgreen, red + 1)
-        def portal(green, red):
-            hint(None, global_merge_point=True)
-            green = abs(green)
-            red = abs(red)
-            hint(green, concrete=True)
-            if green > 42:
-                return 0
-            if red > 42:
-                return 1
-            return indirection(green, red)
-        res = self.timeshift_from_portal(portal, portal, [41, 1], policy=P_NOVIRTUAL)
-        assert res == 0



More information about the Pypy-commit mailing list