[pypy-commit] pypy default: Fix. Obscure case causing endless troubles. See irc discussion.

arigo noreply at buildbot.pypy.org
Mon Jan 5 13:43:11 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r75242:cd4b0dd3d1e3
Date: 2015-01-05 13:43 +0100
http://bitbucket.org/pypy/pypy/changeset/cd4b0dd3d1e3/

Log:	Fix. Obscure case causing endless troubles. See irc discussion.

diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -269,9 +269,8 @@
             op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
             guards.append(op)
         elif level == LEVEL_KNOWNCLASS:
-            op = ResOperation(rop.GUARD_NONNULL, [box], None)
-            guards.append(op)
-            op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
+            op = ResOperation(rop.GUARD_NONNULL_CLASS,
+                              [box, self.known_class], None)
             guards.append(op)
         else:
             if level == LEVEL_NONNULL:
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -297,7 +297,8 @@
                 name = "<unknown>"
             raise InvalidLoop('A promote of a virtual %s (a recently allocated object) never makes sense!' % name)
         old_guard_op = value.get_last_guard(self.optimizer)
-        if old_guard_op:
+        if old_guard_op and not isinstance(old_guard_op.getdescr(),
+                                           compile.ResumeAtPositionDescr):
             # there already has been a guard_nonnull or guard_class or
             # guard_nonnull_class on this value, which is rather silly.
             # replace the original guard with a guard_value
@@ -316,6 +317,11 @@
             op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
                         args = [old_guard_op.getarg(0), op.getarg(1)],
                         descr = descr)
+            # Note: we give explicitly a new descr for 'op'; this is why the
+            # old descr must not be ResumeAtPositionDescr (checked above).
+            # Better-safe-than-sorry but it should never occur: we should
+            # not put in short preambles guard_xxx and guard_value
+            # on the same box.
             self.optimizer.replace_guard(op, value)
             descr.make_a_counter_per_value(op)
             # to be safe
@@ -354,7 +360,8 @@
                               % r)
         assert isinstance(value, PtrOptValue)
         old_guard_op = value.get_last_guard(self.optimizer)
-        if old_guard_op:
+        if old_guard_op and not isinstance(old_guard_op.getdescr(),
+                                           compile.ResumeAtPositionDescr):
             # there already has been a guard_nonnull or guard_class or
             # guard_nonnull_class on this value.
             if old_guard_op.getopnum() == rop.GUARD_NONNULL:
@@ -364,6 +371,11 @@
                 op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS,
                             args = [old_guard_op.getarg(0), op.getarg(1)],
                             descr=descr)
+                # Note: we give explicitly a new descr for 'op'; this is why the
+                # old descr must not be ResumeAtPositionDescr (checked above).
+                # Better-safe-than-sorry but it should never occur: we should
+                # not put in short preambles guard_nonnull and guard_class
+                # on the same box.
                 self.optimizer.replace_guard(op, value)
                 # not emitting the guard, so we have to pass None to
                 # make_constant_class, so last_guard_pos is not updated
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -7255,11 +7255,9 @@
         short = """
         [p0]
         p1 = getfield_gc(p0, descr=nextdescr)
-        guard_nonnull(p1) []
-        guard_class(p1, ConstClass(node_vtable)) []
+        guard_nonnull_class(p1, ConstClass(node_vtable)) []
         p2 = getfield_gc(p1, descr=nextdescr)
-        guard_nonnull(p2) []
-        guard_class(p2, ConstClass(node_vtable)) []
+        guard_nonnull_class(p2, ConstClass(node_vtable)) []
         jump(p0)
         """
         self.optimize_loop(ops, expected, expected_short=short)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py
@@ -402,8 +402,7 @@
         guards = value1.make_guards(box)
         expected = """
         [p0]
-        guard_nonnull(p0) []        
-        guard_class(p0, ConstClass(node_vtable)) []
+        guard_nonnull_class(p0, ConstClass(node_vtable)) []
         """
         self.compare(guards, expected, [box])
 


More information about the pypy-commit mailing list