Author: Armin Rigo <[email protected]>
Branch: jit-constptr-2
Changeset: r83464:27b8d73fef68
Date: 2016-03-31 15:27 +0100
http://bitbucket.org/pypy/pypy/changeset/27b8d73fef68/
Log: progress for x86-64
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -23,10 +23,11 @@
class GuardToken(object):
def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
- guard_opnum, frame_depth):
+ guard_opnum, frame_depth, faildescrindex):
assert isinstance(faildescr, AbstractFailDescr)
self.cpu = cpu
self.faildescr = faildescr
+ self.faildescrindex = faildescrindex
self.failargs = failargs
self.fail_locs = fail_locs
self.gcmap = self.compute_gcmap(gcmap, failargs,
@@ -144,6 +145,21 @@
self.codemap_builder = CodemapBuilder()
self._finish_gcmap = lltype.nullptr(jitframe.GCMAP)
+ def setup_gcrefs_list(self, allgcrefs):
+ self._allgcrefs = allgcrefs
+ self._allgcrefs_faildescr_next = 0
+
+ def teardown_gcrefs_list(self):
+ self._allgcrefs = None
+
+ def get_gcref_from_faildescr(self, descr):
+ """This assumes that it is called in order for all faildescrs."""
+ search = cast_instance_to_gcref(descr)
+ while self._allgcrefs[self._allgcrefs_faildescr_next] != search:
+ self._allgcrefs_faildescr_next += 1
+ assert self._allgcrefs_faildescr_next < len(self._allgcrefs)
+ return self._allgcrefs_faildescr_next
+
def set_debug(self, v):
r = self._debug
self._debug = v
@@ -186,8 +202,7 @@
break
exc = guardtok.must_save_exception()
target = self.failure_recovery_code[exc + 2 * withfloats]
- fail_descr = cast_instance_to_gcref(guardtok.faildescr)
- fail_descr = rffi.cast(lltype.Signed, fail_descr)
+ faildescrindex = guardtok.faildescrindex
base_ofs = self.cpu.get_baseofs_of_frame_field()
#
# in practice, about 2/3rd of 'positions' lists that we build are
@@ -229,7 +244,7 @@
self._previous_rd_locs = positions
# write down the positions of locs
guardtok.faildescr.rd_locs = positions
- return fail_descr, target
+ return faildescrindex, target
def enter_portal_frame(self, op):
if self.cpu.HAS_CODEMAP:
@@ -288,7 +303,7 @@
gcref = cast_instance_to_gcref(value)
if gcref:
- rgc._make_sure_does_not_move(gcref)
+ rgc._make_sure_does_not_move(gcref) # but should be prebuilt
value = rffi.cast(lltype.Signed, gcref)
je_location = self._call_assembler_check_descr(value, tmploc)
#
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -514,7 +514,7 @@
full_size = self.mc.get_relative_pos()
#
rawstart = self.materialize_loop(looptoken)
- self.patch_gcref_table(looptoken, allgcrefs, rawstart)
+ self.patch_gcref_table(looptoken, rawstart)
self.patch_stack_checks(frame_depth_no_fixed_size +
JITFRAME_FIXED_SIZE,
rawstart)
looptoken._ll_loop_code = looppos + rawstart
@@ -582,7 +582,7 @@
fullsize = self.mc.get_relative_pos()
#
rawstart = self.materialize_loop(original_loop_token)
- self.patch_gcref_table(original_loop_token, allgcrefs, rawstart)
+ self.patch_gcref_table(original_loop_token, rawstart)
self.patch_stack_checks(frame_depth_no_fixed_size +
JITFRAME_FIXED_SIZE,
rawstart)
debug_bridge(descr_number, rawstart, codeendpos)
@@ -669,12 +669,14 @@
assert mc.get_relative_pos() == 0
for i in range(gcref_table_size):
mc.writechar('\x00')
+ self.setup_gcrefs_list(allgcrefs)
- def patch_gcref_table(self, looptoken, allgcrefs, rawstart):
+ def patch_gcref_table(self, looptoken, rawstart):
assert IS_X86_64, "XXX"
- tracer = gcreftracer.make_gcref_tracer(rawstart, allgcrefs)
+ tracer = gcreftracer.make_gcref_tracer(rawstart, self._allgcrefs)
gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken)
gcreftracers.append(tracer) # keepalive
+ self.teardown_gcrefs_list()
def write_pending_failure_recoveries(self, regalloc):
# for each pending guard, generate the code of the recovery stub
@@ -1386,16 +1388,20 @@
genop_cast_ptr_to_int = _genop_same_as
genop_cast_int_to_ptr = _genop_same_as
+ def _patch_load_from_gc_table(self, index):
+ # must be called immediately after a "p"-mode instruction
+ # has been emitted
+ address_in_buffer = index * WORD # at the start of the buffer
+ p_location = self.mc.get_relative_pos()
+ offset = address_in_buffer - p_location
+ self.mc.overwrite32(p_location-4, offset)
+
def genop_load_from_gc_table(self, op, arglocs, resloc):
[loc] = arglocs
assert isinstance(loc, ImmedLoc)
assert isinstance(resloc, RegLoc)
- address_in_buffer = loc.value * WORD # at the start of the buffer
- assert IS_X86_64, "XXX"
self.mc.MOV_rp(resloc.value, 0) # %rip-relative
- p_location = self.mc.get_relative_pos()
- offset = address_in_buffer - p_location
- self.mc.overwrite32(p_location-4, offset)
+ self._patch_load_from_gc_table(loc.value)
def genop_int_force_ge_zero(self, op, arglocs, resloc):
self.mc.TEST(arglocs[0], arglocs[0])
@@ -1872,8 +1878,9 @@
def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
fail_locs, frame_depth):
gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
+ faildescrindex = self.get_gcref_from_faildescr(faildescr)
return GuardToken(self.cpu, gcmap, faildescr, failargs, fail_locs,
- guard_opnum, frame_depth)
+ guard_opnum, frame_depth, faildescrindex)
def generate_propagate_error_64(self):
assert WORD == 8
@@ -1891,8 +1898,9 @@
self._update_at_exit(guardtok.fail_locs, guardtok.failargs,
guardtok.faildescr, regalloc)
#
- fail_descr, target = self.store_info_on_descr(startpos, guardtok)
- self.mc.PUSH(imm(fail_descr))
+ faildescrindex, target = self.store_info_on_descr(startpos, guardtok)
+ self.mc.PUSH_p(0) # %rip-relative
+ self._patch_load_from_gc_table(faildescrindex)
self.push_gcmap(self.mc, guardtok.gcmap, push=True)
self.mc.JMP(imm(target))
return startpos
@@ -1996,17 +2004,21 @@
def genop_finish(self, op, arglocs, result_loc):
base_ofs = self.cpu.get_baseofs_of_frame_field()
- if len(arglocs) == 2:
- [return_val, fail_descr_loc] = arglocs
+ if len(arglocs) > 0:
+ [return_val] = arglocs
if op.getarg(0).type == FLOAT and not IS_X86_64:
size = WORD * 2
else:
size = WORD
self.save_into_mem(raw_stack(base_ofs), return_val, imm(size))
- else:
- [fail_descr_loc] = arglocs
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mov(fail_descr_loc, RawEbpLoc(ofs))
+
+ descr = op.getdescr()
+ faildescrindex = self.get_gcref_from_faildescr(descr)
+ self.mc.MOV_rp(eax.value, 0)
+ self._patch_load_from_gc_table(faildescrindex)
+ self.mov(eax, RawEbpLoc(ofs))
+
arglist = op.getarglist()
if arglist and arglist[0].type == REF:
if self._finish_gcmap:
@@ -2076,8 +2088,12 @@
guard_op.getopnum() == rop.GUARD_NOT_FORCED_2)
faildescr = guard_op.getdescr()
ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
- self.mc.MOV(raw_stack(ofs), imm(rffi.cast(lltype.Signed,
- cast_instance_to_gcref(faildescr))))
+
+ assert IS_X86_64, "XXX uses the scratch reg"
+ faildescrindex = self.get_gcref_from_faildescr(faildescr)
+ self.mc.MOV_rp(X86_64_SCRATCH_REG.value, 0)
+ self._patch_load_from_gc_table(faildescrindex)
+ self.mc.MOV(raw_stack(ofs), X86_64_SCRATCH_REG)
def _find_nearby_operation(self, delta):
regalloc = self._regalloc
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -423,16 +423,11 @@
def consider_finish(self, op):
# the frame is in ebp, but we have to point where in the frame is
# the potential argument to FINISH
- descr = op.getdescr()
- fail_descr = cast_instance_to_gcref(descr)
- # we know it does not move, but well
- rgc._make_sure_does_not_move(fail_descr)
- fail_descr = rffi.cast(lltype.Signed, fail_descr)
if op.numargs() == 1:
loc = self.make_sure_var_in_reg(op.getarg(0))
- locs = [loc, imm(fail_descr)]
+ locs = [loc]
else:
- locs = [imm(fail_descr)]
+ locs = []
self.perform(op, locs, None)
def consider_guard_no_exception(self, op):
diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py
--- a/rpython/jit/backend/x86/rx86.py
+++ b/rpython/jit/backend/x86/rx86.py
@@ -600,6 +600,7 @@
PUS1_r = insn(rex_nw, register(1), '\x50')
PUS1_b = insn(rex_nw, '\xFF', orbyte(6<<3), stack_bp(1))
PUS1_m = insn(rex_nw, '\xFF', orbyte(6<<3), mem_reg_plus_const(1))
+ PUS1_p = insn(rex_nw, '\xFF', orbyte(6<<3), rip_offset(1))
PUS1_i8 = insn('\x6A', immediate(1, 'b'))
PUS1_i32 = insn('\x68', immediate(1, 'i'))
@@ -622,6 +623,10 @@
self.PUS1_i32(immed)
self.stack_frame_size_delta(+self.WORD)
+ def PUSH_p(self, rip_offset):
+ self.PUS1_p(rip_offset)
+ self.stack_frame_size_delta(+self.WORD)
+
PO1_r = insn(rex_nw, register(1), '\x58')
PO1_b = insn(rex_nw, '\x8F', orbyte(0<<3), stack_bp(1))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit