Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r62091:8186fc9d56d0
Date: 2013-03-05 17:18 +0200
http://bitbucket.org/pypy/pypy/changeset/8186fc9d56d0/
Log: a bit more consistent debug checking of frame depth
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
@@ -103,6 +103,9 @@
print "Unhandled exception", e, "in realloc_frame"
return lltype.nullptr(llmemory.GCREF.TO)
+ def realloc_frame_crash(frame, size):
+ print "frame", frame, "size", size
+
if not translate_support_code:
fptr = llhelper(FUNC_TP, realloc_frame)
else:
@@ -115,6 +118,18 @@
mixlevelann.finish()
self.realloc_frame =
heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr))
+ if not translate_support_code:
+ fptr = llhelper(FUNC_TP, realloc_frame_crash)
+ else:
+ FUNC = FUNC_TP.TO
+ args_s = [annmodel.lltype_to_annotation(ARG) for ARG in FUNC.ARGS]
+ s_result = annmodel.lltype_to_annotation(FUNC.RESULT)
+ mixlevelann = MixLevelHelperAnnotator(self.rtyper)
+ graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result)
+ fptr = mixlevelann.graph2delayed(graph, FUNC)
+ mixlevelann.finish()
+ self.realloc_frame_crash =
heaptracker.adr2int(llmemory.cast_ptr_to_adr(fptr))
+
def _setup_exception_handling_untranslated(self):
# for running un-translated only, all exceptions occurring in the
# llinterpreter are stored in '_exception_emulator', which is then
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,8 @@
_output_loop_log = None
_second_tmp_reg = ecx
+ DEBUG_FRAME_DEPTH = True
+
def __init__(self, cpu, translate_support_code=False):
BaseAssembler.__init__(self, cpu, translate_support_code)
self.verbose = False
@@ -92,6 +94,7 @@
self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
allblocks)
self.target_tokens_currently_compiling = {}
+ self.frame_depth_to_patch = []
def teardown(self):
self.pending_guard_tokens = None
@@ -480,6 +483,7 @@
regalloc = RegAlloc(self, self.cpu.translate_support_code)
#
self._call_header_with_stack_check()
+ self._check_frame_depth_debug(self.mc)
operations = regalloc.prepare_loop(inputargs, operations, looptoken,
clt.allgcrefs)
looppos = self.mc.get_relative_pos()
@@ -492,6 +496,8 @@
full_size = self.mc.get_relative_pos()
#
rawstart = self.materialize_loop(looptoken)
+ self.patch_stack_checks(frame_depth_no_fixed_size +
JITFRAME_FIXED_SIZE,
+ rawstart)
looptoken._ll_loop_code = looppos + rawstart
debug_start("jit-backend-addr")
debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" %
(
@@ -539,14 +545,15 @@
operations,
self.current_clt.allgcrefs,
self.current_clt.frame_info)
- stack_check_patch_ofs, ofs2 = self._check_frame_depth(self.mc,
- regalloc.get_gcmap())
+ self._check_frame_depth(self.mc, regalloc.get_gcmap())
frame_depth_no_fixed_size = self._assemble(regalloc, inputargs,
operations)
codeendpos = self.mc.get_relative_pos()
self.write_pending_failure_recoveries()
fullsize = self.mc.get_relative_pos()
#
rawstart = self.materialize_loop(original_loop_token)
+ self.patch_stack_checks(frame_depth_no_fixed_size +
JITFRAME_FIXED_SIZE,
+ rawstart)
debug_start("jit-backend-addr")
debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" %
(r_uint(descr_number), r_uint(rawstart),
@@ -558,8 +565,6 @@
ops_offset = self.mc.ops_offset
frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
- self._patch_stackadjust(stack_check_patch_ofs + rawstart, frame_depth)
- self._patch_stackadjust(ofs2 + rawstart, frame_depth)
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
self.teardown()
@@ -624,6 +629,10 @@
baseofs = self.cpu.get_baseofs_of_frame_field()
self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth)
+ def patch_stack_checks(self, framedepth, rawstart):
+ for ofs in self.frame_depth_to_patch:
+ self._patch_frame_depth(ofs + rawstart, framedepth)
+
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.
@@ -650,9 +659,33 @@
offset = mc.get_relative_pos() - jg_location
assert 0 < offset <= 127
mc.overwrite(jg_location-1, chr(offset))
- return stack_check_cmp_ofs, ofs2
+ self.frame_depth_to_patch.append(stack_check_cmp_ofs)
+ self.frame_depth_to_patch.append(ofs2)
- def _patch_stackadjust(self, adr, allocated_depth):
+ def _check_frame_depth_debug(self, mc):
+ """ double check the depth size. It prints the error (and potentially
+ segfaults later)
+ """
+ if not self.DEBUG_FRAME_DEPTH:
+ return
+ descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+ ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
+ mc.CMP_bi(ofs, 0xffffff)
+ stack_check_cmp_ofs = mc.get_relative_pos() - 4
+ mc.J_il8(rx86.Conditions['GE'], 0)
+ jg_location = mc.get_relative_pos()
+ mc.MOV_rr(edi.value, ebp.value)
+ mc.MOV_ri(esi.value, 0xffffff)
+ ofs2 = mc.get_relative_pos() - 4
+ mc.CALL(imm(self.cpu.realloc_frame_crash))
+ # patch the JG above
+ offset = mc.get_relative_pos() - jg_location
+ assert 0 < offset <= 127
+ mc.overwrite(jg_location-1, chr(offset))
+ self.frame_depth_to_patch.append(stack_check_cmp_ofs)
+ self.frame_depth_to_patch.append(ofs2)
+
+ def _patch_frame_depth(self, adr, allocated_depth):
mc = codebuf.MachineCodeBlockWrapper()
mc.writeimm32(allocated_depth)
mc.copy_to_raw_memory(adr)
@@ -2401,7 +2434,7 @@
self.mc.JMP(imm(target))
def label(self):
- pass
+ self._check_frame_depth_debug(self.mc)
def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
assert size & (WORD-1) == 0 # must be correctly aligned
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit