Author: Richard Plangger <planri...@gmail.com> Branch: Changeset: r83609:2fd0d166512f Date: 2016-04-12 11:08 +0200 http://bitbucket.org/pypy/pypy/changeset/2fd0d166512f/
Log: catching up with the backend changes load_from_gc_table. stuffed the gc references before the constant pool, which makes it easy to access them using r13 diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py --- a/rpython/jit/backend/llsupport/test/test_rewrite.py +++ b/rpython/jit/backend/llsupport/test/test_rewrite.py @@ -12,7 +12,6 @@ from rpython.jit.metainterp.history import AbstractFailDescr from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.rtyper import rclass -from rpython.jit.backend.x86.arch import WORD from rpython.jit.backend.llsupport.symbolic import (WORD, get_array_token) diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py --- a/rpython/jit/backend/zarch/assembler.py +++ b/rpython/jit/backend/zarch/assembler.py @@ -1,5 +1,5 @@ from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler, - debug_bridge, DEBUG_COUNTER) + DEBUG_COUNTER) from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.llsupport import jitframe, rewrite from rpython.jit.backend.model import CompiledLoopToken @@ -78,7 +78,6 @@ self.mc = None self.pool = None - def target_arglocs(self, looptoken): return looptoken._zarch_arglocs @@ -131,28 +130,22 @@ def generate_quick_failure(self, guardtok): startpos = self.mc.currpos() - fail_descr, target = self.store_info_on_descr(startpos, guardtok) + faildescrindex, target = self.store_info_on_descr(startpos, guardtok) assert target != 0 - # POOL - #pool_offset = guardtok._pool_offset - #assert pool_offset != -1 - # overwrite the gcmap in the jitframe - #offset = pool_offset + RECOVERY_GCMAP_POOL_OFFSET - #self.mc.LG(r.SCRATCH2, l.pool(offset)) - ## overwrite the target in pool - #offset = pool_offset + RECOVERY_TARGET_POOL_OFFSET - ## overwrite!! - #self.pool.overwrite_64(self.mc, offset, target) - #self.mc.LG(r.r14, l.pool(offset)) + self.load_gcref_into(r.SCRATCH, faildescrindex) self.load_gcmap(self.mc, r.SCRATCH2, gcmap=guardtok.gcmap) self.mc.load_imm(r.r14, target) - self.mc.load_imm(r.SCRATCH, fail_descr) self.mc.BCR(c.ANY, r.r14) return startpos + def load_gcref_into(self, register, index): + topoff = index * WORD + size = self.pool.gcref_table_size + self.mc.LG(r.SCRATCH, l.addr(-size + topoff, r.POOL)) + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): descr = self.cpu.gc_ll_descr.write_barrier_descr if descr is None: @@ -625,7 +618,6 @@ frame_info = self.datablockwrapper.malloc_aligned( jitframe.JITFRAMEINFO_SIZE, alignment=WORD) clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) - clt.allgcrefs = [] clt.frame_info.clear() # for now if log: @@ -634,10 +626,12 @@ regalloc = Regalloc(assembler=self) # + allgcrefs = [] operations = regalloc.prepare_loop(inputargs, operations, - looptoken, clt.allgcrefs) - self.pool.pre_assemble(self, operations) - entrypos = self.mc.get_relative_pos() + looptoken, allgcrefs) + # reserve_gcref_table is handled in pool + self.pool.pre_assemble(self, operations, allgcrefs) + functionpos = self.mc.get_relative_pos() self._call_header_with_stack_check() looppos = self.mc.get_relative_pos() frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, @@ -645,7 +639,7 @@ self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) # size_excluding_failure_stuff = self.mc.get_relative_pos() - #self.pool.post_assemble(self) + # self.write_pending_failure_recoveries() full_size = self.mc.get_relative_pos() # @@ -653,6 +647,8 @@ if not we_are_translated(): self.mc.trap() # should be never reached rawstart = self.materialize_loop(looptoken) + looptoken._ll_function_addr = rawstart + functionpos + self.patch_gcref_table(looptoken, rawstart) # looptoken._ll_loop_code = looppos + rawstart debug_start("jit-backend-addr") @@ -660,8 +656,15 @@ looptoken.number, loopname, r_uint(rawstart + looppos), r_uint(rawstart + size_excluding_failure_stuff), - r_uint(rawstart))) + r_uint(rawstart + functionpos))) + debug_print(" gc table: 0x%x" % r_uint(self.gc_table_addr)) + debug_print(" function: 0x%x" % r_uint(rawstart + functionpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + looppos)) + debug_print(" failures: 0x%x" % r_uint(rawstart + + size_excluding_failure_stuff)) + debug_print(" end: 0x%x" % r_uint(rawstart + full_size)) debug_stop("jit-backend-addr") + # self.patch_pending_failure_recoveries(rawstart) # ops_offset = self.mc.ops_offset @@ -670,7 +673,6 @@ looptoken._zarch_rawstart = rawstart looptoken._zarch_fullsize = full_size looptoken._zarch_ops_offset = ops_offset - looptoken._ll_function_addr = rawstart + entrypos if logger: logger.log_loop(inputargs, operations, 0, "rewritten", name=loopname, ops_offset=ops_offset) @@ -683,7 +685,7 @@ # self.cpu.profile_agent.native_code_written(name, # rawstart, full_size) return AsmInfo(ops_offset, rawstart + looppos, - size_excluding_failure_stuff - looppos) + size_excluding_failure_stuff - looppos, rawstart) @rgc.no_release_gil def assemble_bridge(self, faildescr, inputargs, operations, @@ -700,23 +702,34 @@ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) regalloc = Regalloc(assembler=self) + allgcrefs = [] operations = regalloc.prepare_bridge(inputargs, arglocs, - operations, - self.current_clt.allgcrefs, + operations, allgcrefs, self.current_clt.frame_info) - self.pool.pre_assemble(self, operations, bridge=True) + self.pool.pre_assemble(self, operations, all_gcrefs, bridge=True) startpos = self.mc.get_relative_pos() self.mc.LARL(r.POOL, l.halfword(self.pool.pool_start - startpos)) self._check_frame_depth(self.mc, regalloc.get_gcmap()) + bridgestartpos = self.mc.get_relative_pos() frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) codeendpos = self.mc.get_relative_pos() #self.pool.post_assemble(self) self.write_pending_failure_recoveries() fullsize = self.mc.get_relative_pos() # + rawstart = self.materialize_loop(original_loop_token) + self.patch_gcref_table(original_loop_token, rawstart) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) - rawstart = self.materialize_loop(original_loop_token) - debug_bridge(descr_number, rawstart, codeendpos) + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart + startpos), + r_uint(rawstart + codeendpos))) + debug_print(" gc table: 0x%x" % r_uint(self.gc_table_addr)) + debug_print(" jump target: 0x%x" % r_uint(rawstart + startpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + bridgestartpos)) + debug_print(" failures: 0x%x" % r_uint(rawstart + codeendpos)) + debug_print(" end: 0x%x" % r_uint(rawstart + fullsize)) + debug_stop("jit-backend-addr") self.patch_pending_failure_recoveries(rawstart) # patch the jump from original guard self.patch_jump_for_descr(faildescr, rawstart + startpos) @@ -729,7 +742,22 @@ self.fixup_target_tokens(rawstart) self.update_frame_depth(frame_depth) self.teardown() - return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) + return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos, + rawstart + bridgestartpos) + + def patch_gcref_table(self, looptoken, rawstart): + self.gc_table_addr = rawstart + tracer = self.cpu.gc_ll_descr.make_gcref_tracer(rawstart, + self._allgcrefs) + gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken) + gcreftracers.append(tracer) # keepalive + self.teardown_gcrefs_list() + + def get_asmmemmgr_gcreftracers(self, looptoken): + clt = looptoken.compiled_loop_token + if clt.asmmemmgr_gcreftracers is None: + clt.asmmemmgr_gcreftracers = [] + return clt.asmmemmgr_gcreftracers def patch_jump_for_descr(self, faildescr, adr_new_target): # 'faildescr.adr_jump_offset' is the address of an instruction that is a @@ -996,10 +1024,6 @@ for tok in self.pending_guard_tokens: addr = rawstart + tok.pos_jump_offset # - # POOL - #tok.faildescr.adr_jump_offset = rawstart + \ - # self.pool.pool_start + tok._pool_offset + \ - # RECOVERY_TARGET_POOL_OFFSET tok.faildescr.adr_jump_offset = rawstart + tok.pos_recovery_stub relative_target = tok.pos_recovery_stub - tok.pos_jump_offset # @@ -1199,11 +1223,6 @@ # to be executed, thus remove the first opcode self.mc.b_offset(descr._ll_loop_code + self.mc.LARL_byte_count) else: - # POOL - #offset = self.pool.get_descr_offset(descr) + \ - # JUMPABS_TARGET_ADDR__POOL_OFFSET - #self.mc.LG(r.SCRATCH, l.pool(offset)) - #self.pool.overwrite_64(self.mc, offset, descr._ll_loop_code) self.mc.load_imm(r.SCRATCH, descr._ll_loop_code) self.mc.BCR(c.ANY, r.SCRATCH) @@ -1211,8 +1230,8 @@ def emit_finish(self, op, arglocs, regalloc): base_ofs = self.cpu.get_baseofs_of_frame_field() - if len(arglocs) > 1: - [return_val, fail_descr_loc] = arglocs + if len(arglocs) > 0: + [return_val] = arglocs if op.getarg(0).type == FLOAT: if return_val.is_in_pool(): self.mc.LDY(r.FP_SCRATCH, return_val) @@ -1223,8 +1242,6 @@ self.mc.LG(r.SCRATCH, return_val) return_val = r.SCRATCH self.mc.STG(return_val, l.addr(base_ofs, r.SPP)) - else: - [fail_descr_loc] = arglocs ofs = self.cpu.get_ofs_of_frame_field('jf_descr') ofs2 = self.cpu.get_ofs_of_frame_field('jf_gcmap') @@ -1247,7 +1264,9 @@ gcmap = lltype.nullptr(jitframe.GCMAP) self.load_gcmap(self.mc, r.r9, gcmap) - self.mc.load_imm(r.r10, fail_descr_loc.getint()) + descr = op.getdescr() + faildescrindex = self.get_gcref_from_faildescr(descr) + self.load_gcref_into(r.r10, faildescrindex) self.mc.STG(r.r9, l.addr(ofs2, r.SPP)) self.mc.STG(r.r10, l.addr(ofs, r.SPP)) diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py --- a/rpython/jit/backend/zarch/codebuilder.py +++ b/rpython/jit/backend/zarch/codebuilder.py @@ -31,9 +31,9 @@ class ZARCHGuardToken(GuardToken): def __init__(self, cpu, gcmap, descr, failargs, faillocs, - guard_opnum, frame_depth, fcond=c.cond_none): + guard_opnum, frame_depth, faildescrindex, fcond=c.cond_none): GuardToken.__init__(self, cpu, gcmap, descr, failargs, faillocs, - guard_opnum, frame_depth) + guard_opnum, frame_depth, faildescrindex) self.fcond = fcond class AbstractZARCHBuilder(object): diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -632,12 +632,19 @@ def build_guard_token(self, op, frame_depth, arglocs, fcond): descr = op.getdescr() gcmap = allocate_gcmap(self, frame_depth, r.JITFRAME_FIXED_SIZE) + faildescrindex = self.get_gcref_from_faildescr(descr) token = ZARCHGuardToken(self.cpu, gcmap, descr, op.getfailargs(), arglocs, op.getopnum(), frame_depth, - fcond) + faildescrindex, fcond) #token._pool_offset = self.pool.get_descr_offset(descr) return token + def emit_load_from_gc_table(self, op, arglocs, regalloc): + resloc, = arglocs + index = op.getarg(0).getint() + assert isinstance(resloc, RegLoc) + self.load_gcref_into(resloc, index) + def emit_guard_true(self, op, arglocs, regalloc): self._emit_guard(op, arglocs) diff --git a/rpython/jit/backend/zarch/pool.py b/rpython/jit/backend/zarch/pool.py --- a/rpython/jit/backend/zarch/pool.py +++ b/rpython/jit/backend/zarch/pool.py @@ -99,21 +99,23 @@ self.size = val assert val >= 0 - def pre_assemble(self, asm, operations, bridge=False): - # O(len(operations)). I do not think there is a way - # around this. - # + def pre_assemble(self, asm, operations, allgcrefs, bridge=False): # Problem: # constants such as floating point operations, plain pointers, # or integers might serve as parameter to an operation. thus - # it must be loaded into a register. There is a space benefit - # for 64-bit integers, or python floats, when a constant is used - # twice. + # it must be loaded into a register. Loading them from immediate + # takes quite long and slows down the resulting JIT code. + # There is a space benefit for 64-bit integers/doubles used twice. # - # Solution: - # the current solution (gcc does the same), use a literal pool - # located at register r13. This one can easily offset with 20 - # bit signed values (should be enough) + # creates the table for gc references here + self.gc_table_addr = asm.mc.get_relative_pos() + self.gcref_table_size = len(allgcrefs) * WORD + mc = asm.mc + assert mc.get_relative_pos() == 0 + for i in range(self.gcref_table_size): + mc.writechar('\x00') + asm.setup_gcrefs_list(allgcrefs) + self.pool_start = asm.mc.get_relative_pos() for op in operations: self.ensure_can_hold_constants(asm, op) diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py --- a/rpython/jit/backend/zarch/regalloc.py +++ b/rpython/jit/backend/zarch/regalloc.py @@ -1215,18 +1215,16 @@ src_locations2, dst_locations2, fptmploc, WORD) return [] + def prepare_load_from_gc_table(self, op): + resloc = self.rm.ensure_reg(op) + return [resloc] + def prepare_finish(self, op): - 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) - assert fail_descr > 0 if op.numargs() > 0: loc = self.ensure_reg(op.getarg(0)) - locs = [loc, imm(fail_descr)] + locs = [loc] else: - locs = [imm(fail_descr)] + locs = [] return locs def notimplemented(self, op): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit