Author: David Schneider <david.schnei...@picle.org> Branch: arm-backend-2 Changeset: r51440:be46980ab0b2 Date: 2012-01-18 12:16 +0100 http://bitbucket.org/pypy/pypy/changeset/be46980ab0b2/
Log: Port changes since last merge diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py --- a/pypy/jit/backend/arm/assembler.py +++ b/pypy/jit/backend/arm/assembler.py @@ -596,6 +596,7 @@ rawstart = self.materialize_loop(looptoken) looptoken._arm_func_addr = rawstart + size_excluding_failure_stuff = self.mc.get_relative_pos() self.process_pending_guards(rawstart) self.fixup_target_tokens(rawstart) @@ -604,8 +605,13 @@ self.mc._dump_trace(rawstart, 'loop_%s.asm' % self.cpu.total_compiled_loops) print 'Done assembling loop with token %r' % looptoken + + ops_offset = self.mc.ops_offset self.teardown() + return AsmInfo(ops_offset, rawstart + loop_head, + size_excluding_failure_stuff - loop_head) + def _assemble(self, operations, regalloc): regalloc.compute_hint_frame_locations(operations) #self.mc.BKPT() @@ -632,6 +638,7 @@ if not we_are_translated(): assert len(inputargs) == len(arglocs) + startpos = self.mc.get_relative_pos() regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager()) regalloc.prepare_bridge(inputargs, arglocs, operations) @@ -639,15 +646,19 @@ frame_depth = self._assemble(operations, regalloc) + codeendpos = self.mc.get_relative_pos() + self._patch_sp_offset(sp_patch_location, frame_depth) self.write_pending_failure_recoveries() + rawstart = self.materialize_loop(original_loop_token) + self.process_pending_guards(rawstart) + self.fixup_target_tokens(rawstart) self.patch_trace(faildescr, original_loop_token, rawstart, regalloc) - self.fixup_target_tokens(rawstart) if not we_are_translated(): # for the benefit of tests @@ -658,12 +669,19 @@ self.cpu.total_compiled_bridges) self.current_clt.frame_depth = max(self.current_clt.frame_depth, frame_depth) + ops_offset = self.mc.ops_offset self.teardown() + return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) def _find_failure_recovery_bytecode(self, faildescr): - guard_addr = faildescr._arm_block_start + faildescr._arm_guard_pos + guard_stub_addr = faildescr._arm_recovery_stub_offset + if guard_stub_addr == 0: + # This case should be prevented by the logic in compile.py: + # look for CNT_BUSY_FLAG, which disables tracing from a guard + # when another tracing from the same guard is already in progress. + raise BridgeAlreadyCompiled # a guard requires 3 words to encode the jump to the exit code. - return guard_addr + 3 * WORD + return guard_stub_addr + 3 * WORD def fixup_target_tokens(self, rawstart): for targettoken in self.target_tokens_currently_compiling: @@ -698,21 +716,27 @@ for tok in self.pending_guards: descr = tok.descr assert isinstance(descr, AbstractFailDescr) + jump_target = tok.pos_recovery_stub + relative_target = jump_target - tok.offset - #XXX _arm_block_start should go in the looptoken - descr._arm_block_start = block_start + addr = block_start + tok.offset + stub_addr = block_start + jump_target + + descr._arm_recovery_stub_offset = stub_addr if not tok.is_invalidate: #patch the guard jumpt to the stub # overwrite the generate NOP with a B_offs to the pos of the # stub mc = ARMv7Builder() - mc.B_offs(descr._arm_guard_pos - tok.offset, - c.get_opposite_of(tok.fcond)) - mc.copy_to_raw_memory(block_start + tok.offset) + mc.B_offs(relative_target, c.get_opposite_of(tok.fcond)) + mc.copy_to_raw_memory(addr) else: - clt.invalidate_positions.append( - (block_start + tok.offset, descr._arm_guard_pos - tok.offset)) + # GUARD_NOT_INVALIDATED, record an entry in + # clt.invalidate_positions of the form: + # (addr-in-the-code-of-the-not-yet-written-jump-target, + # relative-target-to-use) + clt.invalidate_positions.append((addr, relative_target)) def get_asmmemmgr_blocks(self, looptoken): clt = looptoken.compiled_loop_token @@ -770,6 +794,7 @@ regalloc.next_instruction() i = regalloc.position() op = operations[i] + self.mc.mark_op(op) opnum = op.getopnum() if op.has_no_side_effect() and op.result not in regalloc.longevity: regalloc.possibly_free_vars_for_op(op) @@ -797,6 +822,7 @@ regalloc.possibly_free_vars_for_op(op) regalloc.free_temp_vars() regalloc._check_invariants() + self.mc.mark_op(None) # end of the loop # from ../x86/regalloc.py def can_merge_with_next_guard(self, op, i, operations): @@ -852,9 +878,11 @@ # The first instruction (word) is not overwritten, because it is the # one that actually checks the condition b = ARMv7Builder() - patch_addr = faildescr._arm_block_start + faildescr._arm_guard_pos + adr_jump_offset = faildescr._arm_recovery_stub_offset + assert adr_jump_offset != 0 b.B(bridge_addr) - b.copy_to_raw_memory(patch_addr) + b.copy_to_raw_memory(adr_jump_offset) + faildescr._arm_recovery_stub_offset = 0 # regalloc support def load(self, loc, value): @@ -1186,3 +1214,7 @@ if hasattr(AssemblerARM, methname): func = getattr(AssemblerARM, methname).im_func asm_operations_with_guard[value] = func + + +class BridgeAlreadyCompiled(Exception): + pass diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py --- a/pypy/jit/backend/arm/codebuilder.py +++ b/pypy/jit/backend/arm/codebuilder.py @@ -265,6 +265,15 @@ def __init__(self): AbstractARMv7Builder.__init__(self) self.init_block_builder() + # + # ResOperation --> offset in the assembly. + # ops_offset[None] represents the beginning of the code after the last op + # (i.e., the tail of the loop) + self.ops_offset = {} + + def mark_op(self, op): + pos = self.get_relative_pos() + self.ops_offset[op] = pos def _dump_trace(self, addr, name, formatter=-1): if not we_are_translated(): diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py --- a/pypy/jit/backend/arm/runner.py +++ b/pypy/jit/backend/arm/runner.py @@ -32,19 +32,19 @@ self.assembler.setup_once() def finish_once(self): - pass + self.assembler.finish_once() def compile_loop(self, inputargs, operations, looptoken, log=True, name=''): - self.assembler.assemble_loop(inputargs, operations, + return self.assembler.assemble_loop(inputargs, operations, looptoken, log=log) def compile_bridge(self, faildescr, inputargs, operations, original_loop_token, log=True): clt = original_loop_token.compiled_loop_token clt.compiling_a_bridge() - self.assembler.assemble_bridge(faildescr, inputargs, operations, - original_loop_token, log=log) + return self.assembler.assemble_bridge(faildescr, inputargs, operations, + original_loop_token, log=log) def get_latest_value_float(self, index): return self.assembler.fail_boxes_float.getitem(index) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit