Author: Jeremy Thurgood <fir...@gmail.com>
Branch: unrecursive-opt
Changeset: r79956:9c9cd68a9013
Date: 2015-10-03 17:38 +0200
http://bitbucket.org/pypy/pypy/changeset/9c9cd68a9013/

Log:    Move intbounds into non-recursive model.

diff --git a/rpython/jit/metainterp/optimizeopt/heap.py 
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -500,6 +500,9 @@
         # default case: produce the operation
         self.make_nonnull(op.getarg(0))
         self.emit_operation(op)
+        self.optimize_GETFIELD_GC_I_callback(op, structinfo, cf)
+
+    def optimize_GETFIELD_GC_I_callback(self, op, structinfo, cf):
         # then remember the result of reading the field
         structinfo.setfield(op.getdescr(), op.getarg(0), op, self, cf)
     optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
@@ -552,6 +555,9 @@
         # default case: produce the operation
         self.make_nonnull(op.getarg(0))
         self.emit_operation(op)
+        self.optimize_GETARRAYITEM_GC_I_callback(op, cf, arrayinfo, indexb)
+
+    def optimize_GETARRAYITEM_GC_I_callback(self, op, cf, arrayinfo, indexb):
         # the remember the result of reading the array item
         if cf is not None:
             arrayinfo.setitem(op.getdescr(), indexb.getint(),
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py 
b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -38,16 +38,27 @@
     return n
 
 
+class IntBoundsCallbackArgs(object):
+    def __init__(self, op, callback_func=None, b1=None, b2=None):
+        self.op = op
+        self.callback_func = callback_func
+        self.b1 = b1
+        self.b2 = b2
+
+    def callback(self):
+        if self.callback_func is not None:
+            self.callback_func(self.op, self.b1, self.b2)
+
+
 class OptIntBounds(Optimization):
     """Keeps track of the bounds placed on integers by guards and remove
        redundant guards"""
 
+    def opt_default(self, op):
+        return IntBoundsCallbackArgs(op)
+
     def propagate_forward(self, op):
-        dispatch_opt(self, op)
-
-    def opt_default(self, op):
-        assert not op.is_ovf()
-        self.emit_operation(op)
+        return dispatch_opt(self, op)
 
     def propagate_bounds_backward(self, box):
         # FIXME: This takes care of the instruction where box is the reuslt
@@ -61,7 +72,9 @@
             dispatch_bounds_ops(self, box)
 
     def _optimize_guard_true_false_value(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, 
self._optimize_guard_true_false_value_callback)
+
+    def _optimize_guard_true_false_value_callback(self, op, bn1, bn2):
         if op.getarg(0).type == 'i':
             self.propagate_bounds_backward(op.getarg(0))
 
@@ -79,8 +92,10 @@
                 self.make_equal_to(op, v1)
             else:
                 self.make_constant_int(op, 0)
-            return
-        self.emit_operation(op)
+            return None
+        return IntBoundsCallbackArgs(op, self.optimize_INT_OR_or_XOR_callback, 
b1, b2)
+
+    def optimize_INT_OR_or_XOR_callback(self, op, b1, b2):
         if b1.known_ge(IntBound(0, 0)) and \
            b2.known_ge(IntBound(0, 0)):
             r = self.getintbound(op)
@@ -93,8 +108,9 @@
     def optimize_INT_AND(self, op):
         b1 = self.getintbound(op.getarg(0))
         b2 = self.getintbound(op.getarg(1))
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_AND_callback, b1, 
b2)
 
+    def optimize_INT_AND_callback(self, op, b1, b2):
         r = self.getintbound(op)
         if b2.is_constant():
             val = b2.lower
@@ -109,7 +125,9 @@
             r.intersect(IntBound(0, next_pow2_m1(lesser)))
 
     def optimize_INT_SUB(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_SUB_callback)
+
+    def optimize_INT_SUB_callback(self, op, bn1, bn2):
         b1 = self.getintbound(op.getarg(0))
         b2 = self.getintbound(op.getarg(1))
         b = b1.sub_bound(b2)
@@ -120,8 +138,7 @@
         arg1 = self.get_box_replacement(op.getarg(0))
         arg2 = self.get_box_replacement(op.getarg(1))
         if self.is_raw_ptr(arg1) or self.is_raw_ptr(arg2):
-            self.emit_operation(op)
-            return
+            return IntBoundsCallbackArgs(op)
         v1 = self.getintbound(arg1)
         v2 = self.getintbound(arg2)
 
@@ -155,7 +172,9 @@
                         arg2 = ConstInt(sum)
                         op = self.replace_op_with(op, rop.INT_ADD, args=[arg1, 
arg2])
 
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_ADD_callback)
+
+    def optimize_INT_ADD_callback(self, op, bn1, bn2):
         b1 = self.getintbound(op.getarg(0))
         b2 = self.getintbound(op.getarg(1))
         r = self.getintbound(op)
@@ -166,7 +185,9 @@
     def optimize_INT_MUL(self, op):
         b1 = self.getintbound(op.getarg(0))
         b2 = self.getintbound(op.getarg(1))
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_MUL_callback, b1, 
b2)
+
+    def optimize_INT_MUL_callback(self, op, b1, b2):
         r = self.getintbound(op)
         b = b1.mul_bound(b2)
         if b.bounded():
@@ -175,7 +196,9 @@
     def optimize_INT_FLOORDIV(self, op):
         b1 = self.getintbound(op.getarg(0))
         b2 = self.getintbound(op.getarg(1))
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_FLOORDIV_callback, 
b1, b2)
+
+    def optimize_INT_FLOORDIV_callback(self, op, b1, b2):
         r = self.getintbound(op)
         r.intersect(b1.div_bound(b2))
 
@@ -192,13 +215,15 @@
                 arg2 = ConstInt(val-1)
                 op = self.replace_op_with(op, rop.INT_AND,
                                           args=[arg1, arg2])
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_MOD_callback, b2, 
known_nonneg)
+
+    def optimize_INT_MOD_callback(self, op, b2, known_nonneg):
         if b2.is_constant():
             val = b2.getint()
             r = self.getintbound(op)
             if val < 0:
                 if val == -sys.maxint-1:
-                    return     # give up
+                    return None     # give up
                 val = -val
             if known_nonneg:
                 r.make_ge(IntBound(0, 0))
@@ -211,7 +236,11 @@
         b1 = self.getintbound(arg0)
         arg1 = self.get_box_replacement(op.getarg(1))
         b2 = self.getintbound(arg1)
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_LSHIFT_callback, 
b1, b2)
+
+    def optimize_INT_LSHIFT_callback(self, op, b1, b2):
+        arg0 = self.get_box_replacement(op.getarg(0))
+        arg1 = self.get_box_replacement(op.getarg(1))
         r = self.getintbound(op)
         b = b1.lshift_bound(b2)
         r.intersect(b)
@@ -230,10 +259,12 @@
         if b.has_lower and b.has_upper and b.lower == b.upper:
             # constant result (likely 0, for rshifts that kill all bits)
             self.make_constant_int(op, b.lower)
-        else:
-            self.emit_operation(op)
-            r = self.getintbound(op)
-            r.intersect(b)
+            return None
+        return IntBoundsCallbackArgs(op, self.optimize_INT_RSHIFT_callback, b)
+
+    def optimize_INT_RSHIFT_callback(self, op, b, bn):
+        r = self.getintbound(op)
+        r.intersect(b)
 
     def optimize_GUARD_NO_OVERFLOW(self, op):
         lastop = self.last_emitted_operation
@@ -259,7 +290,7 @@
                 self.pure_from_args(rop.INT_SUB, [args[0], result], args[1])
             #elif opnum == rop.INT_MUL_OVF:
             #    self.pure(rop.INT_MUL, args[:], result)
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_GUARD_OVERFLOW(self, op):
         # If INT_xxx_OVF was replaced by INT_xxx, *but* we still see
@@ -272,7 +303,7 @@
             raise InvalidLoop('An INT_xxx_OVF was proven not to overflow but' +
                               'guarded with GUARD_OVERFLOW')
 
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op)
 
     def optimize_INT_ADD_OVF(self, op):
         b1 = self.getintbound(op.getarg(0))
@@ -283,7 +314,9 @@
             # by optimize_GUARD_NO_OVERFLOW; if we see instead an
             # optimize_GUARD_OVERFLOW, then InvalidLoop.
             op = self.replace_op_with(op, rop.INT_ADD)
-        self.emit_operation(op) # emit the op
+        return IntBoundsCallbackArgs(op, self.optimize_INT_ADD_OVF_callback, 
resbound)
+
+    def optimize_INT_ADD_OVF_callback(self, op, resbound, bn):
         r = self.getintbound(op)
         r.intersect(resbound)
 
@@ -294,11 +327,13 @@
         b1 = self.getintbound(arg1)
         if arg0.same_box(arg1):
             self.make_constant_int(op, 0)
-            return
+            return None
         resbound = b0.sub_bound(b1)
         if resbound.bounded():
             op = self.replace_op_with(op, rop.INT_SUB)
-        self.emit_operation(op) # emit the op
+        return IntBoundsCallbackArgs(op, self.optimize_INT_SUB_OVF_callback, 
resbound)
+
+    def optimize_INT_SUB_OVF_callback(self, op, resbound, bn):
         r = self.getintbound(op)
         r.intersect(resbound)
 
@@ -308,7 +343,9 @@
         resbound = b1.mul_bound(b2)
         if resbound.bounded():
             op = self.replace_op_with(op, rop.INT_MUL)
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_INT_MUL_OVF_callback, 
resbound)
+
+    def optimize_INT_MUL_OVF_callback(self, op, resbound, bn):
         r = self.getintbound(op)
         r.intersect(resbound)
 
@@ -322,7 +359,7 @@
         elif b1.known_ge(b2) or arg1 is arg2:
             self.make_constant_int(op, 0)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_GT(self, op):
         arg1 = self.get_box_replacement(op.getarg(0))
@@ -334,7 +371,7 @@
         elif b1.known_le(b2) or arg1 is arg2:
             self.make_constant_int(op, 0)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_LE(self, op):
         arg1 = self.get_box_replacement(op.getarg(0))
@@ -346,7 +383,7 @@
         elif b1.known_gt(b2):
             self.make_constant_int(op, 0)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_GE(self, op):
         arg1 = self.get_box_replacement(op.getarg(0))
@@ -358,7 +395,7 @@
         elif b1.known_lt(b2):
             self.make_constant_int(op, 0)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_EQ(self, op):
         arg0 = self.get_box_replacement(op.getarg(0))
@@ -372,7 +409,7 @@
         elif arg0.same_box(arg1):
             self.make_constant_int(op, 1)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_NE(self, op):
         arg0 = self.get_box_replacement(op.getarg(0))
@@ -386,14 +423,14 @@
         elif arg0 is arg1:
             self.make_constant_int(op, 0)
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_FORCE_GE_ZERO(self, op):
         b = self.getintbound(op.getarg(0))
         if b.known_ge(IntBound(0, 0)):
             self.make_equal_to(op, op.getarg(0))
         else:
-            self.emit_operation(op)
+            return IntBoundsCallbackArgs(op)
 
     def optimize_INT_SIGNEXT(self, op):
         b = self.getintbound(op.getarg(0))
@@ -404,29 +441,39 @@
         if bounds.contains_bound(b):
             self.make_equal_to(op, op.getarg(0))
         else:
-            self.emit_operation(op)
-            bres = self.getintbound(op)
-            bres.intersect(bounds)
+            return IntBoundsCallbackArgs(op, 
self.optimize_INT_SIGNEXT_callback, bounds)
+
+    def optimize_INT_SIGNEXT_callback(self, op, bounds, bn):
+        bres = self.getintbound(op)
+        bres.intersect(bounds)
 
     def optimize_ARRAYLEN_GC(self, op):
         array = self.ensure_ptr_info_arg0(op)
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_ARRAYLEN_GC_callback, 
array)
+
+    def optimize_ARRAYLEN_GC_callback(self, op, array, bn):
         self.optimizer.setintbound(op, array.getlenbound(None))
 
     def optimize_STRLEN(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_STRLEN_callback)
+
+    def optimize_STRLEN_callback(self, op, bn1, bn2):
         self.make_nonnull_str(op.getarg(0), vstring.mode_string)
         array = self.getptrinfo(op.getarg(0))
         self.optimizer.setintbound(op, array.getlenbound(vstring.mode_string))
 
     def optimize_UNICODELEN(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_UNICODELEN_callback)
+
+    def optimize_UNICODELEN_callback(self, op, bn1, bn2):
         self.make_nonnull_str(op.getarg(0), vstring.mode_unicode)
         array = self.getptrinfo(op.getarg(0))
         self.optimizer.setintbound(op, array.getlenbound(vstring.mode_unicode))
 
     def optimize_STRGETITEM(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_STRGETITEM_callback)
+
+    def optimize_STRGETITEM_callback(self, op, bn1, bn2):
         v1 = self.getintbound(op)
         v2 = self.getptrinfo(op.getarg(0))
         intbound = self.getintbound(op.getarg(1))
@@ -438,7 +485,9 @@
         v1.make_lt(IntUpperBound(256))
 
     def optimize_GETFIELD_RAW_I(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_GETFIELD_RAW_I_callback)
+
+    def optimize_GETFIELD_RAW_I_callback(self, op, bn1, bn2):
         descr = op.getdescr()
         if descr.is_integer_bounded():
             b1 = self.getintbound(op)
@@ -456,7 +505,9 @@
     optimize_GETINTERIORFIELD_GC_F = optimize_GETFIELD_RAW_I
 
     def optimize_GETARRAYITEM_RAW_I(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, 
self.optimize_GETARRAYITEM_RAW_I_callback)
+
+    def optimize_GETARRAYITEM_RAW_I_callback(self, op, bn1, bn2):
         descr = op.getdescr()
         if descr and descr.is_item_integer_bounded():
             intbound = self.getintbound(op)
@@ -469,7 +520,9 @@
     optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_RAW_I
 
     def optimize_UNICODEGETITEM(self, op):
-        self.emit_operation(op)
+        return IntBoundsCallbackArgs(op, self.optimize_UNICODEGETITEM_callback)
+
+    def optimize_UNICODEGETITEM_callback(self, op, bn1, bn2):
         b1 = self.getintbound(op)
         b1.make_ge(IntLowerBound(0))
         v2 = self.getptrinfo(op.getarg(0))
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
@@ -272,7 +272,7 @@
 
     def set_optimizations(self, optimizations):
         if optimizations:
-            self.first_optimization = optimizations[0]
+            self.first_optimization = optimizations[1]
             for i in range(1, len(optimizations)):
                 optimizations[i - 1].next_optimization = optimizations[i]
             optimizations[-1].next_optimization = self
@@ -521,14 +521,14 @@
             last = len(ops)
         for i in range(last):
             self._really_emitted_operation = None
-            self.first_optimization.propagate_forward(ops[i])
+            self.send_extra_operation(ops[i])
         # accumulate counters
         if flush:
             self.flush()
         if extra_jump:
-            self.first_optimization.propagate_forward(ops[-1])
+            self.send_extra_operation(ops[-1])
         self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
-        
+
         return (BasicLoopInfo(newargs, self.quasi_immutable_deps),
                 self._newoperations)
 
@@ -538,7 +538,12 @@
                 op.set_forwarded(None)
 
     def send_extra_operation(self, op):
-        self.first_optimization.propagate_forward(op)
+        callback_args = self.optimizations[0].propagate_forward(op)
+        if callback_args is None:
+            return
+        self.optimizations[0].last_emitted_operation = callback_args.op
+        self.first_optimization.propagate_forward(callback_args.op)
+        callback_args.callback()
 
     def propagate_forward(self, op):
         dispatch_opt(self, op)
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py 
b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -109,6 +109,9 @@
 
         # otherwise, the operation remains
         self.emit_operation(op)
+        self.optimize_default_callback(op, save, nextop)
+
+    def optimize_default_callback(self, op, save, nextop):
         if op.returns_bool_result():
             self.getintbound(op).make_bool()
         if save:
@@ -159,6 +162,9 @@
         opnum = OpHelpers.call_for_descr(op.getdescr())
         newop = self.optimizer.replace_op_with(op, opnum)
         self.emit_operation(newop)
+        self.optimize_CALL_PURE_I_callback(op)
+
+    def optimize_CALL_PURE_I_callback(self, op):
         self.call_pure_positions.append(
             len(self.optimizer._newoperations) - 1)
 
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
@@ -123,7 +123,10 @@
             self.make_constant_int(op, 0)
         else:
             self.emit_operation(op)
-            self.optimizer.pure_reverse(op)
+            self.optimize_INT_SUB_callback(op)
+
+    def optimize_INT_SUB_callback(self, op):
+        self.optimizer.pure_reverse(op)
 
     def optimize_INT_ADD(self, op):
         if self.is_raw_ptr(op.getarg(0)) or self.is_raw_ptr(op.getarg(1)):
@@ -141,7 +144,10 @@
             self.make_equal_to(op, arg1)
         else:
             self.emit_operation(op)
-            self.optimizer.pure_reverse(op)
+            self.optimize_INT_ADD_callback(op)
+
+    def optimize_INT_ADD_callback(self, op):
+        self.optimizer.pure_reverse(op)
 
     def optimize_INT_MUL(self, op):
         arg1 = self.get_box_replacement(op.getarg(0))
@@ -228,6 +234,9 @@
                     self.emit_operation(newop)
                     return
         self.emit_operation(op)
+        self.optimize_FLOAT_MUL_callback(op)
+
+    def optimize_FLOAT_MUL_callback(self, op):
         self.optimizer.pure_reverse(op)
 
     def optimize_FLOAT_TRUEDIV(self, op):
@@ -253,6 +262,9 @@
 
     def optimize_FLOAT_NEG(self, op):
         self.emit_operation(op)
+        self.optimize_FLOAT_NEG_callback(op)
+
+    def optimize_FLOAT_NEG_callback(self, op):
         self.optimizer.pure_reverse(op)
 
     def optimize_guard(self, op, constbox, emit_operation=True):
@@ -275,12 +287,15 @@
                     raise InvalidLoop('A GUARD_VALUE (%s) '
                                       'was proven to always fail' % r)
                 return
-                    
+
         if emit_operation:
             self.emit_operation(op)
+            self.optimize_guard_callback(op, box, constbox)
+        else:
+            self.optimize_guard_callback(op, box, constbox)
+
+    def optimize_guard_callback(self, op, box, constbox):
         self.make_constant(box, constbox)
-        #if self.optimizer.optheap:  XXX
-        #    self.optimizer.optheap.value_updated(value, 
self.getvalue(constbox))
 
     def optimize_GUARD_ISNULL(self, op):
         info = self.getptrinfo(op.getarg(0))
@@ -292,6 +307,9 @@
                 raise InvalidLoop('A GUARD_ISNULL (%s) was proven to always '
                                   'fail' % r)
         self.emit_operation(op)
+        self.optimize_GUARD_ISNULL_callback(op)
+
+    def optimize_GUARD_ISNULL_callback(self, op):
         self.make_constant(op.getarg(0), self.optimizer.cpu.ts.CONST_NULL)
 
     def optimize_GUARD_IS_OBJECT(self, op):
@@ -368,6 +386,9 @@
                 raise InvalidLoop('A GUARD_NONNULL (%s) was proven to always '
                                   'fail' % r)
         self.emit_operation(op)
+        self.optimize_GUARD_NONNULL_callback(op)
+
+    def optimize_GUARD_NONNULL_callback(self, op):
         self.make_nonnull(op.getarg(0))
         self.getptrinfo(op.getarg(0)).mark_last_guard(self.optimizer)
 
@@ -463,9 +484,15 @@
                 # on the same box.
                 self.optimizer.replace_guard(op, info)
                 self.emit_operation(op)
-                self.make_constant_class(op.getarg(0), expectedclassbox, False)
+                self.optimize_GUARD_CLASS_callback_1(op, expectedclassbox)
                 return
         self.emit_operation(op)
+        self.optimize_GUARD_CLASS_callback_2(op, expectedclassbox)
+
+    def optimize_GUARD_CLASS_callback_1(self, op, expectedclassbox):
+        self.make_constant_class(op.getarg(0), expectedclassbox, False)
+
+    def optimize_GUARD_CLASS_callback_2(self, op, expectedclassbox):
         self.make_constant_class(op.getarg(0), expectedclassbox)
 
     def optimize_GUARD_NONNULL_CLASS(self, op):
@@ -495,6 +522,9 @@
         newop = self.replace_op_with(op,
                                      OpHelpers.call_for_descr(op.getdescr()))
         self.emit_operation(newop)
+        self.optimize_CALL_LOOPINVARIANT_I_callback(newop, op, key)
+
+    def optimize_CALL_LOOPINVARIANT_I_callback(self, newop, op, key):
         self.loop_invariant_producer[key] = self.optimizer.getlastop()
         self.loop_invariant_results[key] = op
     optimize_CALL_LOOPINVARIANT_R = optimize_CALL_LOOPINVARIANT_I
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py 
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -69,13 +69,16 @@
         if self._last_guard_not_forced_2 is not None:
             guard_op = self._last_guard_not_forced_2
             self.emit_operation(op)
-            guard_op = self.optimizer.store_final_boxes_in_guard(guard_op, [])
-            i = len(self.optimizer._newoperations) - 1
-            assert i >= 0
-            self.optimizer._newoperations.insert(i, guard_op)
+            self.optimize_FINISH_callback(op, guard_op)
         else:
             self.emit_operation(op)
 
+    def optimize_FINISH_callback(self, op, guard_op):
+        guard_op = self.optimizer.store_final_boxes_in_guard(guard_op, [])
+        i = len(self.optimizer._newoperations) - 1
+        assert i >= 0
+        self.optimizer._newoperations.insert(i, guard_op)
+
     def optimize_CALL_MAY_FORCE_I(self, op):
         effectinfo = op.getdescr().get_extra_info()
         oopspecindex = effectinfo.oopspecindex
@@ -101,8 +104,6 @@
         vrefinfo = self.optimizer.metainterp_sd.virtualref_info
         c_cls = vrefinfo.jit_virtual_ref_const_class
         vref_descr = vrefinfo.descr
-        descr_virtual_token = vrefinfo.descr_virtual_token
-        descr_forced = vrefinfo.descr_forced
         #
         # Replace the VIRTUAL_REF operation with a virtual structure of type
         # 'jit_virtual_ref'.  The jit_virtual_ref structure may be forced soon,
@@ -113,6 +114,12 @@
         newop.set_forwarded(vrefvalue)
         token = ResOperation(rop.FORCE_TOKEN, [])
         self.emit_operation(token)
+        self.optimize_VIRTUAL_REF_callback(op, vrefvalue, newop, token)
+
+    def optimize_VIRTUAL_REF_callback(self, op, vrefvalue, newop, token):
+        vrefinfo = self.optimizer.metainterp_sd.virtualref_info
+        descr_virtual_token = vrefinfo.descr_virtual_token
+        descr_forced = vrefinfo.descr_forced
         vrefvalue.setfield(descr_virtual_token, newop, token)
         vrefvalue.setfield(descr_forced, newop,
                            self.optimizer.cpu.ts.CONST_NULLREF)
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py 
b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -453,7 +453,10 @@
         else:
             self.make_nonnull_str(op, mode)
             self.emit_operation(op)
-            self.pure_from_args(mode.STRLEN, [op], op.getarg(0))
+            self._optimize_NEWSTR_callback(op, mode)
+
+    def _optimize_NEWSTR_callback(self, op, mode):
+        self.pure_from_args(mode.STRLEN, [op], op.getarg(0))
 
     def optimize_STRSETITEM(self, op):
         opinfo = self.getptrinfo(op.getarg(0))
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to