Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit