[pypy-svn] r65991 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test

fijal at codespeak.net fijal at codespeak.net
Fri Jun 26 06:58:48 CEST 2009


Author: fijal
Date: Fri Jun 26 06:58:48 2009
New Revision: 65991

Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Log:
Detect if can_inline is misbehaving and raise if we see can_enter_jit within
inlined function. Hopefully we'll change it into some other mechanism,
but for now it's a fatal crash


Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Fri Jun 26 06:58:48 2009
@@ -586,6 +586,7 @@
             portal_code = self.metainterp.staticdata.portal_code
             greenkey = varargs[1:num_green_args + 1]
             if self.metainterp.staticdata.warmrunnerdesc.can_inline_callable(greenkey):
+                self.metainterp.in_recursion += 1
                 return self.perform_call(portal_code, varargs[1:])
         return self.execute_with_exc(rop.CALL, varargs, descr=calldescr)
 
@@ -765,6 +766,9 @@
         # may be completely skipped by the logic that replaces perform_call
         # with rop.CALL.  But in that case, no-one will check the flag anyway,
         # so it's fine.
+        if self.metainterp.in_recursion:
+            from pypy.jit.metainterp.warmspot import CannotInlineCanEnterJit
+            raise CannotInlineCanEnterJit()
         self.metainterp.seen_can_enter_jit = True
 
     @arguments("orgpc")
@@ -1057,6 +1061,7 @@
 # ____________________________________________________________
 
 class MetaInterp(object):
+    in_recursion = 0
     def __init__(self, staticdata):
         self.staticdata = staticdata
         self.cpu = staticdata.cpu
@@ -1072,6 +1077,8 @@
 
     def finishframe(self, resultbox):
         frame = self.framestack.pop()
+        if frame.jitcode is self.staticdata.portal_code:
+            self.in_recursion -= 1
         if not we_are_translated():
             self._debug_history.append(['leave', frame.jitcode, None])
         if self.framestack:
@@ -1189,6 +1196,7 @@
                 debug_print('~~~ LEAVE', self.history.extratext)
 
     def interpret(self):
+        self.in_recursion = 0
         if we_are_translated():
             self._interpret()
         else:

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py	Fri Jun 26 06:58:48 2009
@@ -4,6 +4,7 @@
 from pypy.jit.metainterp.simple_optimize import Optimizer
 from pypy.jit.metainterp.policy import StopAtXPolicy
 from pypy.rpython.annlowlevel import hlstr
+from pypy.jit.metainterp.warmspot import CannotInlineCanEnterJit
 
 class RecursiveTests:
 
@@ -95,14 +96,19 @@
                                policy=StopAtXPolicy(opaque))
         assert res == 1
 
-    def get_interpreter(self, codes):
+    def get_interpreter(self, codes, always_inline=False):
         ADD = "0"
         JUMP_BACK = "1"
         CALL = "2"
+        EXIT = "3"
 
-        def can_inline(code, i):
-            code = hlstr(code)
-            return not JUMP_BACK in code
+        if always_inline:
+            def can_inline(*args):
+                return True
+        else:
+            def can_inline(code, i):
+                code = hlstr(code)
+                return not JUMP_BACK in code
 
         jitdriver = JitDriver(greens = ['code', 'i'], reds = ['n'],
                               can_inline = can_inline)
@@ -123,6 +129,8 @@
                         return 42
                     i -= 2
                     jitdriver.can_enter_jit(n=n, i=i, code=code)
+                elif op == EXIT:
+                    return n
                 else:
                     raise NotImplementedError
             return n
@@ -153,6 +161,21 @@
                                 inline=True) == 42
         self.check_loops(call = 1)
 
+    def test_inline_faulty_can_inline(self):
+        code = "021"
+        subcode = "301"
+        codes = [code, subcode]
+
+        f = self.get_interpreter(codes, always_inline=True)
+
+        try:
+            self.meta_interp(f, [0, 0, 0], optimizer=Optimizer,
+                             inline=True)
+        except CannotInlineCanEnterJit:
+            pass
+        else:
+            py.test.fail("DID NOT RAISE")
+
 class TestLLtype(RecursiveTests, LLJitMixin):
     pass
 

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py	Fri Jun 26 06:58:48 2009
@@ -119,6 +119,9 @@
 class JitException(Exception):
     _go_through_llinterp_uncaught_ = True     # ugh
 
+class CannotInlineCanEnterJit(JitException):
+    pass
+
 # ____________________________________________________________
 
 class WarmRunnerDesc:



More information about the Pypy-commit mailing list