[pypy-svn] r75541 - pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86
jcreigh at codespeak.net
jcreigh at codespeak.net
Wed Jun 23 23:39:01 CEST 2010
Author: jcreigh
Date: Wed Jun 23 23:38:59 2010
New Revision: 75541
Modified:
pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
Log:
get rid of mc2
Modified: pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/x86-64-jit-backend/pypy/jit/backend/x86/assembler.py Wed Jun 23 23:38:59 2010
@@ -108,9 +108,15 @@
if name.upper() == name or name == "writechr":
setattr(MachineCodeBlockWrapper, name, _new_method(name))
+class GuardToken(object):
+ def __init__(self, faildescr, failargs, fail_locs, exc):
+ self.faildescr = faildescr
+ self.failargs = failargs
+ self.fail_locs = fail_locs
+ self.exc = exc
+
class Assembler386(object):
mc = None
- mc2 = None
mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE
_float_constants = None
_regalloc = None
@@ -133,6 +139,7 @@
self.float_const_abs_addr = 0
self.malloc_fixedsize_slowpath1 = 0
self.malloc_fixedsize_slowpath2 = 0
+ self.pending_guard_tokens = []
self.setup_failure_recovery()
def leave_jitted_hook(self):
@@ -167,11 +174,7 @@
self.assembler_helper_adr = self.cpu.cast_ptr_to_int(
self.cpu.assembler_helper_ptr)
- # done
- # we generate the loop body in 'mc'
- # 'mc2' is for guard recovery code
self.mc = MachineCodeBlockWrapper(self.mc_size, self.cpu.profile_agent)
- self.mc2 = MachineCodeBlockWrapper(self.mc_size)
self._build_failure_recovery(False)
self._build_failure_recovery(True)
if self.cpu.supports_floats:
@@ -200,7 +203,7 @@
self.float_const_abs_addr = float_constants + 16
def _build_malloc_fixedsize_slowpath(self):
- mc = self.mc2._mc
+ mc = self.mc._mc
# ---------- first helper for the slow path of malloc ----------
self.malloc_fixedsize_slowpath1 = mc.tell()
if self.cpu.supports_floats: # save the XMM registers in
@@ -223,7 +226,7 @@
nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr()
mc.MOV(edx, heap(nursery_free_adr)) # load this in EDX
mc.RET()
- self.mc2.done()
+ self.mc.done()
def assemble_loop(self, inputargs, operations, looptoken):
"""adds the following attributes to looptoken:
@@ -237,6 +240,7 @@
funcname = self._find_debug_merge_point(operations)
self.make_sure_mc_exists()
+
regalloc = RegAlloc(self, self.cpu.translate_support_code)
arglocs = regalloc.prepare_loop(inputargs, operations, looptoken)
looptoken._x86_arglocs = arglocs
@@ -268,8 +272,8 @@
debug_print("Loop #", looptoken.number, "has address",
looptoken._x86_loop_code, "to", self.mc.tell())
self.mc.end_function()
+ self.write_pending_failure_recoveries()
-
def assemble_bridge(self, faildescr, inputargs, operations):
funcname = self._find_debug_merge_point(operations)
@@ -303,6 +307,14 @@
descr_number,
"has address", adr_bridge, "to", self.mc.tell())
self.mc.end_function()
+ self.write_pending_failure_recoveries()
+
+ def write_pending_failure_recoveries(self):
+ for tok in self.pending_guard_tokens:
+ addr = self.generate_quick_failure(tok.faildescr, tok.failargs, tok.fail_locs, tok.exc)
+ self.patch_jump_for_descr(tok.faildescr, addr)
+
+ self.pending_guard_tokens = []
def _find_debug_merge_point(self, operations):
for op in operations:
@@ -321,7 +333,6 @@
self._regalloc = regalloc
regalloc.walk_operations(operations)
self.mc.done()
- self.mc2.done()
if we_are_translated() or self.cpu.dont_keepalive_stuff:
self._regalloc = None # else keep it around for debugging
frame_depth = regalloc.fm.frame_depth
@@ -554,14 +565,15 @@
faildescr._x86_current_depths = current_depths
failargs = guard_op.fail_args
guard_opnum = guard_op.opnum
- failaddr = self.implement_guard_recovery(guard_opnum,
- faildescr, failargs,
- faillocs)
+ guard_token = self.implement_guard_recovery(guard_opnum,
+ faildescr, failargs,
+ faillocs)
+ self.pending_guard_tokens.append(guard_token)
if op is None:
dispatch_opnum = guard_opnum
else:
dispatch_opnum = op.opnum
- res = genop_guard_list[dispatch_opnum](self, op, guard_op, failaddr,
+ res = genop_guard_list[dispatch_opnum](self, op, guard_op, guard_token,
arglocs, resloc)
faildescr._x86_adr_jump_offset = res
@@ -615,24 +627,24 @@
return genop_cmp
def _cmpop_guard(cond, rev_cond, false_cond, false_rev_cond):
- def genop_cmp_guard(self, op, guard_op, addr, arglocs, result_loc):
+ def genop_cmp_guard(self, op, guard_op, guard_token, arglocs, result_loc):
guard_opnum = guard_op.opnum
if isinstance(op.args[0], Const):
self.mc.CMP(arglocs[1], arglocs[0])
if guard_opnum == rop.GUARD_FALSE:
- return self.implement_guard(addr, rev_cond)
+ return self.implement_guard(guard_token, rev_cond)
else:
- return self.implement_guard(addr, false_rev_cond)
+ return self.implement_guard(guard_token, false_rev_cond)
else:
self.mc.CMP(arglocs[0], arglocs[1])
if guard_opnum == rop.GUARD_FALSE:
- return self.implement_guard(addr, cond)
+ return self.implement_guard(guard_token, cond)
else:
- return self.implement_guard(addr, false_cond)
+ return self.implement_guard(guard_token, false_cond)
return genop_cmp_guard
def _cmpop_guard_float(cond, false_cond, need_jp):
- def genop_cmp_guard_float(self, op, guard_op, addr, arglocs,
+ def genop_cmp_guard_float(self, op, guard_op, guard_token, arglocs,
result_loc):
guard_opnum = guard_op.opnum
self.mc.UCOMISD(arglocs[0], arglocs[1])
@@ -640,16 +652,14 @@
mc = self.mc._mc
if need_jp:
mc.J_il8(rx86.Conditions['P'], 6)
- mc.J_il(rx86.Conditions[cond], addr)
- return mc.tell() - 4
+ return self.implement_guard(guard_token, cond)
else:
if need_jp:
mc = self.mc._mc
mc.J_il8(rx86.Conditions['P'], 2)
mc.J_il8(rx86.Conditions[cond], 5)
- mc.JMP_l(addr)
- return mc.tell() - 4
- return self.implement_guard(addr, false_cond)
+ return self.implement_guard(guard_token)
+ return self.implement_guard(guard_token, false_cond)
return genop_cmp_guard_float
# We need to specialize on force_mc because if force_mc is True, "mc" will
@@ -834,19 +844,17 @@
genop_guard_float_gt = _cmpop_guard_float("A", "BE", False)
genop_guard_float_ge = _cmpop_guard_float("AE", "B", False)
- def genop_guard_float_ne(self, op, guard_op, addr, arglocs, result_loc):
+ def genop_guard_float_ne(self, op, guard_op, guard_token, arglocs, result_loc):
guard_opnum = guard_op.opnum
self.mc.UCOMISD(arglocs[0], arglocs[1])
mc = self.mc._mc
if guard_opnum == rop.GUARD_TRUE:
mc.J_il8(rx86.Conditions['P'], 6)
- mc.J_il(rx86.Conditions['E'], addr)
- return mc.tell() - 4
+ return self.implement_guard(guard_token, 'E')
else:
mc.J_il8(rx86.Conditions['P'], 2)
mc.J_il8(rx86.Conditions['E'], 5)
- mc.JMP_l(addr)
- return mc.tell() - 4
+ return self.implement_guard(guard_token)
def genop_float_neg(self, op, arglocs, resloc):
# Following what gcc does: res = x ^ 0x8000000000000000
@@ -862,13 +870,13 @@
def genop_cast_int_to_float(self, op, arglocs, resloc):
self.mc.CVTSI2SD(resloc, arglocs[0])
- def genop_guard_int_is_true(self, op, guard_op, addr, arglocs, resloc):
+ def genop_guard_int_is_true(self, op, guard_op, guard_token, arglocs, resloc):
guard_opnum = guard_op.opnum
self.mc.CMP(arglocs[0], imm(0))
if guard_opnum == rop.GUARD_TRUE:
- return self.implement_guard(addr, 'Z')
+ return self.implement_guard(guard_token, 'Z')
else:
- return self.implement_guard(addr, 'NZ')
+ return self.implement_guard(guard_token, 'NZ')
def genop_int_is_true(self, op, arglocs, resloc):
self.mc.CMP(arglocs[0], imm(0))
@@ -876,13 +884,13 @@
self.mc.SET_ir(rx86.Conditions['NE'], rl.value)
self.mc.MOVZX8(resloc, rl)
- def genop_guard_int_is_zero(self, op, guard_op, addr, arglocs, resloc):
+ def genop_guard_int_is_zero(self, op, guard_op, guard_token, arglocs, resloc):
guard_opnum = guard_op.opnum
self.mc.CMP(arglocs[0], imm(0))
if guard_opnum == rop.GUARD_TRUE:
- return self.implement_guard(addr, 'NZ')
+ return self.implement_guard(guard_token, 'NZ')
else:
- return self.implement_guard(addr, 'Z')
+ return self.implement_guard(guard_token, 'Z')
def genop_int_is_zero(self, op, arglocs, resloc):
self.mc.CMP(arglocs[0], imm8(0))
@@ -1072,65 +1080,65 @@
else:
assert 0, itemsize
- def genop_guard_guard_true(self, ign_1, guard_op, addr, locs, ign_2):
+ def genop_guard_guard_true(self, ign_1, guard_op, guard_token, locs, ign_2):
loc = locs[0]
self.mc.TEST(loc, loc)
- return self.implement_guard(addr, 'Z')
+ return self.implement_guard(guard_token, 'Z')
genop_guard_guard_nonnull = genop_guard_guard_true
- def genop_guard_guard_no_exception(self, ign_1, guard_op, addr,
+ def genop_guard_guard_no_exception(self, ign_1, guard_op, guard_token,
locs, ign_2):
self.mc.CMP(heap(self.cpu.pos_exception()), imm(0))
- return self.implement_guard(addr, 'NZ')
+ return self.implement_guard(guard_token, 'NZ')
- def genop_guard_guard_exception(self, ign_1, guard_op, addr,
+ def genop_guard_guard_exception(self, ign_1, guard_op, guard_token,
locs, resloc):
loc = locs[0]
loc1 = locs[1]
self.mc.MOV(loc1, heap(self.cpu.pos_exception()))
self.mc.CMP(loc1, loc)
- addr = self.implement_guard(addr, 'NE')
+ addr = self.implement_guard(guard_token, 'NE')
if resloc is not None:
self.mc.MOV(resloc, heap(self.cpu.pos_exc_value()))
self.mc.MOV(heap(self.cpu.pos_exception()), imm(0))
self.mc.MOV(heap(self.cpu.pos_exc_value()), imm(0))
return addr
- def _gen_guard_overflow(self, guard_op, addr):
+ def _gen_guard_overflow(self, guard_op, guard_token):
guard_opnum = guard_op.opnum
if guard_opnum == rop.GUARD_NO_OVERFLOW:
- return self.implement_guard(addr, 'O')
+ return self.implement_guard(guard_token, 'O')
elif guard_opnum == rop.GUARD_OVERFLOW:
- return self.implement_guard(addr, 'NO')
+ return self.implement_guard(guard_token, 'NO')
else:
print "int_xxx_ovf followed by", guard_op.getopname()
raise AssertionError
- def genop_guard_int_add_ovf(self, op, guard_op, addr, arglocs, result_loc):
+ def genop_guard_int_add_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
self.genop_int_add(op, arglocs, result_loc)
- return self._gen_guard_overflow(guard_op, addr)
+ return self._gen_guard_overflow(guard_op, guard_token)
- def genop_guard_int_sub_ovf(self, op, guard_op, addr, arglocs, result_loc):
+ def genop_guard_int_sub_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
self.genop_int_sub(op, arglocs, result_loc)
- return self._gen_guard_overflow(guard_op, addr)
+ return self._gen_guard_overflow(guard_op, guard_token)
- def genop_guard_int_mul_ovf(self, op, guard_op, addr, arglocs, result_loc):
+ def genop_guard_int_mul_ovf(self, op, guard_op, guard_token, arglocs, result_loc):
self.genop_int_mul(op, arglocs, result_loc)
- return self._gen_guard_overflow(guard_op, addr)
+ return self._gen_guard_overflow(guard_op, guard_token)
- def genop_guard_guard_false(self, ign_1, guard_op, addr, locs, ign_2):
+ def genop_guard_guard_false(self, ign_1, guard_op, guard_token, locs, ign_2):
loc = locs[0]
self.mc.TEST(loc, loc)
- return self.implement_guard(addr, 'NZ')
+ return self.implement_guard(guard_token, 'NZ')
genop_guard_guard_isnull = genop_guard_guard_false
- def genop_guard_guard_value(self, ign_1, guard_op, addr, locs, ign_2):
+ def genop_guard_guard_value(self, ign_1, guard_op, guard_token, locs, ign_2):
if guard_op.args[0].type == FLOAT:
assert guard_op.args[1].type == FLOAT
self.mc.UCOMISD(locs[0], locs[1])
else:
self.mc.CMP(locs[0], locs[1])
- return self.implement_guard(addr, 'NE')
+ return self.implement_guard(guard_token, 'NE')
def _cmp_guard_class(self, mc, locs):
offset = self.cpu.vtable_offset
@@ -1155,14 +1163,14 @@
expected_typeid = (classptr - sizeof_ti - type_info_group) >> 2
mc.CMP16(mem(locs[0], 0), ImmedLoc(expected_typeid))
- def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2):
+ def genop_guard_guard_class(self, ign_1, guard_op, guard_token, locs, ign_2):
mc = self._start_block()
self._cmp_guard_class(mc, locs)
self._stop_block()
- return self.implement_guard(addr, 'NE')
+ return self.implement_guard(guard_token, 'NE')
def genop_guard_guard_nonnull_class(self, ign_1, guard_op,
- addr, locs, ign_2):
+ guard_token, locs, ign_2):
mc = self._start_block()
mc.CMP(locs[0], imm8(1))
# Patched below
@@ -1175,14 +1183,14 @@
mc.overwrite(jb_location-1, [chr(offset)])
self._stop_block()
#
- return self.implement_guard(addr, 'NE')
+ return self.implement_guard(guard_token, 'NE')
def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
fail_locs):
exc = (guard_opnum == rop.GUARD_EXCEPTION or
guard_opnum == rop.GUARD_NO_EXCEPTION or
guard_opnum == rop.GUARD_NOT_FORCED)
- return self.generate_quick_failure(faildescr, failargs, fail_locs, exc)
+ return GuardToken(faildescr, failargs, fail_locs, exc)
def generate_quick_failure(self, faildescr, failargs, fail_locs, exc):
"""Generate the initial code for handling a failure. We try to
@@ -1193,9 +1201,9 @@
"""
fail_index = self.cpu.get_fail_descr_number(faildescr)
bytes_needed = 20 + 5 * len(failargs) # conservative estimate
- if self.mc2.bytes_free() < bytes_needed:
- self.mc2.make_new_mc()
- mc = self.mc2._mc
+ if self.mc.bytes_free() < bytes_needed:
+ self.mc.make_new_mc()
+ mc = self.mc._mc
addr = mc.tell()
withfloats = False
for box in failargs:
@@ -1389,7 +1397,7 @@
self.failure_recovery_func)
failure_recovery_func = rffi.cast(lltype.Signed,
failure_recovery_func)
- mc = self.mc2._mc
+ mc = self.mc._mc
# Assume that we are called at the beginning, when there is no risk
# that 'mc' runs out of space. Checked by asserts in mc.write().
recovery_addr = mc.tell()
@@ -1441,9 +1449,9 @@
# _assemble_bootstrap_code(). The LEA below throws away most
# of the frame, including all the PUSHes that we did just above.
- # XXX: using self.mc2 instead of mc to make translation pass
- self._call_footer(self.mc2)
- self.mc2.done()
+ # XXX: using self.mc instead of mc to make translation pass
+ self._call_footer(self.mc)
+ self.mc.done()
self.failure_recovery_code[exc + 2 * withfloats] = recovery_addr
def generate_failure(self, fail_index, locs, exc, locs_are_ref):
@@ -1493,11 +1501,12 @@
# FIXME: I changed the third argument to this method, but I don't know
# what to do with @specialize
@specialize.arg(2)
- def implement_guard(self, addr, condition=None):
+ def implement_guard(self, guard_token, condition=None):
+ # These jumps are patched later
if condition:
- self.mc.J_il(rx86.Conditions[condition], addr)
+ self.mc.J_il(rx86.Conditions[condition], self.mc.tell())
else:
- self.mc.JMP_l(addr)
+ self.mc.JMP_l(self.mc.tell())
return self.mc.tell() - 4
def genop_call(self, op, arglocs, resloc):
@@ -1523,16 +1532,16 @@
elif size == 2:
self.mc.AND(eax, imm(0xffff))
- def genop_guard_call_may_force(self, op, guard_op, addr,
+ def genop_guard_call_may_force(self, op, guard_op, guard_token,
arglocs, result_loc):
faildescr = guard_op.descr
fail_index = self.cpu.get_fail_descr_number(faildescr)
self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)
self.genop_call(op, arglocs, result_loc)
self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
- return self.implement_guard(addr, 'L')
+ return self.implement_guard(guard_token, 'L')
- def genop_guard_call_assembler(self, op, guard_op, addr,
+ def genop_guard_call_assembler(self, op, guard_op, guard_token,
arglocs, result_loc):
faildescr = guard_op.descr
fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -1615,7 +1624,7 @@
mc.overwrite(jmp_location - 1, [chr(offset)])
self._stop_block()
self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
- return self.implement_guard(addr, 'L')
+ return self.implement_guard(guard_token, 'L')
def genop_discard_cond_call_gc_wb(self, op, arglocs):
# use 'mc._mc' directly instead of 'mc', to avoid
More information about the Pypy-commit
mailing list