[pypy-commit] pypy jitframe-on-heap: work on stack check failure, failing to call it so far
fijal
noreply at buildbot.pypy.org
Tue Jan 15 12:24:19 CET 2013
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r60081:2a740e45803a
Date: 2013-01-15 13:23 +0200
http://bitbucket.org/pypy/pypy/changeset/2a740e45803a/
Log: work on stack check failure, failing to call it so far
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -45,11 +45,24 @@
else:
self._setup_exception_handling_untranslated()
self.asmmemmgr = AsmMemoryManager()
+ self._setup_frame_realloc()
self.setup()
def setup(self):
pass
+ def _setup_frame_realloc(self):
+ FUNC_TP = lltype.Ptr(lltype.FuncType([llmemory.GCREF],
+ llmemory.GCREF))
+
+ def realloc_frame(frame):
+ frame = lltype.cast_opaque_ptr(jitframe.JITFRAME, frame)
+ import pdb
+ pdb.set_trace()
+ return frame
+
+ f = llhelper(FUNC_TP, realloc_frame)
+ self.realloc_frame = heaptracker.adr2int(llmemory.cast_ptr_to_adr(f))
def _setup_exception_handling_untranslated(self):
# for running un-translated only, all exceptions occurring in the
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
@@ -3766,7 +3766,8 @@
EffectInfo.MOST_GENERAL)
def func2(a, b, c, d, e, f, g, h, i, j, k, l):
- pass
+ import pdb
+ pdb.set_trace()
FUNC2 = self.FuncType([lltype.Signed] * 12, lltype.Void)
FPTR2 = self.Ptr(FUNC2)
diff --git a/pypy/jit/backend/x86/arch.py b/pypy/jit/backend/x86/arch.py
--- a/pypy/jit/backend/x86/arch.py
+++ b/pypy/jit/backend/x86/arch.py
@@ -51,7 +51,7 @@
JITFRAME_FIXED_SIZE = 29 # 13 GPR + 16 XMM
# reg, we don't save it
else:
- # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 18
+ # rbp + rbx + r12 + r13 + r14 + r15 + 12 extra words + return address = 19
FRAME_FIXED_SIZE = 19
PASS_ON_MY_FRAME = 12
JITFRAME_FIXED_SIZE = 29 # 13 GPR + 16 XMM
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
@@ -94,6 +94,7 @@
self._build_failure_recovery(True)
self._build_wb_slowpath(False)
self._build_wb_slowpath(True)
+ self._build_stack_check_failure()
if self.cpu.supports_floats:
self._build_failure_recovery(False, withfloats=True)
self._build_failure_recovery(True, withfloats=True)
@@ -167,6 +168,19 @@
self.float_const_neg_addr = float_constants
self.float_const_abs_addr = float_constants + 16
+ def _build_stack_check_failure(self):
+ mc = codebuf.MachineCodeBlockWrapper()
+ base_ofs = self.cpu.get_baseofs_of_frame_field()
+ self._push_all_regs_to_frame(mc, self.cpu.supports_floats)
+ assert not IS_X86_32
+ # push first arg
+ mc.LEA_rb(edi.value, -base_ofs)
+ mc.CALL(imm(self.cpu.realloc_frame))
+ mc.LEA_rm(ebp.value, (eax.value, base_ofs))
+ self._pop_all_regs_from_frame(mc, self.cpu.supports_floats)
+ mc.RET()
+ self._stack_check_failure = mc.materialize(self.cpu.asmmemmgr, [])
+
def _build_malloc_slowpath(self):
# With asmgcc, we need two helpers, so that we can write two CALL
# instructions in assembler, with a mark_gc_roots in between.
@@ -571,7 +585,7 @@
operations = regalloc.prepare_bridge(inputargs, arglocs,
operations,
self.current_clt.allgcrefs)
- self._check_frame_depth()
+ stack_check_patch_ofs = self._check_frame_depth()
frame_depth = self._assemble(regalloc, operations)
codeendpos = self.mc.get_relative_pos()
self.write_pending_failure_recoveries()
@@ -589,9 +603,10 @@
# patch the jump from original guard
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_info.jfi_frame_depth,
frame_depth + JITFRAME_FIXED_SIZE)
+ self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth)
+ self.fixup_target_tokens(rawstart)
self.current_clt.frame_info.jfi_frame_depth = frame_depth
self.teardown()
# oprofile support
@@ -652,8 +667,21 @@
mc.copy_to_raw_memory(rawstart + pos_after_jz - 4)
def _check_frame_depth(self):
- pass
+ 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()
+ self.mc.CMP_bi(ofs - base_ofs, 0xffffff)
+ stack_check_cmp_ofs = self.mc.get_relative_pos() - 4
+ assert not IS_X86_32
+ self.mc.J_il8(rx86.Conditions['G'], 9)
+ self.mc.CALL(imm(self._stack_check_failure))
+ return stack_check_cmp_ofs
+ def _patch_stackadjust(self, adr, allocated_depth):
+ mc = codebuf.MachineCodeBlockWrapper()
+ mc.writeimm32(allocated_depth)
+ mc.copy_to_raw_memory(adr)
+
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
if clt.asmmemmgr_blocks is None:
@@ -1858,13 +1886,31 @@
def setup_failure_recovery(self):
self.failure_recovery_code = [0, 0, 0, 0]
+ def _push_all_regs_to_frame(self, mc, withfloats):
+ # Push all general purpose registers
+ for i, gpr in enumerate(gpr_reg_mgr_cls.all_regs):
+ mc.MOV_br(i * WORD, gpr.value)
+ if withfloats:
+ # Push all XMM regs
+ ofs = len(gpr_reg_mgr_cls.all_regs)
+ for i in range(self.cpu.NUM_REGS):
+ mc.MOVSD_bx((ofs + i) * WORD, i)
+
+ def _pop_all_regs_from_frame(self, mc, withfloats):
+ # Pop all general purpose registers
+ for i, gpr in enumerate(gpr_reg_mgr_cls.all_regs):
+ mc.MOV_rb(gpr.value, i * WORD)
+ if withfloats:
+ # Pop all XMM regs
+ ofs = len(gpr_reg_mgr_cls.all_regs)
+ for i in range(self.cpu.NUM_REGS):
+ mc.MOVSD_xb(i, (ofs + i) * WORD)
+
def _build_failure_recovery(self, exc, withfloats=False):
mc = codebuf.MachineCodeBlockWrapper()
self.mc = mc
- # Push all general purpose registers
- for i, gpr in enumerate(gpr_reg_mgr_cls.all_regs):
- mc.MOV_br(i * WORD, gpr.value)
+ self._push_all_regs_to_frame(mc, withfloats)
if exc:
# We might have an exception pending. Load it into ebx
@@ -1872,13 +1918,6 @@
mc.MOV(ebx, heap(self.cpu.pos_exc_value()))
mc.MOV(heap(self.cpu.pos_exception()), imm0)
mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
-
- if withfloats:
- ofs = len(gpr_reg_mgr_cls.all_regs)
- for i in range(self.cpu.NUM_REGS):
- mc.MOVSD_bx((ofs + i) * WORD, i)
-
- if exc:
# save ebx into 'jf_guard_exc'
offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
mc.MOV_br(offset, ebx.value)
@@ -2007,12 +2046,14 @@
# first, close the stack in the sense of the asmgcc GC root tracker
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap:
+ xxx
self.call_release_gil(gcrootmap, arglocs)
# do the call
fail_index = self._store_force_index(guard_op)
self._genop_call(op, arglocs, result_loc, fail_index)
# then reopen the stack
if gcrootmap:
+ xxx
self.call_reacquire_gil(gcrootmap, result_loc)
# finally, the guard_not_forced
self._emit_guard_not_forced(guard_token)
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
@@ -212,14 +212,10 @@
self.min_bytes_before_label = max(self.min_bytes_before_label,
at_least_position)
- def needed_extra_stack_locations(self, n):
- # call *after* you needed extra stack locations: (%esp), (%esp+4)...
- min_frame_depth = self.fm.get_frame_depth() + n
+ def get_final_frame_depth(self):
+ min_frame_depth = self.fm.get_frame_depth()
if min_frame_depth > self.min_frame_depth:
self.min_frame_depth = min_frame_depth
-
- def get_final_frame_depth(self):
- self.needed_extra_stack_locations(0) # update min_frame_depth
return self.min_frame_depth
def _set_initial_bindings(self, inputargs):
diff --git a/pypy/jit/backend/x86/test/test_runner.py b/pypy/jit/backend/x86/test/test_runner.py
--- a/pypy/jit/backend/x86/test/test_runner.py
+++ b/pypy/jit/backend/x86/test/test_runner.py
@@ -34,7 +34,7 @@
# ====> ../../test/runner_test.py
add_loop_instructions = ['mov', 'add', 'test', 'je', 'jmp']
- bridge_loop_instructions = ['mov', 'jmp']
+ bridge_loop_instructions = ['cmp', 'jg', 'mov', 'call', 'mov', 'jmp']
def setup_method(self, meth):
self.cpu = CPU(rtyper=None, stats=FakeStats())
More information about the pypy-commit
mailing list