1. Katrina Walser
  2. pypy - RST fix

Commits

Armin Rigo  committed cd409b4

Fix translation. Or at least, test_zrpy_gc.py's test_compile_boehm passes.

  • Participants
  • Parent commits bd64126
  • Branches remove-globals-in-jit

Comments (0)

Files changed (5)

File pypy/jit/backend/llsupport/llmodel.py

View file
             exc = _exception_emulator[1]
             _exception_emulator[0] = 0
             _exception_emulator[1] = 0
+            assert self.propagate_exception_v >= 0
+            faildescr = self.get_fail_descr_from_number(
+                self.propagate_exception_v)
+            faildescr = faildescr.hide(self)
             if not exc:
                 deadframe = self.deadframe_memoryerror
-                assert self.propagate_exception_v >= 0
-                faildescr = self.get_fail_descr_from_number(
-                    self.propagate_exception_v)
                 if not deadframe.jf_descr:
-                    deadframe.jf_descr = faildescr.hide(self)
+                    deadframe.jf_descr = faildescr
                 else:
-                    assert deadframe.jf_descr == faildescr.hide(self)
+                    assert deadframe.jf_descr == faildescr
             else:
                 deadframe = lltype.malloc(jitframe.DEADFRAME, 0)
                 deadframe.jf_guard_exc = rffi.cast(llmemory.GCREF, exc)
-                deadframe.jf_descr = self.get_fail_descr_from_number(
-                    self.propagate_exception_v)
+                deadframe.jf_descr = faildescr
             return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe)
 
         self.pos_exception = pos_exception
         self._propagate_exception = propagate_exception
 
     def _setup_exception_handling_translated(self):
-        xxxxxxxxxxx
 
         def pos_exception():
             addr = llop.get_exception_addr(llmemory.Address)
             addr = llop.get_exc_value_addr(llmemory.Address)
             return heaptracker.adr2int(addr)
 
-        def save_exception():
-            addr = llop.get_exception_addr(llmemory.Address)
-            addr.address[0] = llmemory.NULL
-            addr = llop.get_exc_value_addr(llmemory.Address)
-            exc_value = addr.address[0]
-            addr.address[0] = llmemory.NULL
-            # from now on, the state is again consistent -- no more RPython
-            # exception is set.  The following code produces a write barrier
-            # in the assignment to self.saved_exc_value, as needed.
-            self.saved_exc_value = rffi.cast(llmemory.GCREF, exc_value)
-
-        def save_exception_memoryerr():
-            from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
-            save_exception()
-            if not self.saved_exc_value:
-                exc = MemoryError()
-                exc = cast_instance_to_base_ptr(exc)
-                exc = lltype.cast_opaque_ptr(llmemory.GCREF, exc)
-                self.saved_exc_value = exc
-
         from pypy.rlib import rstack
         STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed],
                                                           lltype.Void))
             slowpathaddr = rffi.cast(lltype.Signed, f)
             return endaddr, lengthaddr, slowpathaddr
 
+        self.deadframe_memoryerror = lltype.malloc(jitframe.DEADFRAME, 0)
+
+        def propagate_exception():
+            addr = llop.get_exception_addr(llmemory.Address)
+            addr.address[0] = llmemory.NULL
+            addr = llop.get_exc_value_addr(llmemory.Address)
+            exc = rffi.cast(llmemory.GCREF, addr.address[0])
+            addr.address[0] = llmemory.NULL
+            assert self.propagate_exception_v >= 0
+            faildescr = self.get_fail_descr_from_number(
+                self.propagate_exception_v)
+            faildescr = faildescr.hide(self)
+            deadframe = lltype.nullptr(jitframe.DEADFRAME)
+            if exc:
+                try:
+                    deadframe = lltype.malloc(jitframe.DEADFRAME, 0)
+                    deadframe.jf_guard_exc = rffi.cast(llmemory.GCREF, exc)
+                    deadframe.jf_descr = faildescr
+                except MemoryError:
+                    deadframe = lltype.nullptr(jitframe.DEADFRAME)
+            if not deadframe:
+                deadframe = self.deadframe_memoryerror
+                if not deadframe.jf_descr:
+                    exc = MemoryError()
+                    exc = cast_instance_to_base_ptr(exc)
+                    exc = lltype.cast_opaque_ptr(llmemory.GCREF, exc)
+                    deadframe.jf_guard_exc = exc
+                    deadframe.jf_descr = faildescr
+                else:
+                    assert deadframe.jf_descr == faildescr
+            return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe)
+
         self.pos_exception = pos_exception
         self.pos_exc_value = pos_exc_value
-        self.save_exception = save_exception
-        self.save_exception_memoryerr = save_exception_memoryerr
         self.insert_stack_check = insert_stack_check
+        self._propagate_exception = propagate_exception
 
     PROPAGATE_EXCEPTION = lltype.Ptr(lltype.FuncType([], llmemory.GCREF))
 

File pypy/jit/backend/x86/assembler.py

View file
         offset = mc.get_relative_pos() - jnz_location
         assert 0 < offset <= 127
         mc.overwrite(jnz_location-1, chr(offset))
-        # call on_leave_jitted_save_exc()
-        addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
+        #
+        # Call the helper, which will return a dead frame object with
+        # the correct exception set, or MemoryError by default
+        addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception())
         mc.CALL(imm(addr))
         #
-        xxxxxxxxxxxxxxxx
-        mc.MOV_ri(eax.value, self.cpu.propagate_exception_v)
-        #
         # footer -- note the ADD, which skips the return address of this
         # function, and will instead return to the caller's caller.  Note
         # also that we completely ignore the saved arguments, because we
             arglocs.append(loc)
         return arglocs[:]
 
-    #@rgc.no_collect XXX
     @staticmethod
+    @rgc.no_collect
     def grab_frame_values(cpu, bytecode, frame_addr, allregisters):
         # no malloc allowed here!! XXX we allocate anyway the deadframe.
         # It will only work on Boehm.
             num += 1
         # allocate the deadframe
         if not deadframe:
+            assert num <= cpu.get_failargs_limit()
             deadframe = lltype.malloc(jitframe.DEADFRAME, num)
         # fill it
         code_inputarg = False
 
     def setup_failure_recovery(self):
 
-        #@rgc.no_collect XXX
+        @rgc.no_collect
         def failure_recovery_func(registers):
             # 'registers' is a pointer to a structure containing the
             # original value of the registers, optionally the original

File pypy/jit/backend/x86/runner.py

View file
     def set_debug(self, flag):
         return self.assembler.set_debug(flag)
 
+    def get_failargs_limit(self):
+        if self.opts is not None:
+            return self.opts.failargs_limit
+        else:
+            return 1000
+
     def setup(self):
         self.assembler = Assembler386(self, self.translate_support_code)
 

File pypy/jit/metainterp/history.py

View file
 class AbstractFailDescr(AbstractDescr):
     index = -1
 
-    def handle_fail(self, metainterp_sd, jitdriver_sd):
+    def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
         raise NotImplementedError
     def compile_and_attach(self, metainterp, new_loop):
         raise NotImplementedError

File pypy/rlib/rerased.py

View file
         _about_ = unerase
 
         def compute_result_annotation(self, s_obj):
-            assert SomeErased().contains(s_obj)
+            # unerase() accepts a GCREF which is normally SomeErased,
+            # tracked directly from a corresponding erase().  For corner
+            # cases, we might get a random GCREF too (only when translated).
+            if isinstance(s_obj, annmodel.SomePtr):
+                assert annmodel.SomePtr(llmemory.GCREF).contains(s_obj)
+            else:
+                assert SomeErased().contains(s_obj)
             return identity.leave_tunnel(self.bookkeeper)
 
         def specialize_call(self, hop):