Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60034:03cc0f5a43b2
Date: 2013-01-13 19:12 +0200
http://bitbucket.org/pypy/pypy/changeset/03cc0f5a43b2/
Log: after much fighting, pass call_assembler test, still not perfect
though
diff --git a/pypy/jit/backend/llsupport/rewrite.py
b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -158,9 +158,9 @@
None, descr=descrs.jf_frame_info)
self.newops.append(op2)
for i, arg in enumerate(op.getarglist()):
- descr = self.cpu.getarraydescr_for_frame(arg.type, i)
+ index, descr = self.cpu.getarraydescr_for_frame(arg.type, i)
self.newops.append(ResOperation(rop.SETARRAYITEM_GC,
- [frame, ConstInt(i), arg],
+ [frame, ConstInt(index), arg],
None, descr))
self.newops.append(ResOperation(rop.CALL_ASSEMBLER, [frame],
op.result, op.getdescr()))
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py
b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -102,8 +102,8 @@
def getarraydescr_for_frame(self, tp, index):
if tp == history.FLOAT:
- return self.floatframedescr
- return self.signedframedescr
+ return index, self.floatframedescr
+ return index, self.signedframedescr
def arraydescrof(self, ARRAY):
try:
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -14,12 +14,13 @@
from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.annlowlevel import llhelper, cast_instance_to_gcref
from pypy.rpython.llinterp import LLException
from pypy.jit.codewriter import heaptracker, longlong
from pypy.rlib import longlong2float
from pypy.rlib.rarithmetic import intmask, is_valid_int
from pypy.jit.backend.detect_cpu import autodetect_main_model_and_size
+from pypy.jit.backend.llsupport import jitframe
def boxfloat(x):
@@ -2756,12 +2757,17 @@
def test_assembler_call(self):
called = []
- def assembler_helper(deadframe, virtualizable):
+ def assembler_helper(failindex, deadframe, virtualizable):
+ deadframe = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR,
+ deadframe)
+ faildescr = self.cpu.get_fail_descr_from_number(failindex)
+ deadframe.jf_descr = cast_instance_to_gcref(faildescr)
assert self.cpu.get_int_value(deadframe, 0) == 97
called.append(self.cpu.get_latest_descr(deadframe))
return 4 + 9
- FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.GCREF],
+ FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF,
+ llmemory.GCREF],
lltype.Signed))
class FakeJitDriverSD:
index_of_virtualizable = -1
diff --git a/pypy/jit/backend/x86/assembler.py
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -12,8 +12,8 @@
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, WORD,
- IS_X86_32, IS_X86_64)
+from pypy.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD, IS_X86_64,
+ JITFRAME_FIXED_SIZE, IS_X86_32)
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,
r12, r13, r14, r15, X86_64_SCRATCH_REG, X86_64_XMM_SCRATCH_REG,
@@ -509,8 +509,7 @@
looppos = self.mc.get_relative_pos()
looptoken._x86_loop_code = looppos
frame_depth = self._assemble(regalloc, operations)
- clt.frame_depth = frame_depth
- clt.frame_info.jfi_frame_depth = frame_depth
+ clt.frame_info.jfi_frame_depth = frame_depth + JITFRAME_FIXED_SIZE
#
size_excluding_failure_stuff = self.mc.get_relative_pos()
self.write_pending_failure_recoveries()
@@ -583,8 +582,8 @@
self.patch_jump_for_descr(faildescr, rawstart)
ops_offset = self.mc.ops_offset
self.fixup_target_tokens(rawstart)
- frame_depth = max(self.current_clt.frame_depth, frame_depth)
- self.current_clt.frame_depth = frame_depth
+ frame_depth = max(self.current_clt.frame_depth,
+ frame_depth + JITFRAME_FIXED_SIZE)
self.current_clt.frame_info.jfi_frame_depth = frame_depth
self.teardown()
# oprofile support
@@ -741,7 +740,7 @@
frame_depth = regalloc.get_final_frame_depth()
jump_target_descr = regalloc.jump_target_descr
if jump_target_descr is not None:
- target_frame_depth = jump_target_descr._x86_clt.frame_depth
+ target_frame_depth =
jump_target_descr._x86_clt.frame_info.frame_depth
frame_depth = max(frame_depth, target_frame_depth)
return frame_depth
@@ -825,6 +824,7 @@
self.mc.SUB_mi8((ebx.value, 0), 2*WORD) # SUB [ebx], 2*WORD
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
+ xxx
# some minimal sanity checking
old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs
new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs
@@ -1958,19 +1958,28 @@
srcloc = eax
self.load_from_mem(eax, srcloc, sizeloc, signloc)
- def genop_guard_call_may_force(self, op, guard_op, guard_token,
- arglocs, result_loc):
+ def _store_force_index(self, guard_op):
faildescr = guard_op.getdescr()
fail_index = self.cpu.get_fail_descr_number(faildescr)
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)
+ return fail_index
+
+ def _emit_guard_not_forced(self, guard_token):
+ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+ base_ofs = self.cpu.unpack_arraydescr(descrs.arraydescr)
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_may_force(self, op, guard_op, guard_token,
+ arglocs, result_loc):
+ fail_index = self._store_force_index(guard_op)
+ self._genop_call(op, arglocs, result_loc, fail_index)
+ self._emit_guard_not_forced()
+
def genop_guard_call_release_gil(self, op, guard_op, guard_token,
arglocs, result_loc):
# first, close the stack in the sense of the asmgcc GC root tracker
@@ -1978,20 +1987,13 @@
if gcrootmap:
self.call_release_gil(gcrootmap, arglocs)
# do the call
- faildescr = guard_op.getdescr()
- fail_index = self.cpu.get_fail_descr_number(faildescr)
- 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)
+ fail_index = self._store_force_index(guard_op)
self._genop_call(op, arglocs, result_loc, fail_index)
# then reopen the stack
if gcrootmap:
self.call_reacquire_gil(gcrootmap, result_loc)
# finally, the guard_not_forced
- ofs_fail = self.cpu.unpack_fielddescr(descrs.jf_descr)
- self.mc.CMP_bi(ofs_fail - base_ofs, 0)
- self.implement_guard(guard_token, 'NE')
+ self._emit_guard_not_forced(guard_token)
def call_release_gil(self, gcrootmap, save_registers):
# First, we need to save away the registers listed in
@@ -2096,17 +2098,16 @@
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)
+ fail_index = self._store_force_index(guard_op)
descr = op.getdescr()
assert isinstance(descr, JitCellToken)
- assert len(arglocs) - 2 == descr.compiled_loop_token._debug_nbargs
+ frame_loc = arglocs[0]
#
# Write a call to the target assembler
+ # we need to allocate the frame, keep in sync with runner's
+ # execute_token
self._emit_call(fail_index, imm(descr._x86_function_addr),
- arglocs, 2, tmp=eax)
+ [frame_loc], 0, tmp=eax)
if op.result is None:
assert result_loc is None
value = self.cpu.done_with_this_frame_void_v
@@ -2123,19 +2124,7 @@
else:
raise AssertionError(kind)
- from pypy.jit.backend.llsupport.descr import unpack_fielddescr
- from pypy.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)
- if rx86.fits_in_32bits(value):
- self.mc.CMP_mi((eax.value, _offset), value)
- else:
- self.mc.MOV_ri(X86_64_SCRATCH_REG.value, value)
- self.mc.CMP_mr((eax.value, _offset), X86_64_SCRATCH_REG.value)
+ self.mc.CMP_ri(eax.value, 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()
@@ -2144,8 +2133,8 @@
jd = descr.outermost_jitdriver_sd
assert jd is not None
asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
- self._emit_call(fail_index, imm(asm_helper_adr), [eax, arglocs[1]], 0,
- tmp=ecx)
+ self._emit_call(fail_index, imm(asm_helper_adr),
+ [eax, frame_loc, imm0], 0, tmp=ecx)
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
@@ -2159,6 +2148,7 @@
#
# Reset the vable token --- XXX really too much special logic here:-(
if jd.index_of_virtualizable >= 0:
+ xxx
from pypy.jit.backend.llsupport.descr import FieldDescr
fielddescr = jd.vable_token_descr
assert isinstance(fielddescr, FieldDescr)
@@ -2169,26 +2159,26 @@
#
if op.result is not None:
# load the return value from the dead frame's value index 0
+ assert isinstance(frame_loc, StackLoc)
+ self.mc.MOV_rb(eax.value, frame_loc.value)
kind = op.result.type
if kind == FLOAT:
+ xxx
t = unpack_interiorfielddescr(descrs.as_float)
self.mc.MOVSD_xm(xmm0.value, (eax.value, t[0]))
if result_loc is not xmm0:
self.mc.MOVSD(result_loc, xmm0)
else:
assert result_loc is eax
- if kind == INT:
- t = unpack_interiorfielddescr(descrs.as_int)
- else:
- t = unpack_interiorfielddescr(descrs.as_ref)
- self.mc.MOV_rm(eax.value, (eax.value, t[0]))
+ _, descr = self.cpu.getarraydescr_for_frame(kind, 0)
+ ofs = self.cpu.unpack_arraydescr(descr)
+ self.mc.MOV_rm(eax.value, (eax.value, ofs))
#
# Here we join Path A and Path B again
offset = self.mc.get_relative_pos() - jmp_location
assert 0 <= offset <= 127
self.mc.overwrite(jmp_location - 1, chr(offset))
- self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
- self.implement_guard(guard_token, 'L')
+ self._emit_guard_not_forced(guard_token)
def genop_discard_cond_call_gc_wb(self, op, arglocs):
# Write code equivalent to write_barrier() in the GC: it checks
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -936,17 +936,13 @@
descr = op.getdescr()
assert isinstance(descr, JitCellToken)
jd = descr.outermost_jitdriver_sd
- assert jd is not None
- size = jd.portal_calldescr.get_result_size()
+ # we attached a frame as a first arg, move index of virtualizable by
one
vable_index = jd.index_of_virtualizable
+ self.rm._sync_var(op.getarg(0))
+ frame_loc = self.fm.loc(op.getarg(0))
if vable_index >= 0:
- self.rm._sync_var(op.getarg(vable_index))
- vable = self.fm.loc(op.getarg(vable_index))
- else:
- vable = imm0
- self._call(op, [imm(size), vable] +
- [self.loc(op.getarg(i)) for i in range(op.numargs())],
- guard_not_forced_op=guard_op)
+ xxx
+ self._call(op, [frame_loc], guard_not_forced_op=guard_op)
def consider_cond_call_gc_wb(self, op):
assert op.result is None
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -112,9 +112,10 @@
addr = executable_token._x86_function_addr
func = rffi.cast(FUNCPTR, addr)
#llop.debug_print(lltype.Void, ">>>> Entering", addr)
- frame = lltype.malloc(jitframe.JITFRAME, clt.frame_depth +
- JITFRAME_FIXED_SIZE, zero=True)
- frame.jf_frame_info = clt.frame_info
+ frame_info = clt.frame_info
+ frame = lltype.malloc(jitframe.JITFRAME,
frame_info.jfi_frame_depth,
+ zero=True)
+ frame.jf_frame_info = frame_info
ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame)
prev_interpreter = None # help flow space
if not self.translate_support_code:
@@ -231,4 +232,11 @@
assert sys.maxint == (2**63 - 1)
super(CPU_X86_64, self).__init__(*args, **kwargs)
+ def getarraydescr_for_frame(self, type, index):
+ if type != history.INT:
+ xxx
+ else:
+ descrs = self.gc_ll_descr.getframedescrs(self)
+ return JITFRAME_FIXED_SIZE + index, descrs.arraydescr
+
CPU = CPU386
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -658,7 +658,7 @@
else:
assert False
(_, jd._PTR_ASSEMBLER_HELPER_FUNCTYPE) = self.cpu.ts.get_FuncType(
- [llmemory.GCREF, llmemory.GCREF], ASMRESTYPE)
+ [lltype.Signed, llmemory.GCREF, llmemory.GCREF], ASMRESTYPE)
def rewrite_can_enter_jits(self):
sublists = {}
@@ -927,9 +927,12 @@
vinfo = jd.virtualizable_info
- def assembler_call_helper(deadframe, virtualizableref):
+ def assembler_call_helper(failindex, deadframe, virtualizableref):
+ XXX # we got failindex, but the descr is not stored on the frame
+ # yet, it's our job
fail_descr = self.cpu.get_latest_descr(deadframe)
if vinfo is not None:
+ xxx
virtualizable = lltype.cast_opaque_ptr(
vinfo.VTYPEPTR, virtualizableref)
vinfo.reset_vable_token(virtualizable)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit