1. Jeff Terrace
  2. pypy

Commits

Armin Rigo  committed b9daf08

Fixes.

  • Participants
  • Parent commits dbe437d
  • Branches jit-simplify-backendintf

Comments (0)

Files changed (4)

File pypy/jit/backend/test/runner_test.py

View file
  • Ignore whitespace
         self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1)
 
         looptoken2 = JitCellToken()
-        inputargs = []
+        inputargs = [BoxInt()]
         operations = [
             ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1),
             ]
         self.cpu.compile_loop(inputargs, operations, looptoken2)
 
-        fail = self.cpu.execute_token(looptoken2)
+        fail = self.cpu.execute_token(looptoken2, -9)
         assert fail.identifier == 42
 
 

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

View file
  • Ignore whitespace
         '''adds the following attributes to looptoken:
                _x86_function_addr   (address of the generated func, as an int)
                _x86_loop_code       (debug: addr of the start of the ResOps)
-               _x86_debug_nbargs    (debug: total # of args)
                _x86_debug_checksum
         '''
         # XXX this function is too longish and contains some code
         #
         self._call_header_with_stack_check()
         stackadjustpos = self._patchable_stackadjust()
+        clt._debug_nbargs = len(inputargs)
         operations = regalloc.prepare_loop(inputargs, operations,
                                            looptoken, clt.allgcrefs)
         looppos = self.mc.get_relative_pos()
         looptoken._x86_loop_code = looppos
-        looptoken._x86_debug_nbargs = len(inputargs)
         clt.frame_depth = -1     # temporarily
         clt.param_depth = -1     # temporarily
         frame_depth, param_depth = self._assemble(regalloc, operations)
 
     def redirect_call_assembler(self, oldlooptoken, newlooptoken):
         # some minimal sanity checking
-        assert oldlooptoken._x86_debug_nbargs == newlooptoken._x86_debug_nbargs
+        old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs
+        new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs
+        assert old_nbargs == new_nbargs
         # we overwrite the instructions at the old _x86_direct_bootstrap_code
         # to start with a JMP to the new _x86_direct_bootstrap_code.
         # Ideally we should rather patch all existing CALLs, but well.
         target = newlooptoken._x86_function_addr
         mc = codebuf.MachineCodeBlockWrapper()
         mc.JMP(imm(target))
-        assert mc.get_relative_pos() <= 13  #keep in sync with consider_label()
+        assert mc.get_relative_pos() <= 13  # keep in sync with prepare_loop()
         mc.copy_to_raw_memory(oldadr)
 
     def dump(self, text):
         self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)
         descr = op.getdescr()
         assert isinstance(descr, JitCellToken)
-        assert len(arglocs) - 2 == descr._x86_debug_nbargs
+        assert len(arglocs) - 2 == descr.compiled_loop_token._debug_nbargs
         #
         # Write a call to the target assembler
         self._emit_call(fail_index, imm(descr._x86_function_addr),
                     self.gcrootmap_retaddr_forced = -1
 
     def closing_jump(self, target_token):
+        # The backend's logic assumes that the target code is in a piece of
+        # assembler that was also called with the same number of arguments,
+        # so that the locations [ebp+8..] of the input arguments are valid
+        # stack locations both before and after the jump.
+        my_nbargs = self.current_clt._debug_nbargs
+        target_nbargs = target_token._x86_clt._debug_nbargs
+        assert my_nbargs == target_nbargs
+        #
         target = target_token._x86_loop_code
         if target_token in self.target_tokens_currently_compiling:
             curpos = self.mc.get_relative_pos() + 5

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

View file
  • Ignore whitespace
         self.jump_target_descr = None
         self.close_stack_struct = 0
         self.final_jump_op = None
+        self.min_bytes_before_label = 0
 
     def _prepare(self, inputargs, operations, allgcrefs):
         self.fm = X86FrameManager()
         # note: we need to make a copy of inputargs because possibly_free_vars
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
+        self.min_bytes_before_label = 13
         return operations
 
     def prepare_bridge(self, prev_depths, inputargs, arglocs, operations,
             i += 1
         assert not self.rm.reg_bindings
         assert not self.xrm.reg_bindings
+        self.flush_loop()
         self.assembler.mc.mark_op(None) # end of the loop
 
+    def flush_loop(self):
+        # rare case: if the loop is too short, pad with NOPs
+        mc = self.assembler.mc
+        while mc.get_relative_pos() < self.min_bytes_before_label:
+            mc.NOP()
+
     def _compute_vars_longevity(self, inputargs, operations):
         # compute a dictionary that maps variables to index in
         # operations that is a "last-time-seen"
         #
         # if we are too close to the start of the loop, the label's target may
         # get overridden by redirect_call_assembler().  (rare case)
-        while self.assembler.mc.get_relative_pos() < 13:
-            self.assembler.mc.NOP()
+        self.flush_loop()
         #
         descr._x86_arglocs = nonfloatlocs, floatlocs
         descr._x86_loop_code = self.assembler.mc.get_relative_pos()

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

View file
  • Ignore whitespace
         FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
         #
         def execute_token(executable_token, *args):
+            clt = executable_token.compiled_loop_token
+            assert len(args) == clt._debug_nbargs
+            #
             addr = executable_token._x86_function_addr
             func = rffi.cast(FUNCPTR, addr)
             #llop.debug_print(lltype.Void, ">>>> Entering", addr)