[pypy-commit] pypy jit-targets: a retrace can now end with a bad VirtualState as it now has a (possible unrelated) bridge as preamble

hakanardo noreply at buildbot.pypy.org
Thu Dec 1 14:43:42 CET 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-targets
Changeset: r50038:2e06799c48d5
Date: 2011-12-01 14:43 +0100
http://bitbucket.org/pypy/pypy/changeset/2e06799c48d5/

Log:	a retrace can now end with a bad VirtualState as it now has a
	(possible unrelated) bridge as preamble

diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -1,5 +1,5 @@
 from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder, ShortBoxes
+from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateAdder, ShortBoxes, BadVirtualState
 from pypy.jit.metainterp.compile import ResumeGuardDescr
 from pypy.jit.metainterp.history import TreeLoop, TargetToken, JitCellToken
 from pypy.jit.metainterp.jitexc import JitException
@@ -272,7 +272,11 @@
         # Construct jumpargs from the virtual state
         original_jumpargs = jumpop.getarglist()[:]
         values = [self.getvalue(arg) for arg in jumpop.getarglist()]
-        jumpargs = virtual_state.make_inputargs(values, self.optimizer)
+        try:
+            jumpargs = virtual_state.make_inputargs(values, self.optimizer)
+        except BadVirtualState:
+            # FIXME: Produce jump to preamble instead (see test_retrace_not_matching_bridge)
+            raise InvalidLoop
         jumpop.initarglist(jumpargs)
 
         # Inline the short preamble at the end of the loop
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -14,6 +14,9 @@
 from pypy.rlib.objectmodel import we_are_translated
 import os
 
+class BadVirtualState(Exception):
+    pass
+
 class AbstractVirtualStateInfo(resume.AbstractVirtualInfo):
     position = -1
 
@@ -104,7 +107,8 @@
 
     def enum_forced_boxes(self, boxes, value, optimizer):
         assert isinstance(value, virtualize.AbstractVirtualStructValue)
-        assert value.is_virtual()
+        if not value.is_virtual():
+            raise BadVirtualState
         for i in range(len(self.fielddescrs)):
             v = value._fields[self.fielddescrs[i]]
             s = self.fieldstate[i]
@@ -181,7 +185,8 @@
 
     def enum_forced_boxes(self, boxes, value, optimizer):
         assert isinstance(value, virtualize.VArrayValue)
-        assert value.is_virtual()
+        if not value.is_virtual():
+            raise BadVirtualState
         for i in range(len(self.fieldstate)):
             v = value._items[i]
             s = self.fieldstate[i]
@@ -249,7 +254,8 @@
 
     def enum_forced_boxes(self, boxes, value, optimizer):
         assert isinstance(value, virtualize.VArrayStructValue)
-        assert value.is_virtual()
+        if not value.is_virtual():
+            raise BadVirtualState
         p = 0
         for i in range(len(self.fielddescrs)):
             for j in range(len(self.fielddescrs[i])):
diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py
--- a/pypy/jit/metainterp/test/test_virtual.py
+++ b/pypy/jit/metainterp/test/test_virtual.py
@@ -1,5 +1,5 @@
 import py
-from pypy.rlib.jit import JitDriver, promote
+from pypy.rlib.jit import JitDriver, promote, dont_look_inside
 from pypy.rlib.objectmodel import compute_unique_id
 from pypy.jit.codewriter.policy import StopAtXPolicy
 from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -764,6 +764,42 @@
         res = self.meta_interp(f, [0x1F, 0x11])
         assert res == f(0x1F, 0x11)
 
+    def test_retrace_not_matching_bridge(self):
+        @dont_look_inside
+        def external(node):
+            return node.value + 1
+        myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'node', 'node2'])
+        class A():
+            def new(self):
+                return A()
+            def val(self, i):
+                return i + 7
+        class B(A):
+            def new(self):
+                return B()
+            def val(self, i):
+                return i + 42
+        def f(n):
+            node = self._new()
+            node2 = A()
+            node.value = 0
+            i = 0
+            while i < n:
+                myjitdriver.jit_merge_point(n=n, i=i, node=node, node2=node2)
+                next = self._new()
+                next.value = node.value + n + node2.val(i)
+                if i != 7:
+                    next.value += external(next)
+                else:
+                    node2 = B()
+                node = next
+                node2 = node2.new()
+
+                i += 1
+            return node.value 
+        res = self.meta_interp(f, [10], repeat=10)
+        assert res == f(10)
+
 class VirtualMiscTests:
 
     def test_multiple_equal_virtuals(self):


More information about the pypy-commit mailing list