[pypy-commit] pypy s390x-backend: allocating the back chain correctly, one problem when hitting a memory error, stack size would have been incorrect!
plan_rich
pypy.commits at gmail.com
Fri Feb 5 07:31:26 EST 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r82085:719886e6865e
Date: 2016-02-05 13:30 +0100
http://bitbucket.org/pypy/pypy/changeset/719886e6865e/
Log: allocating the back chain correctly, one problem when hitting a
memory error, stack size would have been incorrect!
diff --git a/rpython/jit/backend/zarch/assembler.py b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -198,6 +198,8 @@
# the RPython exception that occurred in the CALL, if any).
#
off = STD_FRAME_SIZE_IN_BYTES
+ mc.LG(r.SCRATCH, l.addr(0, r.SP))
+ mc.STG(r.SCRATCH, l.addr(-extra_stack_size, r.SP))
mc.LAY(r.SP, l.addr(-extra_stack_size, r.SP))
mc.STMG(r.r10, r.r12, l.addr(off, r.SP))
mc.STG(r.r2, l.addr(off+3*WORD, r.SP))
@@ -347,7 +349,7 @@
mc.load(r.r5, r.r5, diff)
mc.store(r.r2, r.r5, -WORD)
- self._pop_core_regs_from_jitframe(mc)
+ self._pop_core_regs_from_jitframe(mc, r.MANAGED_REGS)
self._pop_fp_regs_from_jitframe(mc)
mc.restore_link()
@@ -490,7 +492,7 @@
# Check that we don't get NULL; if we do, we always interrupt the
# current loop, as a "good enough" approximation (same as
# emit_call_malloc_gc()).
- self.propagate_memoryerror_if_r2_is_null()
+ self.propagate_memoryerror_if_r2_is_null(True)
self._pop_core_regs_from_jitframe(mc, saved_regs)
self._pop_fp_regs_from_jitframe(mc)
@@ -599,7 +601,7 @@
raise JitFrameTooDeep # XXX
for traps_pos, jmp_target in self.frame_depth_to_patch:
pmc = OverwritingBuilder(self.mc, traps_pos, 3)
- # three traps, so exactly three instructions to patch here
+ # patch 3 instructions as shown above
pmc.CGFI(r.r1, l.imm(frame_depth))
pmc.BRC(c.GE, l.imm(jmp_target - (traps_pos + 6)))
pmc.LGHI(r.r0, l.imm(frame_depth))
@@ -756,18 +758,28 @@
# sadly we cannot use LOCGHI
# it is included in some extension that seem to be NOT installed
# by default.
- self.mc.LGHI(result_loc, l.imm(1))
+ self.mc.LGHI(result_loc, l.imm(-1))
off = self.mc.XGR_byte_count + self.mc.BRC_byte_count
- self.mc.BRC(condition, l.imm(off)) # branch over LGHI
+ self.mc.BRC(condition, l.imm(off)) # branch over XGR
self.mc.XGR(result_loc, result_loc)
- def propagate_memoryerror_if_r2_is_null(self):
+ def propagate_memoryerror_if_r2_is_null(self, pop_one_stackframe=False):
# if self.propagate_exception_path == 0 (tests), this may jump to 0
# and segfaults. too bad. the alternative is to continue anyway
# with r2==0, but that will segfault too.
+ jmp_pos = self.mc.get_relative_pos()
+ # bails to propagate exception path if r2 != 0
+ self.mc.reserve_cond_jump()
+
self.mc.load_imm(r.RETURN, self.propagate_exception_path)
- self.mc.cmp_op(r.r2, l.imm(0), imm=True)
- self.mc.BCR(c.EQ, r.RETURN)
+ if pop_one_stackframe:
+ self.mc.LAY(r.SP, l.addr(STD_FRAME_SIZE_IN_BYTES, r.SP))
+ self.mc.BCR(c.ANY, r.RETURN)
+
+ currpos = self.mc.currpos()
+ pmc = OverwritingBuilder(self.mc, jmp_pos, 1)
+ pmc.CGIJ(r.r2, l.imm(0), c.EQ, l.imm(curpos - jmp_pos))
+ pmc.overwrite()
def regalloc_push(self, loc, already_pushed):
"""Pushes the value stored in loc to the stack
diff --git a/rpython/jit/backend/zarch/callbuilder.py b/rpython/jit/backend/zarch/callbuilder.py
--- a/rpython/jit/backend/zarch/callbuilder.py
+++ b/rpython/jit/backend/zarch/callbuilder.py
@@ -143,15 +143,16 @@
def emit_raw_call(self):
# always allocate a stack frame for the new function
# save the SP back chain
- self.mc.STG(r.SP, l.addr(-self.subtracted_to_sp, r.SP))
# move the frame pointer
if self.subtracted_to_sp != 0:
+ # rewrite the back chain
+ self.mc.LG(r.SCRATCH, l.addr(0, r.SP))
+ self.mc.STG(r.SCRATCH, l.addr(-self.subtracted_to_sp, r.SP))
self.mc.LAY(r.SP, l.addr(-self.subtracted_to_sp, r.SP))
self.mc.raw_call()
def restore_stack_pointer(self):
- # it must at LEAST be 160 bytes
if self.subtracted_to_sp != 0:
self.mc.LAY(r.SP, l.addr(self.subtracted_to_sp, r.SP))
diff --git a/rpython/jit/backend/zarch/codebuilder.py b/rpython/jit/backend/zarch/codebuilder.py
--- a/rpython/jit/backend/zarch/codebuilder.py
+++ b/rpython/jit/backend/zarch/codebuilder.py
@@ -218,8 +218,9 @@
self.LMG(r.r14, r.r15, l.addr(off+14*WORD, r.SP))
def push_std_frame(self, additional_bytes=0):
- self.STG(r.SP, l.addr(0, r.SP))
- self.LAY(r.SP, l.addr(-(STD_FRAME_SIZE_IN_BYTES + additional_bytes), r.SP))
+ off = (STD_FRAME_SIZE_IN_BYTES + additional_bytes)
+ self.STG(r.SP, l.addr(off, r.SP))
+ self.LAY(r.SP, l.addr(-off, r.SP))
def pop_std_frame(self, additional_bytes=0):
self.LAY(r.SP, l.addr(STD_FRAME_SIZE_IN_BYTES + additional_bytes, r.SP))
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -369,8 +369,7 @@
fcond = c.negate(fcond)
jmp_adr = self.mc.get_relative_pos()
- self.mc.trap() # patched later to a relative branch
- self.mc.write('\x00' * 4)
+ self.mc.reserve_cond_jump() # patched later to a relative branch
# save away r2, r3, r4, r5, r12 into the jitframe
should_be_saved = [
@@ -378,6 +377,7 @@
if reg in self._COND_CALL_SAVE_REGS]
self._push_core_regs_to_jitframe(self.mc, should_be_saved)
+ # load gc map into unusual location: r0
self.load_gcmap(self.mc, r.SCRATCH2, regalloc.get_gcmap())
#
# load the 0-to-4 arguments into these registers, with the address of
@@ -751,10 +751,9 @@
self._read_typeid(r.SCRATCH2, loc_object)
self.mc.load_imm(r.SCRATCH, base_type_info + infobits_offset)
assert shift_by == 0
- self.mc.AGR(r.SCRATCH, r.SCRATCH2)
- self.mc.LLGC(r.SCRATCH2, l.addr(0, r.SCRATCH))
- self.mc.LGHI(r.SCRATCH, l.imm(IS_OBJECT_FLAG & 0xff))
- self.mc.NGR(r.SCRATCH2, r.SCRATCH)
+ self.mc.LGR(r.SCRATCH, r.SCRATCH2)
+ self.mc.LLGC(r.SCRATCH2, l.addr(0, r.SCRATCH)) # cannot use r.r0 as index reg
+ self.mc.NILL(r.SCRATCH2, l.imm(IS_OBJECT_FLAG & 0xff))
self.guard_success_cc = c.NE
self._emit_guard(op, arglocs[1:])
More information about the pypy-commit
mailing list