Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: guard-compatible
Changeset: r85437:09617ecb9107
Date: 2016-06-28 16:49 +0200
http://bitbucket.org/pypy/pypy/changeset/09617ecb9107/

Log:    fix the problem

        when attaching a new bridge to a GuardCompatibleDescr and we cannot
        find out whether the new bridge is checking conditions on the same
        variable as the GuardCompatibleDescr, the guard needs to henceforth
        always jump to that new trace if none of the other traces match.
        Otherwise we will keep compiling more and more code.

diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -1091,6 +1091,12 @@
         # list of compatibility conditions about the same variable, with
         # bridges attached to them
         self.other_compat_conditions = []
+        # fallback jump target is the one to jump to if the generated bridges
+        # do not start with a guard_compatible at all, so we don't have a basis
+        # to decide on
+        # XXX it would be better to patch the guard properly in the backend,
+        # but later
+        self.fallback_jump_target = 0
 
     def find_compatible(self, cpu, ref):
         """ callback for the CPU: given a value ref, it returns:
@@ -1108,7 +1114,10 @@
             if _compatibility_conditions.check_compat_and_activate(
                     cpu, ref, self.rd_loop_token):
                 return _compatibility_conditions.jump_target
-        return 0
+        # none of the other conditions matched. if we have a
+        # fallback_jump_target, go there (otherwise we run the risk of
+        # producing arbitrary amounts of code)
+        return self.fallback_jump_target
 
     def compile_and_attach(self, metainterp, new_loop, orig_inputargs):
         # if new_loop starts with another guard_compatible on the same argument
@@ -1131,6 +1140,9 @@
             self, metainterp, new_loop, orig_inputargs)
         if compat_cond:
             compat_cond.jump_target = asminfo.asmaddr
+        else:
+            assert self.fallback_jump_target == 0 # this can never happen twice
+            self.fallback_jump_target = asminfo.asmaddr
         return asminfo
 
     def make_a_counter_per_value(self, guard_value_op, index):
diff --git a/rpython/jit/metainterp/test/test_compatible.py 
b/rpython/jit/metainterp/test/test_compatible.py
--- a/rpython/jit/metainterp/test/test_compatible.py
+++ b/rpython/jit/metainterp/test/test_compatible.py
@@ -418,8 +418,7 @@
 
         x = self.meta_interp(main, [])
 
-        # trace, two bridges, a finish bridge
-        self.check_trace_count(4)
+        self.check_trace_count(6)
 
     def test_merge_switch_object(self):
         S = lltype.GcStruct('S', ('x', lltype.Signed))
@@ -611,7 +610,7 @@
 
         x = self.meta_interp(main, [False])
         assert x < 70
-        self.check_trace_count(9)
+        self.check_trace_count(7)
         self.check_resops(call_i=0)
 
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to