Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r61262:5fadcd6a778d
Date: 2013-02-15 14:37 +0200
http://bitbucket.org/pypy/pypy/changeset/5fadcd6a778d/

Log:    work on call_assembler up to the point at least

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
@@ -1100,78 +1100,48 @@
         self.mc.MOV_rr(res_loc.value, r.fp.value)
         return fcond
 
-    # from: ../x86/assembler.py:1668
-    # XXX Split into some helper methods
+    def imm(self, v):
+        return imm(v)
+    
     def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc,
-                                                                    fcond):
-        tmploc = arglocs[1]
-        resloc = arglocs[2]
-        callargs = arglocs[3:]
+                                  fcond):
+        if len(arglocs) == 4:
+            [frame_loc, argloc, vloc, tmploc] = arglocs
+        else:
+            [frame_loc, argloc, tmploc] = arglocs
+            vloc = imm(0)
+        self.call_assembler(op, guard_op, frame_loc, argloc, vloc, tmploc)
+        xxx
 
-        self._store_force_index(guard_op)
-        descr = op.getdescr()
-        assert isinstance(descr, JitCellToken)
-        # check value
-        assert tmploc is r.r0
-        self._emit_call(imm(descr._ll_function_addr),
-                                callargs, fcond, resloc=tmploc)
-        if op.result is None:
-            value = self.cpu.done_with_this_frame_void_v
-        else:
-            kind = op.result.type
-            if kind == INT:
-                value = self.cpu.done_with_this_frame_int_v
-            elif kind == REF:
-                value = self.cpu.done_with_this_frame_ref_v
-            elif kind == FLOAT:
-                value = self.cpu.done_with_this_frame_float_v
-            else:
-                raise AssertionError(kind)
-        from rpython.jit.backend.llsupport.descr import unpack_fielddescr
-        from rpython.jit.backend.llsupport.descr import 
unpack_interiorfielddescr
-        descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
-        _offset, _size, _ = unpack_fielddescr(descrs.jf_descr)
-        fail_descr = self.cpu.get_fail_descr_from_number(value)
-        value = fail_descr.hide(self.cpu)
-        rgc._make_sure_does_not_move(value)
-        value = rffi.cast(lltype.Signed, value)
+    def _call_assembler_check_descr(self, value, tmploc):
+        ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+        self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs)
+        self.mc.CMP_ri(r.ip.value, imm=value)
+        pos = self.mc.currpos()
+        self.mc.BPKT()
+        return pos
 
-        if check_imm_arg(_offset):
-            self.mc.LDR_ri(r.ip.value, tmploc.value, imm=_offset)
-        else:
-            self.mc.gen_load_int(r.ip.value, _offset)
-            self.mc.LDR_rr(r.ip.value, tmploc.value, r.ip.value)
-        if check_imm_arg(value):
-            self.mc.CMP_ri(r.ip.value, imm=value)
-        else:
-            self.mc.gen_load_int(r.lr.value, value)
-            self.mc.CMP_rr(r.lr.value, r.ip.value)
+    def _call_assembler_patch_je(self, result_loc, jmp_location):
+        pos = self.mc.currpos()
+        self.mc.BPKT()
+        pmc = OverwritingBuilder(self.mc, jmp_location, WORD)
+        pmc.B_offs(self.mc.currpos(), c.EQ)
+        return pos
 
+    def _call_assembler_reset_vtoken(self, jd, vloc):
+        from rpython.jit.backend.llsupport.descr import FieldDescr
+        fielddescr = jd.vable_token_descr
+        assert isinstance(fielddescr, FieldDescr)
+        ofs = fielddescr.offset
+        tmploc = self._regalloc.get_scratch_reg(INT)
+        self.mov_loc_loc(vloc, r.ip)
+        self.mc.MOV_ri(tmploc.value, 0)
+        self.mc.STR_ri(tmploc.value, r.ip.value, ofs)
 
-        #if values are equal we take the fast path
-        # Slow path, calling helper
-        # jump to merge point
-
-        jd = descr.outermost_jitdriver_sd
-        assert jd is not None
-
-        # Path A: load return value and reset token
-        # Fast Path using result boxes
-
-        fast_path_cond = c.EQ
-        # Reset the vable token --- XXX really too much special logic here:-(
-        if jd.index_of_virtualizable >= 0:
-            from rpython.jit.backend.llsupport.descr import FieldDescr
-            fielddescr = jd.vable_token_descr
-            assert isinstance(fielddescr, FieldDescr)
-            ofs = fielddescr.offset
-            tmploc = regalloc.get_scratch_reg(INT)
-            self.mov_loc_loc(arglocs[0], r.ip, cond=fast_path_cond)
-            self.mc.MOV_ri(tmploc.value, 0, cond=fast_path_cond)
-            self.mc.STR_ri(tmploc.value, r.ip.value, ofs, cond=fast_path_cond)
-
+    def _call_assembler_load_result(self, op, result_loc):
+        XXX
         if op.result is not None:
-            # load the return value from fail_boxes_xxx[0]
+            # load the return value from (tmploc, 0)
             kind = op.result.type
             if kind == FLOAT:
                 t = unpack_interiorfielddescr(descrs.as_float)[0]
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
@@ -1101,20 +1101,10 @@
     prepare_guard_call_release_gil = prepare_guard_call_may_force
 
     def prepare_guard_call_assembler(self, op, guard_op, fcond):
-        descr = op.getdescr()
-        assert isinstance(descr, JitCellToken)
-        jd = descr.outermost_jitdriver_sd
-        assert jd is not None
-        vable_index = jd.index_of_virtualizable
-        if vable_index >= 0:
-            self._sync_var(op.getarg(vable_index))
-            vable = self.frame_manager.loc(op.getarg(vable_index))
-        else:
-            vable = imm(0)
-        # make sure the call result location is free
         tmploc = self.get_scratch_reg(INT, selected_reg=r.r0)
+        locs = self.locs_for_call_assembler(op, guard_op)
         self.possibly_free_vars(guard_op.getfailargs())
-        return [vable, tmploc] + self._prepare_call(op, save_all_regs=True)
+        return locs + [tmploc]
 
     def _prepare_args_for_new_op(self, new_args):
         gc_ll_descr = self.cpu.gc_ll_descr
diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -1,7 +1,8 @@
 
+from rpython.rlib import rgc
 from rpython.rlib.rarithmetic import r_uint
 from rpython.jit.backend.llsupport.symbolic import WORD
-from rpython.jit.metainterp.history import REF, FLOAT
+from rpython.jit.metainterp.history import INT, REF, FLOAT, JitCellToken
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.rtyper.lltypesystem import rffi, lltype
 
@@ -100,3 +101,59 @@
         # we want the descr to keep alive
         guardtok.faildescr.rd_loop_token = self.current_clt
         return fail_descr, target
+
+    def call_assembler(self, op, guard_op, frame_loc, argloc,
+                       vloc, result_loc, tmploc):
+        self._store_force_index(guard_op)
+        descr = op.getdescr()
+        assert isinstance(descr, JitCellToken)
+        #
+        # Write a call to the target assembler
+        # we need to allocate the frame, keep in sync with runner's
+        # execute_token
+        jd = descr.outermost_jitdriver_sd
+        self._emit_call(self.imm(descr._ll_function_addr),
+                        [argloc], 0, tmp=tmploc)
+        if op.result is None:
+            assert result_loc is None
+            value = self.cpu.done_with_this_frame_descr_void
+        else:
+            kind = op.result.type
+            if kind == INT:
+                assert result_loc is tmploc
+                value = self.cpu.done_with_this_frame_descr_int
+            elif kind == REF:
+                assert result_loc is tmploc
+                value = self.cpu.done_with_this_frame_descr_ref
+            elif kind == FLOAT:
+                value = self.cpu.done_with_this_frame_descr_float
+            else:
+                raise AssertionError(kind)
+
+        gcref = cast_instance_to_gcref(value)
+        rgc._make_sure_does_not_move(gcref)
+        value = rffi.cast(lltype.Signed, gcref)
+        je_location = self._call_assembler_check_descr(value, tmploc)
+        #
+        # Path A: use assembler_helper_adr
+        assert jd is not None
+        asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
+
+        self._emit_call(self.imm(asm_helper_adr),
+                        [tmploc, vloc], 0, tmp=self._second_tmp_reg)
+
+        jmp_location = self._call_assembler_patch_je(result_loc, je_location)
+
+        # Path B: fast path.  Must load the return value, and reset the token
+
+        # Reset the vable token --- XXX really too much special logic here:-(
+        if jd.index_of_virtualizable >= 0:
+            self._call_assembler_reset_vtoken(jd, vloc)
+        #
+        self._call_assembler_load_result(op, result_loc)
+        #
+        # Here we join Path A and Path B again
+        self._call_assembler_patch_jmp(jmp_location)
+        # XXX here should be emitted guard_not_forced, but due
+        #     to incompatibilities in how it's done, we leave it for the
+        #     caller to deal with
diff --git a/rpython/jit/backend/llsupport/regalloc.py 
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -1,5 +1,5 @@
 import os
-from rpython.jit.metainterp.history import Const, Box, REF
+from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.jit.metainterp.resoperation import rop
 
@@ -667,6 +667,18 @@
             return False
         return True
 
+    def locs_for_call_assembler(self, op, guard_op):
+        descr = op.getdescr()
+        assert isinstance(descr, JitCellToken)
+        arglist = op.getarglist()
+        self.rm._sync_var(arglist[0])
+        frame_loc = self.fm.loc(op.getarg(0))
+        if len(arglist) == 2:
+            self.rm._sync_var(arglist[1])
+            return [frame_loc, self.loc(arglist[0]), self.fm.loc(arglist[1])]
+        else:
+            return [frame_loc, self.loc(arglist[0])]
+
 
 def compute_vars_longevity(inputargs, operations):
     # compute a dictionary that maps variables to index in
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
@@ -51,6 +51,7 @@
 class Assembler386(BaseAssembler):
     _regalloc = None
     _output_loop_log = None
+    _second_tmp_reg = ecx
 
     def __init__(self, cpu, translate_support_code=False):
         self.cpu = cpu
@@ -2198,76 +2199,51 @@
         if isinstance(save_loc, RegLoc) and not save_loc.is_xmm:
             self.mc.MOV_rs(save_loc.value, WORD)
 
+    def imm(self, v):
+        return imm(v)
+
+    # ------------------- CALL ASSEMBLER --------------------------
+
     def genop_guard_call_assembler(self, op, guard_op, guard_token,
                                    arglocs, result_loc):
-        self._store_force_index(guard_op)
-        descr = op.getdescr()
-        assert isinstance(descr, JitCellToken)
         if len(arglocs) == 3:
             [frame_loc, argloc, vloc] = arglocs
         else:
             [frame_loc, argloc] = arglocs
-            vloc = imm(0)
-        #
-        # Write a call to the target assembler
-        # we need to allocate the frame, keep in sync with runner's
-        # execute_token
-        jd = descr.outermost_jitdriver_sd
-        base_ofs = self.cpu.get_baseofs_of_frame_field()
-        self._emit_call(imm(descr._ll_function_addr),
-                        [argloc], 0, tmp=eax)
-        if op.result is None:
-            assert result_loc is None
-            value = self.cpu.done_with_this_frame_descr_void
-        else:
-            kind = op.result.type
-            if kind == INT:
-                assert result_loc is eax
-                value = self.cpu.done_with_this_frame_descr_int
-            elif kind == REF:
-                assert result_loc is eax
-                value = self.cpu.done_with_this_frame_descr_ref
-            elif kind == FLOAT:
-                value = self.cpu.done_with_this_frame_descr_float
-            else:
-                raise AssertionError(kind)
+            vloc = self.imm(0)
+        self.call_assembler(op, guard_op, frame_loc, argloc, vloc,
+                            result_loc, eax)
+        self._emit_guard_not_forced(guard_token)
 
-        gcref = cast_instance_to_gcref(value)
-        rgc._make_sure_does_not_move(gcref)
-        value = rffi.cast(lltype.Signed, gcref)
+    def _call_assembler_check_descr(self, value, tmploc):
         ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
         self.mc.CMP_mi((eax.value, ofs), value)
         # patched later
         self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get 
'done_with_this_frame'
-        je_location = self.mc.get_relative_pos()
-        #
-        # Path A: use assembler_helper_adr
-        assert jd is not None
-        asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
+        return self.mc.get_relative_pos()
 
-        self._emit_call(imm(asm_helper_adr),
-                        [eax, vloc], 0, tmp=ecx)
+    def _call_assembler_patch_je(self, result_loc, je_location):
         if IS_X86_32 and isinstance(result_loc, StackLoc) and result_loc.type 
== FLOAT:
             self.mc.FSTPL_b(result_loc.value)
-        #else: result_loc is already either eax or None, checked below
         self.mc.JMP_l8(0) # jump to done, patched later
         jmp_location = self.mc.get_relative_pos()
         #
-        # Path B: fast path.  Must load the return value, and reset the token
         offset = jmp_location - je_location
         assert 0 < offset <= 127
         self.mc.overwrite(je_location - 1, chr(offset))
         #
-        # Reset the vable token --- XXX really too much special logic here:-(
-        if jd.index_of_virtualizable >= 0:
-            from rpython.jit.backend.llsupport.descr import FieldDescr
-            fielddescr = jd.vable_token_descr
-            assert isinstance(fielddescr, FieldDescr)
-            vtoken_ofs = fielddescr.offset
-            self.mc.MOV(edx, vloc) # we know vloc is on the current frame
-            self.mc.MOV_mi((edx.value, vtoken_ofs), 0)
-            # in the line above, TOKEN_NONE = 0
-        #
+        return jmp_location
+
+    def _call_assembler_reset_vtoken(self, jd, vloc):
+        from rpython.jit.backend.llsupport.descr import FieldDescr
+        fielddescr = jd.vable_token_descr
+        assert isinstance(fielddescr, FieldDescr)
+        vtoken_ofs = fielddescr.offset
+        self.mc.MOV(edx, vloc) # we know vloc is on the current frame
+        self.mc.MOV_mi((edx.value, vtoken_ofs), 0)
+        # in the line above, TOKEN_NONE = 0
+
+    def _call_assembler_load_result(self, op, result_loc):
         if op.result is not None:
             # load the return value from the dead frame's value index 0
             kind = op.result.type
@@ -2282,12 +2258,13 @@
                 descr = self.cpu.getarraydescr_for_frame(kind)
                 ofs = self.cpu.unpack_arraydescr(descr)
                 self.mc.MOV_rm(eax.value, (eax.value, ofs))
-        #
-        # Here we join Path A and Path B again
+
+    def _call_assembler_patch_jmp(self, jmp_location):
         offset = self.mc.get_relative_pos() - jmp_location
         assert 0 <= offset <= 127
         self.mc.overwrite(jmp_location - 1, chr(offset))
-        self._emit_guard_not_forced(guard_token)
+
+    # ------------------- END CALL ASSEMBLER -----------------------
 
     def _write_barrier_fastpath(self, mc, descr, arglocs, array=False,
                                 is_frame=False):
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp.history import (Box, Const, ConstInt, ConstPtr,
                                             ConstFloat, BoxInt,
                                             BoxFloat, INT, REF, FLOAT,
-                                            TargetToken, JitCellToken)
+                                            TargetToken)
 from rpython.jit.backend.x86.regloc import *
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
@@ -802,16 +802,7 @@
         self._consider_call(op)
 
     def consider_call_assembler(self, op, guard_op):
-        descr = op.getdescr()
-        assert isinstance(descr, JitCellToken)
-        arglist = op.getarglist()
-        self.rm._sync_var(arglist[0])
-        frame_loc = self.fm.loc(op.getarg(0))
-        if len(arglist) == 2:
-            self.rm._sync_var(arglist[1])
-            locs = [frame_loc, self.loc(arglist[0]), self.fm.loc(arglist[1])]
-        else:
-            locs = [frame_loc, self.loc(arglist[0])]
+        locs = self.locs_for_call_assembler(op, guard_op)
         self._call(op, locs, guard_not_forced_op=guard_op)
 
     def consider_cond_call_gc_wb(self, op):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to