[pypy-commit] pypy default: Tentative fix for a bug that shows up rarely on the full pypy:

arigo noreply at buildbot.pypy.org
Mon Oct 5 10:31:55 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r79986:8cc8067ed404
Date: 2015-10-05 09:12 +0200
http://bitbucket.org/pypy/pypy/changeset/8cc8067ed404/

Log:	Tentative fix for a bug that shows up rarely on the full pypy: the
	likely cause is that short-preamble operations are supposed to never
	be forwarded, but they temporarily are. The problem is that the
	send_extra_operation() in the middle of this piece of code can
	invoke arbitrary parts of the optimizer.

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
@@ -320,6 +320,14 @@
             return None # explicit because the return can be non-None
         return virtual_state
 
+    def _map_args(self, mapping, arglist):
+        result = []
+        for box in arglist:
+            if not isinstance(box, Const):
+                box = mapping[box]
+            result.append(box)
+        return result
+
     def inline_short_preamble(self, jump_args, args_no_virtuals, short,
                               patchguardop, target_token, label_op):
         short_inputargs = short[0].getarglist()
@@ -331,33 +339,39 @@
             # THIS WILL MODIFY ALL THE LISTS PROVIDED, POTENTIALLY
             self.short_preamble_producer.setup(short_inputargs, short_jump_args,
                                                short, label_op.getarglist())
-        try:
+        if 1:     # (keep indentation)
             self._check_no_forwarding([short_inputargs, short], False)
             assert len(short_inputargs) == len(jump_args)
+            # We need to make a list of fresh new operations corresponding
+            # to the short preamble operations.  We could temporarily forward
+            # the short operations to the fresh ones, but there are obscure
+            # issues: send_extra_operation() below might occasionally invoke
+            # use_box(), which assumes the short operations are not forwarded.
+            # So we avoid such temporary forwarding and just use a dict here.
+            mapping = {}
             for i in range(len(jump_args)):
-                short_inputargs[i].set_forwarded(None)
-                self.make_equal_to(short_inputargs[i], jump_args[i])
+                mapping[short_inputargs[i]] = jump_args[i]
             i = 1
             while i < len(short) - 1:
-                op = short[i]
-                if op.is_guard():
-                    op = self.replace_op_with(op, op.getopnum(),
+                sop = short[i]
+                arglist = self._map_args(mapping, sop.getarglist())
+                if sop.is_guard():
+                    op = sop.copy_and_change(sop.getopnum(), arglist,
                                     descr=compile.ResumeAtPositionDescr())
                     assert isinstance(op, GuardResOp)
                     op.rd_snapshot = patchguardop.rd_snapshot
                     op.rd_frame_info_list = patchguardop.rd_frame_info_list
+                else:
+                    op = sop.copy_and_change(sop.getopnum(), arglist)
+                mapping[sop] = op
                 i += 1
                 self.optimizer.send_extra_operation(op)
             # force all of them except the virtuals
             for arg in args_no_virtuals + short_jump_args:
                 self.optimizer.force_box(self.get_box_replacement(arg))
             self.optimizer.flush()
-            return [self.get_box_replacement(box) for box in short_jump_args]
-        finally:
-            for op in short_inputargs:
-                op.set_forwarded(None)
-            for op in short:
-                op.set_forwarded(None)
+            return [self.get_box_replacement(box)
+                    for box in self._map_args(mapping, short_jump_args)]
 
     def _expand_info(self, arg, infos):
         if isinstance(arg, AbstractResOp) and arg.is_same_as():


More information about the pypy-commit mailing list