Commits

Hakan Ardo committed b4c589b

Proper handling of resuming from a GUARD_NO_OVERFLOW inlined from the short preamble. This fix should probably go into trunk aswell.

Comments (0)

Files changed (4)

pypy/jit/metainterp/blackhole.py

             assert kind == 'v'
         return lltype.nullptr(rclass.OBJECTPTR.TO)
 
-    def _prepare_resume_from_failure(self, opnum, dont_change_position=False):
+    def _prepare_resume_from_failure(self, opnum, resume_at_position=False):
         from pypy.jit.metainterp.resoperation import rop
         #
         if opnum == rop.GUARD_TRUE:
             # Produced directly by some goto_if_not_xxx() opcode that did not
             # jump, but which must now jump.  The pc is just after the opcode.
-            if not dont_change_position:
+            if not resume_at_position:
                 self.position = self.jitcode.follow_jump(self.position)
         #
         elif opnum == rop.GUARD_FALSE:
         elif opnum == rop.GUARD_NO_OVERFLOW:
             # Produced by int_xxx_ovf().  The pc is just after the opcode.
             # We get here because it did not used to overflow, but now it does.
-            return get_llexception(self.cpu, OverflowError())
+            if not resume_at_position:
+                return get_llexception(self.cpu, OverflowError())
         #
         elif opnum == rop.GUARD_OVERFLOW:
             # Produced by int_xxx_ovf().  The pc is just after the opcode.
         resumedescr,
         all_virtuals)
     if isinstance(resumedescr, ResumeAtPositionDescr):
-        dont_change_position = True
+        resume_at_position = True
     else:
-        dont_change_position = False
+        resume_at_position = False
 
     current_exc = blackholeinterp._prepare_resume_from_failure(
-        resumedescr.guard_opnum, dont_change_position)
+        resumedescr.guard_opnum, resume_at_position)
         
     try:
         _run_forever(blackholeinterp, current_exc)

pypy/jit/metainterp/compile.py

         if self.must_compile(metainterp_sd, jitdriver_sd):
             return self._trace_and_compile_from_bridge(metainterp_sd,
                                                        jitdriver_sd)
-        else:
+        else:            
             from pypy.jit.metainterp.blackhole import resume_in_blackhole
             resume_in_blackhole(metainterp_sd, jitdriver_sd, self)
             assert 0, "unreachable"

pypy/jit/metainterp/pyjitpl.py

         self.seen_loop_header_for_jdindex = -1
         if isinstance(key, compile.ResumeAtPositionDescr):
             self.seen_loop_header_for_jdindex = self.jitdriver_sd.index
-            dont_change_position = True
+            resume_at_position = True
         else:
-            dont_change_position = False
+            resume_at_position = False
         try:
-            self.prepare_resume_from_failure(key.guard_opnum, dont_change_position)
+            self.prepare_resume_from_failure(key.guard_opnum,
+                                             resume_at_position)
             if self.resumekey_original_loop_token is None:   # very rare case
                 raise SwitchToBlackhole(ABORT_BRIDGE)
             self.interpret()
         history.set_future_values(self.cpu, residual_args)
         return loop_token
 
-    def prepare_resume_from_failure(self, opnum, dont_change_position=False):
+    def prepare_resume_from_failure(self, opnum, resume_at_position=False):
         frame = self.framestack[-1]
         if opnum == rop.GUARD_TRUE:     # a goto_if_not that jumps only now
-            if not dont_change_position:
+            if not resume_at_position:
                 frame.pc = frame.jitcode.follow_jump(frame.pc)
         elif opnum == rop.GUARD_FALSE:     # a goto_if_not that stops jumping
             pass
               opnum == rop.GUARD_NONNULL_CLASS):
             pass        # the pc is already set to the *start* of the opcode
         elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
+            if resume_at_position:
+                assert False, "FIXME: How do we handle exceptions here?"
             exception = self.cpu.grab_exc_value()
             if exception:
                 self.execute_ll_raised(lltype.cast_opaque_ptr(rclass.OBJECTPTR,
             except ChangeFrame:
                 pass
         elif opnum == rop.GUARD_NO_OVERFLOW:   # an overflow now detected
-            self.execute_raised(OverflowError(), constant=True)
-            try:
-                self.finishframe_exception()
-            except ChangeFrame:
-                pass
+            if resume_at_position:
+                self.clear_exception()
+            else:
+                self.execute_raised(OverflowError(), constant=True)
+                try:
+                    self.finishframe_exception()
+                except ChangeFrame:
+                    pass
         elif opnum == rop.GUARD_OVERFLOW:      # no longer overflowing
             self.clear_exception()
         else:

pypy/jit/metainterp/test/test_basic.py

                     res += ovfcheck(x1 * x1)
                 except OverflowError:
                     res += 1
-                #if y<n and (y>>2)&1==0:
                 y -= 1
-                if (y>>2)&1==0:
+                if y&4 == 0:
                     x1, x2 = x2, x1
             return res
         res = self.meta_interp(f, [6, sys.maxint, 32, 48])