[pypy-commit] pypy default: Backout PR #490 (ab8a0b092d2d + follow-up bd7b1902c4df).

arigo pypy.commits at gmail.com
Mon May 22 12:32:43 EDT 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r91373:1a06512dea4b
Date: 2017-05-22 18:21 +0200
http://bitbucket.org/pypy/pypy/changeset/1a06512dea4b/

Log:	Backout PR #490 (ab8a0b092d2d + follow-up bd7b1902c4df).

	See https://bitbucket.org/pypy/pypy/issues/2534. It gives a smallish
	PyPy example which crashes because of this PR #490. For more infos
	see https://bitbucket.org/pypy/pypy/pull-requests/490/.

diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -110,7 +110,7 @@
     """
     log_noopt = False
 
-    def __init__(self, trace, celltoken, state, runtime_boxes,
+    def __init__(self, trace, celltoken, state,
                  call_pure_results=None, enable_opts=None,
                  inline_short_preamble=True):
         self.trace = trace
@@ -119,8 +119,6 @@
         self.state = state
         self.call_pure_results = call_pure_results
         self.inline_short_preamble = inline_short_preamble
-        assert runtime_boxes is not None
-        self.runtime_boxes = runtime_boxes
 
     def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
         from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
@@ -128,11 +126,7 @@
         assert unroll # we should not be here if it's disabled
         opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
         return opt.optimize_peeled_loop(self.trace, self.celltoken, self.state,
-            self.runtime_boxes, self.call_pure_results, self.inline_short_preamble)
-
-    def forget_optimization_info(self):
-        self.state.forget_optimization_info()
-        CompileData.forget_optimization_info(self)
+            self.call_pure_results, self.inline_short_preamble)
 
 def show_procedures(metainterp_sd, procedure=None, error=None):
     # debugging
@@ -298,7 +292,7 @@
     start_descr = TargetToken(jitcell_token,
                               original_jitcell_token=jitcell_token)
     jitcell_token.target_tokens = [start_descr]
-    loop_data = UnrolledLoopData(trace, jitcell_token, start_state, jumpargs,
+    loop_data = UnrolledLoopData(trace, jitcell_token, start_state,
                                  call_pure_results=call_pure_results,
                                  enable_opts=enable_opts)
     try:
@@ -368,7 +362,7 @@
     history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token)
     enable_opts = jitdriver_sd.warmstate.enable_opts
     call_pure_results = metainterp.call_pure_results
-    loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, jumpargs,
+    loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state,
                                  call_pure_results=call_pure_results,
                                  enable_opts=enable_opts)
     try:
@@ -380,7 +374,6 @@
         history.cut(cut)
         history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token)
         loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state,
-                                     jumpargs,
                                      call_pure_results=call_pure_results,
                                      enable_opts=enable_opts,
                                      inline_short_preamble=False)
@@ -525,7 +518,7 @@
     for item in lst:
         item.set_forwarded(None)
         # XXX we should really do it, but we need to remember the values
-        #     somehow for ContinueRunningNormally
+        #     somehoe for ContinueRunningNormally
         if reset_values:
             item.reset_value()
 
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
@@ -12,7 +12,7 @@
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.resoperation import rop, ResOperation, OpHelpers,\
      AbstractResOp, GuardResOp
-from rpython.rlib.objectmodel import we_are_translated, we_are_debug
+from rpython.rlib.objectmodel import we_are_translated
 from rpython.jit.metainterp.optimizeopt import info
         
 
@@ -173,7 +173,7 @@
 
     def _getfield(self, opinfo, descr, optheap, true_force=True):
         res = opinfo.getfield(descr, optheap)
-        if we_are_debug() and res:
+        if not we_are_translated() and res:
             if isinstance(opinfo, info.AbstractStructPtrInfo):
                 assert opinfo in self.cached_infos
         if isinstance(res, PreambleOp):
@@ -203,7 +203,7 @@
 
     def _getfield(self, opinfo, descr, optheap, true_force=True):
         res = opinfo.getitem(descr, self.index, optheap)
-        if we_are_debug() and res:
+        if not we_are_translated() and res:
             if isinstance(opinfo, info.ArrayPtrInfo):
                 assert opinfo in self.cached_infos
         if (isinstance(res, PreambleOp) and
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
@@ -24,20 +24,9 @@
 llhelper.CONST_NULLREF = llhelper.CONST_NULL
 REMOVED = AbstractResOp()
 
-def check_no_forwarding(lsts):
-    for lst in lsts:
-        for op in lst:
-            assert op.get_forwarded() is None
-
 class LoopInfo(object):
     label_op = None
 
-    def _check_no_forwarding(self):
-        pass
-
-    def forget_optimization_info(self):
-        pass
-
 class BasicLoopInfo(LoopInfo):
     def __init__(self, inputargs, quasi_immutable_deps, jump_op):
         self.inputargs = inputargs
@@ -567,8 +556,7 @@
         return (BasicLoopInfo(trace.inputargs, self.quasi_immutable_deps, last_op),
                 self._newoperations)
 
-    @staticmethod
-    def _clean_optimization_info(lst):
+    def _clean_optimization_info(self, lst):
         for op in lst:
             if op.get_forwarded() is not None:
                 op.set_forwarded(None)
diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
--- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py
+++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
@@ -5,7 +5,6 @@
      rop, AbstractResOp, AbstractInputArg
 from rpython.jit.metainterp.history import Const, make_hashable_int,\
      TreeLoop
-from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.optimizeopt import info
 
 class PreambleOp(AbstractResOp):
@@ -19,7 +18,7 @@
     See force_op_from_preamble for details how the extra things are put.
     """
     op = None
-
+    
     def __init__(self, op, preamble_op, invented_name):
         self.op = op
         self.preamble_op = preamble_op
@@ -52,13 +51,7 @@
 class AbstractShortOp(object):
     """ An operation that is potentially produced by the short preamble
     """
-    res = None
-
-    def _check_no_forwarding(self):
-        assert self.res.get_forwarded() is None
-
-    def forget_optimization_info(self):
-        self.res.clear_forwarded()
+    pass
 
 class HeapOp(AbstractShortOp):
     def __init__(self, res, getfield_op):
@@ -108,14 +101,6 @@
                                        descr=sop.getdescr())
         return ProducedShortOp(self, preamble_op)
 
-    def _check_no_forwarding(self):
-        AbstractShortOp._check_no_forwarding(self)
-        assert self.getfield_op.get_forwarded() is None
-
-    def forget_optimization_info(self):
-        AbstractShortOp.forget_optimization_info(self)
-        self.getfield_op.clear_forwarded()
-
     def __repr__(self):
         return "HeapOp(%r)" % (self.res,)
 
@@ -208,16 +193,6 @@
                 l.append(pop)
         return l
 
-    def _check_no_forwarding(self):
-        AbstractShortOp._check_no_forwarding(self)
-        self.one._check_no_forwarding()
-        self.two._check_no_forwarding()
-
-    def forget_optimization_info(self):
-        AbstractShortOp.forget_optimization_info(self)
-        self.one.forget_optimization_info()
-        self.two.forget_optimization_info()
-
     def repr(self, memo):
         return "CompoundOp(%s, %s, %s)" % (self.res.repr(memo),
                                            self.one.repr(memo),
@@ -228,7 +203,7 @@
 
 class ProducedShortOp(AbstractProducedShortOp):
     invented_name = False
-
+    
     def __init__(self, short_op, preamble_op):
         self.short_op = short_op
         self.preamble_op = preamble_op
@@ -240,14 +215,6 @@
     def repr(self, memo):
         return self.short_op.repr(memo)
 
-    def _check_no_forwarding(self):
-        self.short_op._check_no_forwarding()
-        assert self.preamble_op.get_forwarded() is None
-
-    def forget_optimization_info(self):
-        self.short_op.forget_optimization_info()
-        self.preamble_op.clear_forwarded()
-
     def __repr__(self):
         return "%r -> %r" % (self.short_op, self.preamble_op)
 
@@ -268,14 +235,6 @@
     def repr(self, memo):
         return "INP(%s)" % (self.res.repr(memo),)
 
-    def _check_no_forwarding(self):
-        AbstractShortOp._check_no_forwarding(self)
-        assert self.preamble_op.get_forwarded() is None
-
-    def forget_optimization_info(self):
-        AbstractShortOp.forget_optimization_info(self)
-        self.preamble_op.clear_forwarded()
-
     def __repr__(self):
         return "INP(%r -> %r)" % (self.res, self.preamble_op)
 
@@ -495,23 +454,16 @@
         self.sb = sb
         self.extra_same_as = self.sb.extra_same_as
         self.target_token = target_token
-        self.build_inplace = False
 
     def setup(self, jump_args, short, label_args):
         self.jump_args = jump_args
         self.short = short
         self.label_args = label_args
-        self.build_inplace = True
 
     def add_preamble_op(self, preamble_op):
         """ Notice that we're actually using the preamble_op, add it to
         label and jump
         """
-        # Could this be considered a speculative error?
-        # This check should only fail when trying to jump to an existing trace
-        # by forcing portions of the virtualstate.
-        if not self.build_inplace:
-            raise InvalidLoop("Forcing boxes would modify an existing short preamble")
         op = preamble_op.op.get_box_replacement()
         if preamble_op.invented_name:
             self.extra_same_as.append(op)
@@ -519,8 +471,6 @@
         self.jump_args.append(preamble_op.preamble_op)
 
     def use_box(self, box, preamble_op, optimizer=None):
-        if not self.build_inplace:
-            raise InvalidLoop("Forcing boxes would modify an existing short preamble")
         jump_op = self.short.pop()
         AbstractShortPreambleBuilder.use_box(self, box, preamble_op, optimizer)
         self.short.append(jump_op)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -577,7 +577,6 @@
         #
         compile_data.enable_opts = self.enable_opts
         state = optimize_trace(metainterp_sd, None, compile_data)
-        state[0]._check_no_forwarding()
         return state
 
     def _convert_call_pure_results(self, d):
@@ -626,7 +625,7 @@
         start_state, preamble_ops = self._do_optimize_loop(preamble_data)
         preamble_data.forget_optimization_info()
         loop_data = compile.UnrolledLoopData(preamble_data.trace,
-            celltoken, start_state, runtime_boxes, call_pure_results)
+            celltoken, start_state, call_pure_results)
         loop_info, ops = self._do_optimize_loop(loop_data)
         preamble = TreeLoop('preamble')
         preamble.inputargs = start_state.renamed_inputargs
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp.optimizeopt import info, intutils
 from rpython.jit.metainterp.optimize import InvalidLoop, SpeculativeError
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer,\
-     Optimization, LoopInfo, MININT, MAXINT, BasicLoopInfo, check_no_forwarding
+     Optimization, LoopInfo, MININT, MAXINT, BasicLoopInfo
 from rpython.jit.metainterp.optimizeopt.vstring import StrPtrInfo
 from rpython.jit.metainterp.optimizeopt.virtualstate import (
     VirtualStateConstructor, VirtualStatesCantMatch)
@@ -35,7 +35,7 @@
 
     def setinfo_from_preamble_list(self, lst, infos):
         for item in lst:
-            if item is None or isinstance(item, Const):
+            if item is None:
                 continue
             i = infos.get(item, None)
             if i is not None:
@@ -99,6 +99,7 @@
         elif isinstance(preamble_info, info.FloatConstInfo):
             op.set_forwarded(preamble_info._const)
 
+
 class UnrollOptimizer(Optimization):
     """Unroll the loop into two iterations. The first one will
     become the preamble or entry bridge (don't think there is a
@@ -116,22 +117,26 @@
         return modifier.get_virtual_state(args)
 
     def _check_no_forwarding(self, lsts, check_newops=True):
-        check_no_forwarding(lsts)
+        for lst in lsts:
+            for op in lst:
+                assert op.get_forwarded() is None
         if check_newops:
             assert not self.optimizer._newoperations
 
+
     def optimize_preamble(self, trace, runtime_boxes, call_pure_results, memo):
         info, newops = self.optimizer.propagate_all_forward(
             trace.get_iter(), call_pure_results, flush=False)
         exported_state = self.export_state(info.jump_op.getarglist(),
-                                           info.inputargs, memo)
+                                           info.inputargs,
+                                           runtime_boxes, memo)
         exported_state.quasi_immutable_deps = info.quasi_immutable_deps
         # we need to absolutely make sure that we've cleaned up all
         # the optimization info
         self.optimizer._clean_optimization_info(self.optimizer._newoperations)
         return exported_state, self.optimizer._newoperations
 
-    def optimize_peeled_loop(self, trace, celltoken, state, runtime_boxes,
+    def optimize_peeled_loop(self, trace, celltoken, state,
                              call_pure_results, inline_short_preamble=True):
         trace = trace.get_iter()
         try:
@@ -183,7 +188,7 @@
 
         try:
             new_virtual_state = self.jump_to_existing_trace(
-                    end_jump, label_op, runtime_boxes, force_boxes=False)
+                    end_jump, label_op, state.runtime_boxes, force_boxes=False)
         except InvalidLoop:
             # inlining short preamble failed, jump to preamble
             self.jump_to_preamble(celltoken, end_jump, info)
@@ -196,7 +201,7 @@
             # to the preamble.
             try:
                 new_virtual_state = self.jump_to_existing_trace(
-                        end_jump, label_op, runtime_boxes, force_boxes=True)
+                        end_jump, label_op, state.runtime_boxes, force_boxes=True)
             except InvalidLoop:
                 pass
 
@@ -279,7 +284,8 @@
             debug_print("Retrace count reached, jumping to preamble")
             return self.jump_to_preamble(cell_token, jump_op, info)
         exported_state = self.export_state(info.jump_op.getarglist(),
-                                           info.inputargs, box_names_memo)
+                                           info.inputargs, runtime_boxes,
+                                           box_names_memo)
         exported_state.quasi_immutable_deps = self.optimizer.quasi_immutable_deps
         self.optimizer._clean_optimization_info(self.optimizer._newoperations)
         return exported_state, self.optimizer._newoperations
@@ -443,7 +449,8 @@
                 continue
             self._expand_info(item, infos)
 
-    def export_state(self, original_label_args, renamed_inputargs, memo):
+    def export_state(self, original_label_args, renamed_inputargs,
+                     runtime_boxes, memo):
         end_args = [self.optimizer.force_box_for_end_of_preamble(a)
                     for a in original_label_args]
         self.optimizer.flush()
@@ -464,17 +471,16 @@
             op = produced_op.short_op.res
             if not isinstance(op, Const):
                 self._expand_info(op, infos)
+        self.optimizer._clean_optimization_info(end_args)
         return ExportedState(label_args, end_args, virtual_state, infos,
                              short_boxes, renamed_inputargs,
-                             short_inputargs, memo)
+                             short_inputargs, runtime_boxes, memo)
 
     def import_state(self, targetargs, exported_state):
         # the mapping between input args (from old label) and what we need
         # to actually emit. Update the info
         assert (len(exported_state.next_iteration_args) ==
                 len(targetargs))
-        self._check_no_forwarding([targetargs])
-        exported_state._check_no_forwarding()
         for i, target in enumerate(exported_state.next_iteration_args):
             source = targetargs[i]
             assert source is not target
@@ -530,11 +536,13 @@
     * renamed_inputargs - the start label arguments in optimized version
     * short_inputargs - the renamed inputargs for short preamble
     * quasi_immutable_deps - for tracking quasi immutables
+    * runtime_boxes - runtime values for boxes, necessary when generating
+                      guards to jump to
     """
 
     def __init__(self, end_args, next_iteration_args, virtual_state,
                  exported_infos, short_boxes, renamed_inputargs,
-                 short_inputargs, memo):
+                 short_inputargs, runtime_boxes, memo):
         self.end_args = end_args
         self.next_iteration_args = next_iteration_args
         self.virtual_state = virtual_state
@@ -542,8 +550,8 @@
         self.short_boxes = short_boxes
         self.renamed_inputargs = renamed_inputargs
         self.short_inputargs = short_inputargs
+        self.runtime_boxes = runtime_boxes
         self.dump(memo)
-        self.forget_optimization_info()
 
     def dump(self, memo):
         if have_debug_prints():
@@ -553,35 +561,5 @@
                 debug_print("  " + box.repr(memo))
             debug_stop("jit-log-exported-state")
 
-    def _check_no_forwarding(self):
-        """ Ensures that no optimization state is attached to relevant operations
-        before importing anything. """
-        # Some of these may be redunant
-        check_no_forwarding([
-            self.end_args,
-            self.next_iteration_args,
-            self.renamed_inputargs,
-            self.short_inputargs,
-            self.exported_infos.keys()])
-        for box in self.short_boxes:
-            box._check_no_forwarding()
-
-    def forget_optimization_info(self):
-        """ Clean up optimization info on all operations stored in the ExportedState.
-
-        This function needs to be called when exporting the optimizer state to
-        prevent leaking of optimization information between invocations of the
-        optimizer.
-
-        That includes cleaning up in the event that optimize_peeled_loop() fails
-        with an InvalidLoop exception, as optimize_peeled_loop() mutates the
-        contents of ExportedState.
-        """
-        Optimizer._clean_optimization_info(self.renamed_inputargs)
-        for box in self.exported_infos.iterkeys():
-            box.clear_forwarded()
-        for box in self.short_boxes:
-            box.forget_optimization_info()
-
     def final(self):
         return False
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -2024,8 +2024,6 @@
         self.aborted_tracing_greenkey = None
 
     def retrace_needed(self, trace, exported_state):
-        if not we_are_translated():
-            exported_state._check_no_forwarding()
         self.partial_trace = trace
         self.retracing_from = self.potential_retrace_position
         self.exported_state = exported_state
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -52,10 +52,6 @@
         llop.debug_print(lltype.Void, "setting forwarded on:", self.__class__.__name__)
         raise SettingForwardedOnAbstractValue()
 
-    def clear_forwarded(self):
-        if self.get_forwarded() is not None:
-            self.set_forwarded(None)
-
     @specialize.arg(1)
     def get_box_replacement(op, not_const=False):
         # Read the chain "op, op._forwarded, op._forwarded._forwarded..."
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -295,15 +295,10 @@
 
 malloc_zero_filled = CDefinedIntSymbolic('MALLOC_ZERO_FILLED', default=0)
 _translated_to_c = CDefinedIntSymbolic('1 /*_translated_to_c*/', default=0)
-_rpy_assert_value = CDefinedIntSymbolic('RPY_ASSERT_VALUE', default=1)
 
 def we_are_translated_to_c():
     return we_are_translated() and _translated_to_c
 
-def we_are_debug():
-    """ Returns True when not translated or translated with debugging enabled. """
-    return not we_are_translated() or (_translated_to_c and _rpy_assert_value)
-
 # ____________________________________________________________
 
 def instantiate(cls, nonmovable=False):
diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -31,10 +31,8 @@
 RPY_EXTERN
 void RPyAssertFailed(const char* filename, long lineno,
                      const char* function, const char *msg);
-#  define RPY_ASSERT_VALUE 1
 #else
 #  define RPyAssert(x, msg)   /* nothing */
-#  define RPY_ASSERT_VALUE 0
 #endif
 
 RPY_EXTERN


More information about the pypy-commit mailing list