[pypy-commit] pypy default: 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
plan_rich
pypy.commits at gmail.com
Tue Apr 12 05:47:56 EDT 2016
Author: Richard Plangger <planrichi at 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):
More information about the pypy-commit
mailing list