Commits

Maciej Fijalkowski committed 4fe6e64

call_may_force

  • Participants
  • Parent commits 9dbce99
  • Branches jitframe-on-heap

Comments (0)

Files changed (6)

File pypy/jit/backend/llsupport/gc.py

         descrs.jf_descr = cpu.fielddescrof(jitframe.JITFRAME, 'jf_descr')
         descrs.jf_guard_exc = cpu.fielddescrof(jitframe.JITFRAME,
                                                'jf_guard_exc')
+        descrs.jf_force_index = cpu.fielddescrof(jitframe.JITFRAME,
+                                                 'jf_force_index')
         descrs.jf_frame_info = cpu.fielddescrof(jitframe.JITFRAME,
                                                 'jf_frame_info')
         descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO,

File pypy/jit/backend/llsupport/jitframe.py

     # This field is also set immediately before doing CALL_MAY_FORCE
     # or CALL_ASSEMBLER.
     ('jf_descr', llmemory.GCREF),
+    # index of guard_not_force
+    ('jf_force_index', lltype.Signed),
     # For the front-end: a GCREF for the savedata
     ('jf_savedata', llmemory.GCREF),
     # For GUARD_(NO)_EXCEPTION and GUARD_NOT_FORCED: the exception we
     # exception is not stored there, but is simply kept as a variable there)
     ('jf_guard_exc', llmemory.GCREF),
     # the actual frame
-    ('jf_frame', lltype.Array(lltype.Signed, hints={'nolength': True}))
+    ('jf_frame', lltype.Array(lltype.Signed))
+    # it should be: , hints={'nolength': True})), but ll2ctypes is complaining
 )
 
 JITFRAMEPTR = lltype.Ptr(JITFRAME)

File pypy/jit/backend/llsupport/llmodel.py

         return deadframe.jf_guard_exc
 
     def set_savedata_ref(self, deadframe, data):
-        XXX
-        deadframe = lltype.cast_opaque_ptr(jitframe.DEADFRAMEPTR, deadframe)
+        deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe)
         deadframe.jf_savedata = data
 
     def get_savedata_ref(self, deadframe):
-        XXXX
-        deadframe = lltype.cast_opaque_ptr(jitframe.DEADFRAMEPTR, deadframe)
+        deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe)
         return deadframe.jf_savedata
 
     def free_loop_and_bridges(self, compiled_loop_token):

File pypy/jit/backend/x86/arch.py

 # one word for the force_index, and some extra space used only
 # during a malloc that needs to go via its slow path.
 
-# XXX FORCE_INDEX might need to go to GC frame
-
 if WORD == 4:
     # XXX rethink the fixed size
     # ebp + ebx + esi + edi + 4 extra words + force_index = 9 words
     FRAME_FIXED_SIZE = 6
-    FORCE_INDEX_OFS = 0
     SAVED_REGISTERS = 1    # range(1, 5)
     MY_COPY_OF_REGS = 5    # range(5, 9)
     XXX
 else:
     # rbp + rbx + r12 + r13 + r14 + r15 + 11 extra words + force_index = 18
     FRAME_FIXED_SIZE = 6
-    FORCE_INDEX_OFS = 0
     SAVED_REGISTERS = 1    # range(1, 7)
     MY_COPY_OF_REGS = 7    # range(7, 18)
     JITFRAME_FIXED_SIZE = 29 # 13 GPR + 16 XMM

File pypy/jit/backend/x86/assembler.py

 from pypy.jit.backend.model import CompiledLoopToken
 from pypy.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs, _get_scale,
     gpr_reg_mgr_cls, xmm_reg_mgr_cls, _valid_addressing_size)
-from pypy.jit.backend.x86.arch import (FRAME_FIXED_SIZE, FORCE_INDEX_OFS, WORD,
+from pypy.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD,
                                        IS_X86_32, IS_X86_64)
 from pypy.jit.backend.x86.regloc import (eax, ecx, edx, ebx, esp, ebp, esi, edi,
     xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, r8, r9, r10, r11,
         self.propagate_exception_path = 0
         self.gcrootmap_retaddr_forced = 0
         self.teardown()
-        self.force_token_to_dead_frame = {}    # XXX temporary hack
 
     def set_debug(self, v):
         r = self._debug
                                                      'b', descr_number)
 
         descr = self.cpu.get_fail_descr_from_number(descr_number)
-        arglocs = self.rebuild_faillocs_from_descr(descr)
+        arglocs = self.rebuild_faillocs_from_descr(descr, inputargs)
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
         startpos = self.mc.get_relative_pos()
         operations = regalloc.prepare_bridge(inputargs, arglocs,
             dst_locs.append(r10)
             x = r10
         remap_frame_layout(self, src_locs, dst_locs, X86_64_SCRATCH_REG)
-        # align
         self.mc.CALL(x)
         if align:
             self.mc.ADD_ri(esp.value, align * WORD)
         # instruction that doesn't already have a force_index.
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap and gcrootmap.is_shadow_stack:
+            xxx
             clt = self.current_clt
             force_index = clt.reserve_and_record_some_faildescr_index()
             self.mc.MOV_bi(FORCE_INDEX_OFS, force_index)
             mc.PUSH(imm(fail_index))
             mc.JMP_r(X86_64_SCRATCH_REG.value)
         # write tight data that describes the failure recovery
-        if guardtok.is_guard_not_forced:
-            XXX
-            mc.writechar(chr(self.CODE_FORCED))
         positions = [0] * len(guardtok.fail_locs)
         for i, loc in enumerate(guardtok.fail_locs):
             if loc is None:
                 positions[i] = loc.value
             else:
                 assert isinstance(loc, RegLoc)
-                v = (gpr_reg_mgr_cls.all_reg_indexes[loc.value] +
-                     loc.is_xmm * len(gpr_reg_mgr_cls.all_regs))
+                if loc.is_xmm:
+                    v = len(gpr_reg_mgr_cls.all_regs) + loc.value
+                else:
+                    v = gpr_reg_mgr_cls.all_reg_indexes[loc.value]
                 positions[i] = v * WORD
         guardtok.faildescr.rd_locs = positions
         # write fail_index too
         # for testing the decoding, write a final byte 0xCC
         return startpos
 
-    def rebuild_faillocs_from_descr(self, descr):
+    def rebuild_faillocs_from_descr(self, descr, inputargs):
         locs = []
         GPR_REGS = len(gpr_reg_mgr_cls.all_regs)
         XMM_REGS = len(xmm_reg_mgr_cls.all_regs)
+        input_i = 0
         for pos in descr.rd_locs:
             if pos == -1:
-                pass
+                continue
             elif pos < GPR_REGS * WORD:
                 locs.append(gpr_reg_mgr_cls.all_regs[pos // WORD])
             elif pos < (GPR_REGS + XMM_REGS) * WORD:
-                locs.append(xmm_reg_mgr_cls.xrm.all_regs[pos // WORD])
+                pos = pos // WORD - GPR_REGS
+                locs.append(xmm_reg_mgr_cls.all_regs[pos])
             else:
                 i = pos // WORD - 2 * self.cpu.NUM_REGS
-                tp = xxx
+                tp = inputargs[input_i].type
                 locs.append(StackLoc(i, pos, tp))
+            input_i += 1
         return locs
 
     def setup_failure_recovery(self):
                                    arglocs, result_loc):
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
-        self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)
+        descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+        base_ofs = self.cpu.unpack_arraydescr(descrs.arraydescr)
+        ofs = self.cpu.unpack_fielddescr(descrs.jf_force_index)
+        self.mc.MOV_bi(ofs - base_ofs, fail_index)
         self._genop_call(op, arglocs, result_loc, fail_index)
-        self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
-        self.implement_guard(guard_token, 'L')
+        ofs_fail = self.cpu.unpack_fielddescr(descrs.jf_descr)
+        self.mc.CMP_bi(ofs_fail - base_ofs, 0)
+        self.implement_guard(guard_token, 'NE')
 
     def genop_guard_call_release_gil(self, op, guard_op, guard_token,
                                      arglocs, result_loc):
+        xxx
         # first, close the stack in the sense of the asmgcc GC root tracker
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap:
 
     def genop_guard_call_assembler(self, op, guard_op, guard_token,
                                    arglocs, result_loc):
+        xxx
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
         self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)

File pypy/jit/backend/x86/runner.py

 from pypy.jit.codewriter import longlong
 from pypy.jit.metainterp import history, compile
 from pypy.jit.backend.x86.assembler import Assembler386
-from pypy.jit.backend.x86.arch import (FORCE_INDEX_OFS, IS_X86_32,
-                                       JITFRAME_FIXED_SIZE)
+from pypy.jit.backend.x86.arch import IS_X86_32, JITFRAME_FIXED_SIZE
 from pypy.jit.backend.x86.profagent import ProfileAgent
 from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU
 from pypy.jit.backend.llsupport import jitframe
 
     def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
                  gcdescr=None):
-        if gcdescr is not None:
-            gcdescr.force_index_ofs = FORCE_INDEX_OFS
         AbstractLLCPU.__init__(self, rtyper, stats, opts,
                                translate_support_code, gcdescr)
 
                                        immortal=True)
 
     def force(self, addr_of_force_token):
-        TP = rffi.CArrayPtr(lltype.Signed)
-        addr_of_force_index = addr_of_force_token + FORCE_INDEX_OFS
-        fail_index = rffi.cast(TP, addr_of_force_index)[0]
-        assert fail_index >= 0, "already forced!"
+        descr = self.gc_ll_descr.getframedescrs(self).arraydescr
+        ofs = self.unpack_arraydescr(descr)
+        frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token - ofs)
+        fail_index = frame.jf_force_index
         faildescr = self.get_fail_descr_from_number(fail_index)
-        rffi.cast(TP, addr_of_force_index)[0] = ~fail_index
-        frb = self.assembler._find_failure_recovery_bytecode(faildescr)
-        bytecode = rffi.cast(rffi.UCHARP, frb)
-        assert (rffi.cast(lltype.Signed, bytecode[0]) ==
-                self.assembler.CODE_FORCED)
-        bytecode = rffi.ptradd(bytecode, 1)
-        deadframe = self.assembler.grab_frame_values(
-            self,
-            bytecode,
-            addr_of_force_token,
-            self.all_null_registers)
-        assert self.get_latest_descr(deadframe) is faildescr
-        self.assembler.force_token_to_dead_frame[addr_of_force_token] = (
-            deadframe)
-        return deadframe
+        frame.jf_descr = cast_instance_to_gcref(faildescr)
+        return frame
 
     def redirect_call_assembler(self, oldlooptoken, newlooptoken):
         self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)