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

Reply via email to