[pypy-svn] r52440 - in pypy/branch/jit-hotpath/pypy/jit/rainbow: . test

arigo at codespeak.net arigo at codespeak.net
Thu Mar 13 11:23:03 CET 2008


Author: arigo
Date: Thu Mar 13 11:23:02 2008
New Revision: 52440

Modified:
   pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
   pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
Log:
Start supporting portals that exit with a 'return'.


Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/fallback.py	Thu Mar 13 11:23:02 2008
@@ -12,11 +12,13 @@
     actual values for the live red vars, and interprets the jitcode
     normally until it reaches the 'jit_merge_point' or raises.
     """
-    def __init__(self, interpreter, ContinueRunningNormally, exceptiondesc):
+    def __init__(self, interpreter, exceptiondesc,
+                 DoneWithThisFrame, ContinueRunningNormally):
         self.interpreter = interpreter
         self.rgenop = interpreter.rgenop
-        self.ContinueRunningNormally = ContinueRunningNormally
         self.exceptiondesc = exceptiondesc
+        self.DoneWithThisFrame = DoneWithThisFrame
+        self.ContinueRunningNormally = ContinueRunningNormally
         self.register_opcode_impls(interpreter)
 
     def run(self, fallback_point, framebase, pc):
@@ -70,6 +72,21 @@
             XXX
         return gv_res
 
+    def leave_fallback_interp(self, gv_result):
+        # at this point we might have an exception set in self.gv_exc_xxx
+        # and we have to really raise it.
+        exceptiondesc = self.exceptiondesc
+        lltype = self.gv_exc_type.revealconst(exceptiondesc.LL_EXC_TYPE)
+        if lltype:
+            # XXX non-translatable hack follows...
+            from pypy.rpython.llinterp import LLException, type_name
+            llvalue = self.gv_exc_value.revealconst(exceptiondesc.LL_EXC_VALUE)
+            assert lltype and llvalue
+            self.interpreter.debug_trace("fb_raise", type_name(lltype))
+            raise LLException(lltype, llvalue)
+        else:
+            raise self.DoneWithThisFrame(gv_result)
+
     # ____________________________________________________________
     # XXX Lots of copy and paste from interp.py!
 
@@ -381,15 +398,12 @@
     @arguments()
     def opimpl_hp_gray_return(self):
         assert self.current_source_jitframe.backframe is None   # XXX for now
-        # at this point we should have an exception set in self.gv_exc_xxx
-        # and we have to really raise it.  XXX non-translatable hack follows...
-        from pypy.rpython.llinterp import LLException, type_name
-        exceptiondesc = self.exceptiondesc
-        lltype = self.gv_exc_type.revealconst(exceptiondesc.LL_EXC_TYPE)
-        llvalue = self.gv_exc_value.revealconst(exceptiondesc.LL_EXC_VALUE)
-        assert lltype and llvalue
-        self.interpreter.debug_trace("fb_raise", type_name(lltype))
-        raise LLException(lltype, llvalue)
+        self.leave_fallback_interp(None)
+
+    @arguments()
+    def opimpl_hp_red_return(self):
+        assert self.current_source_jitframe.backframe is None   # XXX for now
+        self.leave_fallback_interp(self.local_red[0])
 
     @arguments()
     def opimpl_hp_yellow_return(self):

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/hotpath.py	Thu Mar 13 11:23:02 2008
@@ -38,10 +38,6 @@
 
     def make_args_specification(self):
         origportalgraph = self.hintannotator.portalgraph
-        for block in origportalgraph.iterblocks():
-            if block is origportalgraph.returnblock:
-                raise Exception("XXX doesn't support portal functions with"
-                                " a 'return' yet - leave it with 'raise' :-)")
         newportalgraph = self.hintannotator.translator.graphs[0]
         ALLARGS = []
         RESARGS = []
@@ -94,8 +90,9 @@
     def update_interp(self):
         self.fallbackinterp = FallbackInterpreter(
             self.interpreter,
-            self.ContinueRunningNormally,
-            self.codewriter.exceptiondesc)
+            self.codewriter.exceptiondesc,
+            self.DoneWithThisFrame,
+            self.ContinueRunningNormally)
         ERASED = self.RGenOp.erasedType(lltype.Bool)
         self.interpreter.bool_hotpromotiondesc = rhotpath.HotPromotionDesc(
             ERASED, self.interpreter, self.threshold, self.fallbackinterp)
@@ -178,8 +175,8 @@
                               # not its copy
 
         ARGS = [v.concretetype for v in portalgraph.getargs()]
-        assert portalgraph.getreturnvar().concretetype is lltype.Void
-        PORTALFUNC = lltype.FuncType(ARGS, lltype.Void)
+        RES = portalgraph.getreturnvar().concretetype
+        PORTALFUNC = lltype.FuncType(ARGS, RES)
 
         if not self.translate_support_code:
             # ____________________________________________________________
@@ -190,6 +187,17 @@
             llinterp = LLInterpreter(self.rtyper, exc_data_ptr=exc_data_ptr)
             maybe_enter_jit = self.maybe_enter_jit_fn
 
+            class DoneWithThisFrame(Exception):
+                _go_through_llinterp_uncaught_ = True     # ugh
+                def __init__(self, gv_result):
+                    if RES is lltype.Void:
+                        assert gv_result is None
+                        self.result = None
+                    else:
+                        self.result = gv_result.revealconst(RES)
+                def __str__(self):
+                    return 'DoneWithThisFrame(%s)' % (self.result,)
+
             class ContinueRunningNormally(Exception):
                 _go_through_llinterp_uncaught_ = True     # ugh
                 def __init__(self, args_gv, seen_can_enter_jit):
@@ -200,6 +208,8 @@
                 def __str__(self):
                     return 'ContinueRunningNormally(%s)' % (
                         ', '.join(map(str, self.args)),)
+
+            self.DoneWithThisFrame = DoneWithThisFrame
             self.ContinueRunningNormally = ContinueRunningNormally
 
             def portal_runner(*args):
@@ -208,8 +218,9 @@
                     try:
                         if check_for_immediate_reentry:
                             maybe_enter_jit(*args)
-                        llinterp.eval_graph(portalgraph, list(args))
-                        assert 0, "unreachable"
+                        return llinterp.eval_graph(portalgraph, list(args))
+                    except DoneWithThisFrame, e:
+                        return e.result
                     except ContinueRunningNormally, e:
                         args = e.args
                         self.interpreter.debug_trace("fb_leave", *args)
@@ -235,13 +246,12 @@
         vlist += greens_v
         vlist += reds_v
         v_result = Variable()
-        v_result.concretetype = lltype.Void
+        v_result.concretetype = RES
         newop = SpaceOperation('direct_call', vlist, v_result)
         del origblock.operations[origindex:]
         origblock.operations.append(newop)
         origblock.exitswitch = None
-        origblock.recloseblock(Link([Constant(None, lltype.Void)],
-                                    origportalgraph.returnblock))
+        origblock.recloseblock(Link([v_result], origportalgraph.returnblock))
         checkgraph(origportalgraph)
         return True
 

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	Thu Mar 13 11:23:02 2008
@@ -881,7 +881,11 @@
 
     @arguments()
     def opimpl_hp_gray_return(self):
-        assert False, "unreachable for now"
+        xxx
+
+    @arguments()
+    def opimpl_hp_red_return(self):
+        xxx
 
     @arguments()
     def opimpl_hp_yellow_return(self):

Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py	(original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_hotpath.py	Thu Mar 13 11:23:02 2008
@@ -202,7 +202,6 @@
         assert len(self.rewriter.interpreter.debug_traces) < 20
 
     def test_simple_return(self):
-        py.test.skip("in-progress")
         def ll_function(n):
             total = 0
             if n <= 0:
@@ -217,7 +216,12 @@
 
         res = self.run(ll_function, [0], threshold=3, small=True)
         assert res == -1
-        assert len(self.rewriter.interpreter.debug_traces) == 0
+        self.check_traces([])
+
+        res = self.run(ll_function, [3], threshold=3, small=True)
+        assert res == (3*4)/2
+        self.check_traces(['jit_not_entered 2 3',
+                           'jit_not_entered 1 5'])
 
         res = self.run(ll_function, [50], threshold=3, small=True)
         assert res == (50*51)/2



More information about the Pypy-commit mailing list