[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