[pypy-commit] pypy guard-compatible: emulate the x86's behavior wrt always caching the most recent result of

arigo pypy.commits at gmail.com
Sun May 22 15:54:18 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: guard-compatible
Changeset: r84589:802f122fcc75
Date: 2016-05-22 21:53 +0200
http://bitbucket.org/pypy/pypy/changeset/802f122fcc75/

Log:	emulate the x86's behavior wrt always caching the most recent result
	of find_compatible(), even if that was a return of 0.

diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -364,6 +364,10 @@
         if not isinstance(faildescr, GuardCompatibleDescr):
             # don't patch GuardCompatibleDescr
             faildescr._llgraph_bridge = lltrace
+        else:
+            # invalidate the cache
+            if hasattr(faildescr, '_guard_compatible_llgraph_lst'):
+                faildescr._guard_compatible_llgraph_lst[0] = (None, None)
         clt._llgraph_alltraces.append(lltrace)
         self._record_labels(lltrace)
         return LLAsmInfo(lltrace)
@@ -1159,6 +1163,7 @@
         if force_bridge is None:
             force_bridge = getattr(descr, '_llgraph_bridge', None)
         if force_bridge is not None:
+            assert isinstance(force_bridge, LLTrace)
             if propagate_exception:
                 assert (force_bridge.operations[0].opnum in
                         (rop.SAVE_EXC_CLASS, rop.GUARD_EXCEPTION,
@@ -1294,22 +1299,30 @@
             try:
                 lst = descr._guard_compatible_llgraph_lst
             except AttributeError:
-                lst = descr._guard_compatible_llgraph_lst = []
+                lst = descr._guard_compatible_llgraph_lst = [(None, None)]
             for ref, target in lst:
-                if ref == arg1:
+                if ref is not None and ref == arg1:
                     break
             else:
                 target = descr.find_compatible(self.cpu, arg1)
-                if target == 0:
-                    self.fail_guard(descr, extra_value=arg1)
-                    assert 0, "fail_guard should raise"
-                descr._guard_compatible_llgraph_lst.append((arg1, target))
+                # we use list item 0 as the cache, which caches
+                # the most recent find_compatible() result even if
+                # it returned zero.  For non-zero results, we also
+                # save them away in another non-overwritable entry.
+                pair = (arg1, target)
+                descr._guard_compatible_llgraph_lst[0] = pair
+                if target != 0:
+                    descr._guard_compatible_llgraph_lst.append(pair)
             #
             if target == -1:
                 return
+            elif target == 0:
+                self.fail_guard(descr, extra_value=arg1)
+                assert 0, "fail_guard should raise"
             else:
                 self.fail_guard(descr, extra_value='should not be used',
                                 force_bridge=target)
+                assert 0, "fail_guard should raise"
 
     def execute_int_add_ovf(self, _, x, y):
         try:
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -257,8 +257,11 @@
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         assert seen == []
 
-        t_list = [t1_box._resref, t2_box._resref, t3_box._resref]
+        t_list = [t1_box._resref, t1_box._resref,
+                  t2_box._resref, t2_box._resref,
+                  t3_box._resref, t3_box._resref]
         expected = []
+        prev_t = None
         for t in t_list * 2:
             # find_compatible() returns 0: the guard fails
             deadframe = self.cpu.execute_token(looptoken, t)
@@ -267,8 +270,12 @@
                 assert fail.identifier == 2
             else:
                 assert fail.identifier == 1
-                expected.append(t)     # never cache returns of 0
+                # returns of 0 are only cached if they are the most recent
+                # return, not longer
+                if t != prev_t:
+                    expected.append(t)
             assert seen == expected
+            prev_t = t
 
     def test_extend_guard_compatible_3(self):
         seen = []


More information about the pypy-commit mailing list