Author: Hakan Ardo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit