Author: Armin Rigo <[email protected]>
Branch: jit-constptr-2
Changeset: r83502:646421afc5c5
Date: 2016-04-01 19:14 +0200
http://bitbucket.org/pypy/pypy/changeset/646421afc5c5/
Log: (untested) ARM support
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -14,7 +14,7 @@
CoreRegisterManager, check_imm_arg, VFPRegisterManager,
operations as regalloc_operations)
from rpython.jit.backend.llsupport import jitframe, rewrite
-from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER,
debug_bridge, BaseAssembler
+from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER,
BaseAssembler
from rpython.jit.backend.llsupport.regalloc import get_scale,
valid_addressing_size
from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
from rpython.jit.backend.model import CompiledLoopToken
@@ -481,8 +481,9 @@
def generate_quick_failure(self, guardtok):
startpos = self.mc.currpos()
- fail_descr, target = self.store_info_on_descr(startpos, guardtok)
- self.regalloc_push(imm(fail_descr))
+ faildescrindex, target = self.store_info_on_descr(startpos, guardtok)
+ self.load_from_gc_table(r.ip.value, faildescrindex)
+ self.regalloc_push(r.ip)
self.push_gcmap(self.mc, gcmap=guardtok.gcmap, push=True)
self.mc.BL(target)
return startpos
@@ -596,20 +597,22 @@
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:
operations = self._inject_debugging_code(looptoken, operations,
'e', looptoken.number)
+ regalloc = Regalloc(assembler=self)
+ allgcrefs = []
+ operations = regalloc.prepare_loop(inputargs, operations, looptoken,
+ allgcrefs)
+ self.reserve_gcref_table(allgcrefs)
+ functionpos = self.mc.get_relative_pos()
+
self._call_header_with_stack_check()
self._check_frame_depth_debug(self.mc)
- regalloc = Regalloc(assembler=self)
- operations = regalloc.prepare_loop(inputargs, operations, looptoken,
- clt.allgcrefs)
-
loop_head = self.mc.get_relative_pos()
looptoken._ll_loop_code = loop_head
#
@@ -620,9 +623,11 @@
self.write_pending_failure_recoveries()
+ full_size = self.mc.get_relative_pos()
rawstart = self.materialize_loop(looptoken)
- looptoken._function_addr = looptoken._ll_function_addr = rawstart
+ looptoken._ll_function_addr = rawstart + functionpos
+ self.patch_gcref_table(looptoken, rawstart)
self.process_pending_guards(rawstart)
self.fixup_target_tokens(rawstart)
@@ -641,7 +646,13 @@
looptoken.number, loopname,
r_uint(rawstart + loop_head),
r_uint(rawstart + size_excluding_failure_stuff),
- r_uint(rawstart)))
+ r_uint(rawstart + functionpos)))
+ debug_print(" gc table: 0x%x" % r_uint(rawstart))
+ debug_print(" function: 0x%x" % r_uint(rawstart + functionpos))
+ debug_print(" resops: 0x%x" % r_uint(rawstart + loop_head))
+ 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")
return AsmInfo(ops_offset, rawstart + loop_head,
@@ -678,27 +689,43 @@
arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
regalloc = Regalloc(assembler=self)
- startpos = self.mc.get_relative_pos()
+ allgcrefs = []
operations = regalloc.prepare_bridge(inputargs, arglocs,
operations,
- self.current_clt.allgcrefs,
+ allgcrefs,
self.current_clt.frame_info)
+ self.reserve_gcref_table(allgcrefs)
+ startpos = self.mc.get_relative_pos()
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.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.process_pending_guards(rawstart)
+ 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(rawstart))
+ 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")
+
# patch the jump from original guard
self.patch_trace(faildescr, original_loop_token,
- rawstart, regalloc)
+ rawstart + startpos, regalloc)
self.patch_stack_checks(frame_depth_no_fixed_size +
JITFRAME_FIXED_SIZE,
rawstart)
@@ -716,9 +743,53 @@
ops_offset=ops_offset)
self.teardown()
- debug_bridge(descr_number, rawstart, codeendpos)
+ return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos)
- return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos)
+ def reserve_gcref_table(self, allgcrefs):
+ gcref_table_size = len(allgcrefs) * WORD
+ # align to a multiple of 16 and reserve space at the beginning
+ # of the machine code for the gc table. This lets us write
+ # machine code with relative addressing (see load_from_gc_table())
+ gcref_table_size = (gcref_table_size + 15) & ~15
+ mc = self.mc
+ 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, rawstart):
+ # the gc table is at the start of the machine code. Fill it now
+ 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 load_from_gc_table(self, regnum, index):
+ """emits either:
+ LDR Rt, [PC, #offset] if -4095 <= offset
+ or:
+ gen_load_int(Rt, offset)
+ LDR Rt, [PC, Rt] for larger offsets
+ """
+ mc = self.mc
+ address_in_buffer = index * WORD # at the start of the buffer
+ offset = address_in_buffer - (mc.get_relative_pos() + 8) # negative
+ if offset >= -4095:
+ mc.LDR_ri(regnum, r.pc.value, offset)
+ else:
+ # The offset we're loading is negative: right now,
+ # gen_load_int() will always use exactly
+ # get_max_size_of_gen_load_int() instructions. No point
+ # in optimizing in case we get less. Just in case though,
+ # we check and pad with nops.
+ extra_bytes = mc.get_max_size_of_gen_load_int() * 2
+ offset -= extra_bytes
+ start = mc.get_relative_pos()
+ mc.gen_load_int(regnum, offset)
+ while mc.get_relative_pos() != start + extra_bytes:
+ mc.NOP()
+ mc.LDR_rr(regnum, r.pc.value, regnum)
def new_stack_loc(self, i, tp):
base_ofs = self.cpu.get_baseofs_of_frame_field()
@@ -929,6 +1000,12 @@
clt.asmmemmgr_blocks = []
return clt.asmmemmgr_blocks
+ 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 _walk_operations(self, inputargs, operations, regalloc):
fcond = c.AL
self._regalloc = regalloc
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -35,9 +35,9 @@
class ArmGuardToken(GuardToken):
def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
- offset, guard_opnum, frame_depth, fcond=c.AL):
+ offset, guard_opnum, frame_depth, faildescrindex, fcond=c.AL):
GuardToken.__init__(self, cpu, gcmap, faildescr, failargs, fail_locs,
- guard_opnum, frame_depth)
+ guard_opnum, frame_depth, faildescrindex)
self.fcond = fcond
self.offset = offset
@@ -178,6 +178,7 @@
assert isinstance(descr, AbstractFailDescr)
gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
+ faildescrindex = self.get_gcref_from_faildescr(descr)
token = ArmGuardToken(self.cpu, gcmap,
descr,
failargs=op.getfailargs(),
@@ -185,6 +186,7 @@
offset=offset,
guard_opnum=op.getopnum(),
frame_depth=frame_depth,
+ faildescrindex=faildescrindex,
fcond=fcond)
return token
@@ -398,14 +400,13 @@
def emit_op_finish(self, op, arglocs, regalloc, fcond):
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
self.store_reg(self.mc, return_val, r.fp, base_ofs)
- else:
- [fail_descr_loc] = arglocs
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
- self.mc.gen_load_int(r.ip.value, fail_descr_loc.value)
+ faildescrindex = self.get_gcref_from_faildescr(op.getdescr())
+ self.load_from_gc_table(r.ip.value, faildescrindex)
# XXX self.mov(fail_descr_loc, RawStackLoc(ofs))
self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr)
if op.numargs() > 0 and op.getarg(0).type == REF:
@@ -1035,9 +1036,9 @@
assert (guard_op.getopnum() == rop.GUARD_NOT_FORCED or
guard_op.getopnum() == rop.GUARD_NOT_FORCED_2)
faildescr = guard_op.getdescr()
+ faildescrindex = self.get_gcref_from_faildescr(faildescr)
ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
- value = rffi.cast(lltype.Signed, cast_instance_to_gcref(faildescr))
- self.mc.gen_load_int(r.ip.value, value)
+ self.load_from_gc_table(r.ip.value, faildescrindex)
self.store_reg(self.mc, r.ip, r.fp, ofs)
def _find_nearby_operation(self, delta):
@@ -1250,3 +1251,9 @@
self._load_from_mem(res_loc, res_loc, ofs_loc, imm(scale), signed,
fcond)
return fcond
+
+ def emit_op_load_from_gc_table(self, op, arglocs, regalloc, fcond):
+ res_loc, = arglocs
+ index = op.getarg(0).getint()
+ self.load_from_gc_table(res_loc.value, index)
+ return fcond
diff --git a/rpython/jit/backend/arm/regalloc.py
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -1,5 +1,4 @@
from rpython.rtyper.annlowlevel import cast_instance_to_gcref
-from rpython.rlib import rgc
from rpython.rlib.debug import debug_print, debug_start, debug_stop
from rpython.jit.backend.llsupport.regalloc import FrameManager, \
RegisterManager, TempVar, compute_vars_longevity, BaseRegalloc, \
@@ -627,16 +626,11 @@
def prepare_op_finish(self, op, fcond):
# the frame is in fp, 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 = []
return locs
def load_condition_into_cc(self, box):
@@ -892,6 +886,10 @@
prepare_op_same_as_r = _prepare_op_same_as
prepare_op_same_as_f = _prepare_op_same_as
+ def prepare_op_load_from_gc_table(self, op, fcond):
+ resloc = self.force_allocate_reg(op)
+ return [resloc]
+
def prepare_op_call_malloc_nursery(self, op, fcond):
size_box = op.getarg(0)
assert isinstance(size_box, ConstInt)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit