Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: guard-compatible Changeset: r85430:f8abbe802a80 Date: 2016-06-24 23:39 +0200 http://bitbucket.org/pypy/pypy/changeset/f8abbe802a80/
Log: corner case: sometimes the guarded value is really missing from the failargs, in which case we are annoyed, but should still not crash. 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 @@ -1114,19 +1114,19 @@ # if new_loop starts with another guard_compatible on the same argument # (which is most of the time) we have to connect the new guard's descr # to this descr - assert self.failarg_index != -1 - arg = new_loop.inputargs[self.failarg_index] - firstop = new_loop.operations[0] compat_cond = None - if (firstop.getopnum() == rop.GUARD_COMPATIBLE and - firstop.getarg(0) is arg): - # a guard_compatible about the same box - # remove it, it doesn't have to be checked in the bridge - del new_loop.operations[0] - newdescr = firstop.getdescr() - assert isinstance(newdescr, GuardCompatibleDescr) - compat_cond = newdescr._compatibility_conditions - self.other_compat_conditions.append(compat_cond) + if self.failarg_index != -1: + arg = new_loop.inputargs[self.failarg_index] + firstop = new_loop.operations[0] + if (firstop.getopnum() == rop.GUARD_COMPATIBLE and + firstop.getarg(0) is arg): + # a guard_compatible about the same box + # remove it, it doesn't have to be checked in the bridge + del new_loop.operations[0] + newdescr = firstop.getdescr() + assert isinstance(newdescr, GuardCompatibleDescr) + compat_cond = newdescr._compatibility_conditions + self.other_compat_conditions.append(compat_cond) asminfo = ResumeGuardDescr.compile_and_attach( self, metainterp, new_loop, orig_inputargs) if compat_cond: @@ -1134,8 +1134,12 @@ return asminfo def make_a_counter_per_value(self, guard_value_op, index): - self.failarg_index = guard_value_op.getfailargs().index( - guard_value_op.getarg(0)) + try: + self.failarg_index = guard_value_op.getfailargs().index( + guard_value_op.getarg(0)) + except ValueError: + pass # we don't set the failarg_index, too bad + # this is not actually enabling the counter_per_value logic, # which right now gives bad results with a GUARD_COMPATIBLE #ResumeGuardDescr.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 @@ -362,6 +362,53 @@ # trace, two bridges, a finish bridge self.check_trace_count(4) + def test_merge_obj_not_in_failargs(self): + S = lltype.GcStruct('S', ('x', lltype.Signed)) + p1 = lltype.malloc(S) + p1.x = 1 + + p2 = lltype.malloc(S) + p2.x = 1 + + driver = jit.JitDriver(greens = [], reds = ['n']) + + class A(object): + pass + + c = A() + c.count = 0 + @jit.elidable_compatible() + def g(s, ignored): + c.count += 1 + return s.x + + class B(object): + pass + + glob_b = B() + + def f(n): + while n > 0: + driver.can_enter_jit(n=n) + driver.jit_merge_point(n=n) + x = glob_b.x + n -= g(x, "abc") + if n & 2: + n -= 2 + + def main(): + g(p1, "def") # make annotator not make argument constant + glob_b.x = p1 + f(1000) + glob_b.x = p2 + f(1000) + return c.count + + x = self.meta_interp(main, []) + + # trace, two bridges, a finish bridge + self.check_trace_count(4) + def test_merge_switch_object(self): S = lltype.GcStruct('S', ('x', lltype.Signed)) p1 = lltype.malloc(S) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit