[pypy-commit] pypy jitframe-on-heap: merge

fijal noreply at buildbot.pypy.org
Thu Feb 7 12:21:05 CET 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r60931:1aaead29f5ad
Date: 2013-02-07 13:20 +0200
http://bitbucket.org/pypy/pypy/changeset/1aaead29f5ad/

Log:	merge

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
@@ -96,6 +96,7 @@
         self._build_failure_recovery(exc=False, withfloats=False)
         self._build_wb_slowpath(False)
         self._build_wb_slowpath(True)
+        self._build_stack_check_failure()
         if self.cpu.supports_floats:
             self._build_wb_slowpath(False, withfloats=True)
             self._build_wb_slowpath(True, withfloats=True)
@@ -231,6 +232,7 @@
         ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
         # make sure ofs fits into a register
         assert check_imm_arg(ofs)
+        self.mc.MOV_rr(r.r0.value, r.fp.value)
         self.mc.BKPT()
         #base_ofs = self.cpu.get_baseofs_of_frame_field()
         #self.mc.MOV_bi(ofs, propagate_exception_descr)
@@ -340,6 +342,7 @@
         self.wb_slowpath[withcards + 2 * withfloats] = rawstart
 
     def _build_malloc_slowpath(self):
+        return # XXX fix me
         mc = ARMv7Builder()
         if self.cpu.supports_floats:
             vfp_regs = r.all_vfp_regs
@@ -377,15 +380,16 @@
 
     def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats,
                                 callee_only=False):
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
         if callee_only:
             regs = CoreRegisterManager.save_around_call_regs
         else:
             regs = CoreRegisterManager.all_regs
-        # use STMDB ops here
+        # XXX use STMDB ops here
         for i, gpr in enumerate(regs):
             if gpr in ignored_regs:
                 continue
-            mc.STR_ri(gpr.value, r.fp.value, i * WORD)
+            self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD)
         if withfloats:
             if callee_only:
                 regs = VFPRegisterManager.save_around_call_regs
@@ -394,8 +398,36 @@
             for i, vfpr in enumerate(regs):
                 if vfpr in ignored_regs:
                     continue
-                # add the offset of the gpr_regs
-                mc.VSTR(vfpr.value, r.fp.value, imm=i * DOUBLE_WORD)
+                ofs = len(CoreRegisterManager.all_regs) * WORD
+                ofs += i * DOUBLE_WORD + base_ofs
+                self.store_reg(mc, vfpr, r.fp, ofs)
+
+    def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats,
+                                 callee_only=False):
+        # Pop all general purpose registers
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        if callee_only:
+            regs = CoreRegisterManager.save_around_call_regs
+        else:
+            regs = CoreRegisterManager.all_regs
+        # XXX use LDMDB ops here
+        for i, gpr in enumerate(regs):
+            if gpr in ignored_regs:
+                continue
+            ofs = i * WORD + base_ofs
+            self.load_reg(mc, gpr, r.fp, ofs)
+        if withfloats:
+            # Pop all XMM regs
+            if callee_only:
+                regs = VFPRegisterManager.save_around_call_regs
+            else:
+                regs = VFPRegisterManager.all_regs
+            for i, vfpr in enumerate(regs):
+                if vfpr in ignored_regs:
+                    continue
+                ofs = len(CoreRegisterManager.all_regs) * WORD
+                ofs += i * DOUBLE_WORD + base_ofs
+                self.load_reg(mc, vfpr, r.fp, ofs)
 
     def _build_failure_recovery(self, exc, withfloats=False):
         mc = ARMv7Builder()
@@ -434,8 +466,8 @@
 
         # set return value
         assert check_imm_arg(base_ofs)
-        mc.SUB_ri(r.r0.value, r.fp.value, base_ofs)
-
+        mc.MOV_rr(r.r0.value, r.fp.value)
+        #
         self.gen_func_epilog(mc)
         rawstart = mc.materialize(self.cpu.asmmemmgr, [])
         self.failure_recovery_code[exc + 2 * withfloats] = rawstart
@@ -547,10 +579,8 @@
         self.mc.SUB_ri(r.sp.value, r.sp.value, WORD) # for the force index
         assert stack_size % 8 == 0 # ensure we keep alignment
 
-        # set fp to point to the JITFRAME + ofs
-        ofs = self.cpu.get_baseofs_of_frame_field()
-        assert check_imm_arg(ofs)
-        self.mc.ADD_ri(r.fp.value, r.r0.value, imm=ofs)
+        # set fp to point to the JITFRAME
+        self.mc.MOV_rr(r.fp.value, r.r0.value)
         #
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap and gcrootmap.is_shadow_stack:
@@ -703,40 +733,38 @@
         arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
 
         regalloc = Regalloc(assembler=self)
+        startpos = self.mc.get_relative_pos()
         operations = regalloc.prepare_bridge(inputargs, arglocs,
                                              operations,
                                              self.current_clt.allgcrefs,
                                              self.current_clt.frame_info)
 
-        #sp_patch_location = self._prepare_sp_patch_position()
+        stack_check_patch_ofs = self._check_frame_depth(self.mc,
+                                                       regalloc.get_gcmap())
 
-        startpos = self.mc.get_relative_pos()
-
-        frame_depth = self._assemble(regalloc, inputargs, operations)
+        frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations)
 
         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)
 
         # patch the jump from original guard
         self.patch_trace(faildescr, original_loop_token,
                                     rawstart, regalloc)
 
         if not we_are_translated():
-            # for the benefit of tests
-            faildescr._arm_bridge_frame_depth = frame_depth
             if log:
                 self.mc._dump_trace(rawstart, 'bridge.asm')
+
+        ops_offset = self.mc.ops_offset
         frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
-                          frame_depth + JITFRAME_FIXED_SIZE)
-        ops_offset = self.mc.ops_offset
+                          frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+        self.fixup_target_tokens(rawstart)
+        self.update_frame_depth(frame_depth)
         self.teardown()
 
         debug_start("jit-backend-addr")
@@ -767,6 +795,108 @@
             input_i += 1
         return locs
 
+    def check_frame_before_jump(self, target_token):
+        if target_token in self.target_tokens_currently_compiling:
+            return
+        if target_token._arm_clt is self.current_clt:
+            return
+        # We can have a frame coming from god knows where that's
+        # passed to a jump to another loop. Make sure it has the
+        # correct depth
+        expected_size = target_token._arm_clt.frame_info.jfi_frame_depth
+        self._check_frame_depth(self.mc, self._regalloc.get_gcmap(),
+                                expected_size=expected_size)
+
+
+    def _check_frame_depth(self, mc, gcmap, expected_size=-1):
+        """ check if the frame is of enough depth to follow this bridge.
+        Otherwise reallocate the frame in a helper.
+        There are other potential solutions
+        to that, but this one does not sound too bad.
+        """
+        descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+        ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        mc.gen_load_int(r.ip.value, ofs)
+        mc.SUB_ri(r.ip.value, r.ip.value, base_ofs)
+        stack_check_cmp_ofs = mc.currpos()
+        if expected_size == -1:
+            mc.gen_load_int(r.lr.value, 0xffffff)
+        else:
+            mc.gen_load_int(r.lr.value, expected_size)
+        mc.CMP_rr(r.ip.value, r.lr.value)
+
+        jg_location = mc.currpos()
+        mc.BKPT()
+
+        self.push_gcmap(mc, gcmap, push=True)
+
+        # the size value is still stored in lr
+        mc.PUSH([r.lr.value])
+
+        self.mc.BL(self._stack_check_failure)
+
+        # patch jg_location above
+        currpos = self.mc.currpos()
+        pmc = OverwritingBuilder(mc, jg_location, WORD)
+        pmc.B_offs(currpos, c.GE)
+
+        return stack_check_cmp_ofs
+
+    def _build_stack_check_failure(self):
+        # this code should do the following steps
+        # a) store all registers in the jitframe
+        # b) fish for the arguments passed by the caller
+        # c) store the gcmap in the jitframe
+        # d) call realloc_frame
+        # e) set the fp to point to the new jitframe
+        # f) store the address of the new jitframe in the shadowstack
+        # c) set the gcmap field to 0 in the new jitframe
+        # g) restore registers and return
+        mc = ARMv7Builder()
+        self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats)
+        # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame
+        # and the expected_size pushed in _check_stack_frame
+        # pop the values passed on the stack, gcmap -> r0, expected_size -> r1
+        mc.POP([r.r0.value, r.r1.value])
+        # store return address and keep the stack aligned
+        mc.PUSH([r.ip.value, r.lr.value])
+
+        # store the current gcmap(r1) in the jitframe
+        gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
+        assert check_imm_arg(abs(gcmap_ofs))
+        mc.STR_ri(r.r1.value, r.fp.value, imm=gcmap_ofs)
+
+        # set first arg, which is the old jitframe address
+        mc.MOV_rr(r.r0.value, r.fp.value)
+        # call realloc_frame, it takes two arguments
+        # arg0: the old jitframe
+        # arg1: the new size
+        mc.BL(self.cpu.realloc_frame)
+        # set fp to the new jitframe plus the baseofs
+        mc.ADD_ri(r.fp.value, r.r0.value)
+
+        gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+        if gcrootmap and gcrootmap.is_shadow_stack:
+            self._load_shadowstack_top(mc, r.r5, gcrootmap)
+            # store the new jitframe addr in the shadowstack
+            mc.STR_ri(r.r0.value, r.r5.value, imm=-WORD)
+
+        # reset the jf_gcmap field in the jitframe
+        mc.gen_load_int(r.ip.value, 0)
+        mc.STR_ri(r.ip.value, r.fp.value, imm=gcmap_ofs)
+
+        # restore registers
+        self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats)
+        mc.POP([r.ip.value, r.pc.value]) # return
+        self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, [])
+
+    def _load_shadowstack_top(self, mc, reg, gcrootmap):
+        rst = gcrootmap.get_root_stack_top_addr()
+        self.mc.gen_load_int(reg.value, rst)
+        self.mc.gen_load_int(reg.value, reg.value)
+        return rst
+
     def fixup_target_tokens(self, rawstart):
         for targettoken in self.target_tokens_currently_compiling:
             targettoken._arm_loop_code += rawstart
@@ -966,6 +1096,46 @@
         faildescr._arm_failure_recovery_block = 0
 
     # regalloc support
+    def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+        if target.is_vfp_reg():
+            return self._load_vfp_reg(mc, target, base, ofs, cond)
+        elif target.is_reg():
+            return self._load_core_reg(mc, target, base, ofs, cond)
+
+    def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+        if check_imm_arg(ofs):
+            mc.VLDR(target.value, base.value, imm=ofs, cond=cond)
+        else:
+            mc.gen_load_int(helper.value, ofs)
+            mc.VLDR(target.value, base.value, helper.value, cond=cond)
+
+    def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
+        if check_imm_arg(ofs):
+            mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond)
+        else:
+            mc.gen_load_int(helper.value, ofs)
+            mc.LDR_rr(target.value, base.value, helper.value, cond=cond)
+
+    def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+        if source.is_vfp_reg():
+            return self._store_vfp_reg(mc, source, base, ofs, cond)
+        else:
+            return self._store_core_reg(mc, source, base, ofs, cond)
+
+    def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+        if check_imm_arg(ofs):
+            mc.VSTR(source.value, base.value, imm=ofs, cond=cond)
+        else:
+            mc.gen_load_int(helper.value, ofs)
+            mc.VSTR(source.value, base.value, helper.value, cond=cond)
+
+    def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
+        if check_imm_arg(ofs):
+            mc.STR_ri(source.value, base.value, imm=ofs, cond=cond)
+        else:
+            gen_load_int(helper.value, ofs)
+            mc.STR_rr(source.value, base.value, helper.value, cond=cond)
+
     def load(self, loc, value):
         assert (loc.is_reg() and value.is_imm()
                     or loc.is_vfp_reg() and value.is_imm_float())
@@ -1269,6 +1439,7 @@
         mc.MOV_bi(ofs, 0)
 
 
+
 def not_implemented(msg):
     os.write(2, '[ARM/asm] %s\n' % msg)
     raise NotImplementedError(msg)
diff --git a/rpython/jit/backend/arm/locations.py b/rpython/jit/backend/arm/locations.py
--- a/rpython/jit/backend/arm/locations.py
+++ b/rpython/jit/backend/arm/locations.py
@@ -136,5 +136,5 @@
     return ImmLocation(i)
 
 
-def get_fp_offset(position):
-    return WORD * (position + JITFRAME_FIXED_SIZE)
+def get_fp_offset(base_ofs, position):
+    return base_ofs + WORD * (position + JITFRAME_FIXED_SIZE)
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
@@ -22,6 +22,7 @@
 from rpython.jit.backend.arm.regalloc import TempInt, TempPtr
 from rpython.jit.backend.arm.locations import imm
 from rpython.jit.backend.llsupport import symbolic, jitframe
+from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.descr import InteriorFieldDescr
 from rpython.jit.metainterp.history import (Box, AbstractFailDescr,
                                             INT, FLOAT, REF)
@@ -67,8 +68,8 @@
                 if loc.is_reg():
                     val = loc.value
                 else:
-                    assert 0, 'ffuu, implement'
-                    val = loc.value // WORD
+                    assert loc.is_stack()
+                    val = JITFRAME_FIXED_SIZE + loc.value
                 gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
         return gcmap
 
@@ -234,7 +235,7 @@
             self.mc.NOP()
         else:
             self.mc.BKPT()
-        gcmap = self.allocate_gcmap(arglocs[0].value)
+        gcmap = allocate_gcmap(self, arglocs[0].value, JITFRAME_FIXED_SIZE)
         self.pending_guards.append(GuardToken(gcmap,
                                     descr,
                                     failargs=op.getfailargs(),
@@ -247,19 +248,6 @@
                                     fcond=fcond))
         return c.AL
 
-    def allocate_gcmap(self, frame_depth):
-        size = frame_depth + JITFRAME_FIXED_SIZE
-        malloc_size = (size // WORD // 8 + 1) + 1
-        rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size,
-                                                        WORD)
-        # set the length field
-        rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1
-        gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap)
-        # zero the area
-        for i in range(malloc_size - 1):
-            gcmap[i] = r_uint(0)
-        return gcmap
-
     def _emit_guard_overflow(self, guard, failargs, fcond):
         if guard.getopnum() == rop.GUARD_OVERFLOW:
             fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False)
@@ -344,6 +332,7 @@
         # stack locations both before and after the jump.
         #
         target_token = op.getdescr()
+        target = target_token._arm_loop_code
         assert isinstance(target_token, TargetToken)
         assert fcond == c.AL
         my_nbargs = self.current_clt._debug_nbargs
@@ -352,31 +341,26 @@
 
         self._insert_checks()
         if target_token in self.target_tokens_currently_compiling:
-            self.mc.B_offs(target_token._arm_loop_code, fcond)
+            self.mc.B_offs(target, fcond)
         else:
-            self.mc.B(target_token._arm_loop_code, fcond)
+            self.mc.B(target, fcond)
         return fcond
 
     def emit_op_finish(self, op, arglocs, regalloc, fcond):
-        base_ofs = self.cpu.get_baseofs_of_frame_field() - WORD
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
         if len(arglocs) == 2:
             [return_val, fail_descr_loc] = arglocs
-            if op.getarg(0).type == FLOAT:
-                self.mc.VSTR(return_val.value, r.fp.value)#, imm=-base_ofs)
-            else:
-                self.mc.STR_ri(return_val.value, r.fp.value)#, imm=-base_ofs)
-            #self.save_into_mem(raw_stack(0), return_val, imm(size))
+            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')
-        base_ofs = self.cpu.get_baseofs_of_frame_field()
 
         self.mc.gen_load_int(r.ip.value, fail_descr_loc.value)
         # XXX self.mov(fail_descr_loc, RawStackLoc(ofs))
-        self.mc.STR_ri(r.ip.value, r.fp.value, imm=ofs)
+        self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr)
         gcmap = self.gcmap_for_finish
         self.push_gcmap(self.mc, gcmap, store=True)
-        self.mc.SUB_ri(r.r0.value, r.fp.value, base_ofs)
+        self.mc.MOV_rr(r.r0.value, r.fp.value)
         # exit function
         self.gen_func_epilog()
         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,6 @@
 from rpython.rtyper.annlowlevel import llhelper, 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, TempBox, compute_vars_longevity
 from rpython.jit.backend.arm import registers as r
@@ -15,7 +16,7 @@
                                                     )
 from rpython.jit.backend.arm.jump import remap_frame_layout_mixed
 from rpython.jit.backend.arm.arch import MY_COPY_OF_REGS
-from rpython.jit.backend.arm.arch import WORD
+from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE
 from rpython.jit.codewriter import longlong
 from rpython.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr,
                                         Box, BoxPtr,
@@ -23,6 +24,7 @@
 from rpython.jit.metainterp.history import JitCellToken, TargetToken
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.backend.llsupport.descr import ArrayDescr
+from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport import symbolic
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
@@ -61,12 +63,12 @@
 
 class ARMFrameManager(FrameManager):
 
-    def __init__(self):
+    def __init__(self, base_ofs):
         FrameManager.__init__(self)
+        self.base_ofs = base_ofs
 
-    @staticmethod
-    def frame_pos(i, box_type):
-        return locations.StackLocation(i, get_fp_offset(i), box_type)
+    def frame_pos(self, i, box_type):
+        return locations.StackLocation(i, get_fp_offset(self.base_ofs, i), box_type)
 
     @staticmethod
     def frame_size(type):
@@ -282,8 +284,9 @@
             return self.vfprm.convert_to_imm(value)
 
     def _prepare(self, inputargs, operations, allgcrefs):
-        self.frame_manager = self.fm = ARMFrameManager()
         cpu = self.assembler.cpu
+        self.fm = ARMFrameManager(cpu.get_baseofs_of_frame_field())
+        self.frame_manager = self.fm
         operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
                                                        allgcrefs)
         # compute longevity of variables
@@ -350,6 +353,30 @@
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
 
+    def get_gcmap(self, forbidden_regs=[], noregs=False):
+        frame_depth = self.fm.get_frame_depth()
+        gcmap = allocate_gcmap(self.assembler,
+                        frame_depth, JITFRAME_FIXED_SIZE)
+        debug_start("jit-backend-gcmap")
+        for box, loc in self.rm.reg_bindings.iteritems():
+            if loc in forbidden_regs:
+                continue
+            if box.type == REF:
+                assert not noregs
+                assert isinstance(loc, RegLoc)
+                val = gpr_reg_mgr_cls.all_reg_indexes[loc.value]
+                gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
+        for box, loc in self.fm.bindings.iteritems():
+            if box.type == REF:
+                assert isinstance(loc, StackLoc)
+                val = loc.value // WORD
+                gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
+        for i in range(len(gcmap)):
+            debug_print(str(gcmap[i]))
+        debug_stop('jit-backend-gcmap')
+        return gcmap
+
+    # ------------------------------------------------------------
     def perform_llong(self, op, args, fcond):
         return self.assembler.regalloc_emit_llong(op, args, fcond, self)
     
@@ -767,6 +794,7 @@
             else:
                 src_locations2.append(src_loc)
                 dst_locations2.append(dst_loc)
+        self.assembler.check_frame_before_jump(self.jump_target_descr)
         remap_frame_layout_mixed(self.assembler,
                                  src_locations1, dst_locations1, tmploc,
                                  src_locations2, dst_locations2, vfptmploc)
diff --git a/rpython/jit/backend/llsupport/gcmap.py b/rpython/jit/backend/llsupport/gcmap.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/gcmap.py
@@ -0,0 +1,20 @@
+from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import lltype
+from rpython.jit.backend.llsupport import jitframe
+from rpython.rlib.rarithmetic import r_uint
+from rpython.jit.backend.llsupport.symbolic import WORD
+from rpython.rlib.debug import debug_print
+
+def allocate_gcmap(assembler, frame_depth, fixed_size):
+    size = frame_depth + fixed_size
+    malloc_size = (size // WORD // 8 + 1) + 1
+    rawgcmap = assembler.datablockwrapper.malloc_aligned(WORD * malloc_size,
+                                                    WORD)
+    debug_print("gcmap: %x, len %d" % (rawgcmap, malloc_size - 1))
+    # set the length field
+    rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1
+    gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap)
+    # zero the area
+    for i in range(malloc_size - 1):
+        gcmap[i] = r_uint(0)
+    return gcmap
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -11,7 +11,8 @@
 from rpython.jit.backend.llsupport.descr import (
     get_size_descr, get_field_descr, get_array_descr,
     get_call_descr, get_interiorfield_descr,
-    FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr)
+    FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr,
+    FLAG_POINTER, FLAG_FLOAT)
 from rpython.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
 from rpython.annotator import model as annmodel
 
@@ -46,8 +47,25 @@
             self._setup_exception_handling_untranslated()
         self.asmmemmgr = AsmMemoryManager()
         self._setup_frame_realloc(translate_support_code)
+        ad = self.gc_ll_descr.getframedescrs(self).arraydescr
+        self.signedarraydescr = ad
+        # the same as normal JITFRAME, however with an array of pointers
+        self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr,
+                                        FLAG_POINTER)
+        self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr,
+                                          FLAG_FLOAT)
         self.setup()
 
+    def getarraydescr_for_frame(self, type, index):
+        if type == history.FLOAT:
+            descr = self.floatarraydescr
+        elif type == history.REF:
+            descr = self.refarraydescr
+        else:
+            descr = self.signedarraydescr
+        return JITFRAME_FIXED_SIZE + index, descr
+
+
     def setup(self):
         pass
 
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -2,6 +2,7 @@
 import sys, os
 from rpython.jit.backend.llsupport import symbolic, jitframe
 from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
+from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.metainterp.history import Const, Box, BoxInt, ConstInt
 from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
 from rpython.jit.metainterp.history import JitCellToken
@@ -1845,26 +1846,11 @@
                guard_opnum == rop.GUARD_NOT_FORCED)
         is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED
         is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED
-        gcmap = self.allocate_gcmap(frame_depth)
+        gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
         return GuardToken(gcmap, faildescr, failargs,
                           fail_locs, exc, frame_depth,
                           is_guard_not_invalidated, is_guard_not_forced)
 
-    def allocate_gcmap(self, frame_depth):
-        size = frame_depth + JITFRAME_FIXED_SIZE
-        malloc_size = (size // WORD // 8 + 1) + 1
-        rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size,
-                                                        WORD)
-        debug_print("gcmap: %x, len %d for %d" % (rawgcmap, malloc_size - 1,
-                                                  self.mc.get_relative_pos()))
-        # set the length field
-        rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1
-        gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap)
-        # zero the area
-        for i in range(malloc_size - 1):
-            gcmap[i] = r_uint(0)
-        return gcmap
-
     def generate_propagate_error_64(self):
         assert WORD == 8
         startpos = self.mc.get_relative_pos()
diff --git a/rpython/jit/backend/x86/runner.py b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -13,8 +13,6 @@
 from rpython.jit.backend.llsupport import jitframe
 from rpython.jit.backend.x86 import regloc
 from rpython.jit.backend.llsupport.symbolic import WORD
-from rpython.jit.backend.llsupport.descr import ArrayDescr, FLAG_POINTER,\
-     FLAG_FLOAT
 
 import sys
 
@@ -48,23 +46,6 @@
 
         self.profile_agent = profile_agent
 
-        ad = self.gc_ll_descr.getframedescrs(self).arraydescr
-        self.signedarraydescr = ad
-        # the same as normal JITFRAME, however with an array of pointers
-        self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr,
-                                        FLAG_POINTER)
-        self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr,
-                                          FLAG_FLOAT)
-
-    def getarraydescr_for_frame(self, type, index):
-        if type == history.FLOAT:
-            descr = self.floatarraydescr
-        elif type == history.REF:
-            descr = self.refarraydescr
-        else:
-            descr = self.signedarraydescr
-        return JITFRAME_FIXED_SIZE + index, descr
-
     def set_debug(self, flag):
         return self.assembler.set_debug(flag)
 


More information about the pypy-commit mailing list