Author: Armin Rigo <ar...@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 = [] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit