Author: Hakan Ardo <ha...@debian.org> Branch: Changeset: r54810:1ba8cd8dfd89 Date: 2012-04-29 15:26 +0200 http://bitbucket.org/pypy/pypy/changeset/1ba8cd8dfd89/
Log: Verify that the struct pointer is the same as during tracing before optimizing out a quasiimmutable getfield. This hopefully fixes the inifite_loop bug of issue 1080. diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py --- a/pypy/jit/metainterp/optimizeopt/heap.py +++ b/pypy/jit/metainterp/optimizeopt/heap.py @@ -481,7 +481,7 @@ # already between the tracing and now. In this case, we are # simply ignoring the QUASIIMMUT_FIELD hint and compiling it # as a regular getfield. - if not qmutdescr.is_still_valid(): + if not qmutdescr.is_still_valid_for(structvalue.get_key_box()): self._remove_guard_not_invalidated = True return # record as an out-of-line guard diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py --- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py @@ -6533,9 +6533,9 @@ def test_quasi_immut_2(self): ops = """ [] - quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr) + quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr) guard_not_invalidated() [] - i1 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr) + i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr) escape(i1) jump() """ @@ -6585,13 +6585,13 @@ def test_call_may_force_invalidated_guards_reload(self): ops = """ [i0a, i0b] - quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr) + quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr) guard_not_invalidated() [] - i1 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr) + i1 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr) call_may_force(i0b, descr=mayforcevirtdescr) - quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr) + quasiimmut_field(ConstPtr(quasiptr), descr=quasiimmutdescr) guard_not_invalidated() [] - i2 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr) + i2 = getfield_gc(ConstPtr(quasiptr), descr=quasifielddescr) i3 = escape(i1) i4 = escape(i2) jump(i3, i4) @@ -7833,8 +7833,13 @@ setfield_gc(p106, p108, descr=nextdescr) # inst_storage jump(p106) """ - py.test.raises(InvalidLoop, self.optimize_loop, - ops, expected) + expected = """ + [] + p72 = getfield_gc(ConstPtr(myptr2), descr=quasifielddescr) + guard_value(p72, -4247) [] + jump() + """ + self.optimize_loop(ops, expected) def test_issue1080_infinitie_loop_simple(self): @@ -7852,8 +7857,7 @@ guard_value(p72, -4247) [] jump() """ - py.test.raises(InvalidLoop, self.optimize_loop, - ops, expected) + self.optimize_loop(ops, expected) class TestLLtype(OptimizeOptTest, LLtypeMixin): pass diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py --- a/pypy/jit/metainterp/optimizeopt/test/test_util.py +++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py @@ -122,6 +122,7 @@ quasi.inst_field = -4247 quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field') quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi)) + quasiptr = quasibox.value quasiimmutdescr = QuasiImmutDescr(cpu, quasibox, quasifielddescr, cpu.fielddescrof(QUASI, 'mutate_field')) diff --git a/pypy/jit/metainterp/quasiimmut.py b/pypy/jit/metainterp/quasiimmut.py --- a/pypy/jit/metainterp/quasiimmut.py +++ b/pypy/jit/metainterp/quasiimmut.py @@ -120,8 +120,10 @@ self.fielddescr, self.structbox) return fieldbox.constbox() - def is_still_valid(self): + def is_still_valid_for(self, structconst): assert self.structbox is not None + if not self.structbox.constbox().same_constant(structconst): + return False cpu = self.cpu gcref = self.structbox.getref_base() qmut = get_current_qmut_instance(cpu, gcref, self.mutatefielddescr) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit