Author: Armin Rigo <[email protected]>
Branch: jit-simplify-backendintf
Changeset: r50411:b9daf080154c
Date: 2011-12-12 09:59 +0100
http://bitbucket.org/pypy/pypy/changeset/b9daf080154c/
Log: Fixes.
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -3047,13 +3047,13 @@
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
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -423,7 +423,6 @@
'''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
@@ -447,11 +446,11 @@
#
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)
@@ -800,7 +799,9 @@
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.
@@ -808,7 +809,7 @@
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):
@@ -2235,7 +2236,7 @@
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),
@@ -2469,6 +2470,14 @@
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
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -165,6 +165,7 @@
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()
@@ -188,6 +189,7 @@
# 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,
@@ -460,8 +462,15 @@
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"
@@ -1493,8 +1502,7 @@
#
# 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()
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -117,6 +117,9 @@
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)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit