Author: Richard Plangger <planri...@gmail.com> Branch: s390x-backend Changeset: r81492:4fbd38846596 Date: 2015-12-29 16:36 +0100 http://bitbucket.org/pypy/pypy/changeset/4fbd38846596/
Log: added save/restore exception impl 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 @@ -423,7 +423,42 @@ return mc.materialize(self.cpu, []) def _build_stack_check_slowpath(self): - pass # TODO + _, _, slowpathaddr = self.cpu.insert_stack_check() + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: + return # no stack check (for tests, or non-translated) + # + # make a regular function that is called from a point near the start + # of an assembler function (after it adjusts the stack and saves + # registers). + mc = InstrBuilder() + # + mc.STG(r.r14, l.addr(14*WORD, r.SP)) + # Do the call + # use SP as single parameter for the call + mc.STG(r.SP, l.addr(0, r.SP)) # store the backchain + mc.AGHI(r.SP, l.imm(-STD_FRAME_SIZE_IN_BYTES)) + mc.LGR(r.r2, r.SP) + mc.load_imm(mc.RAW_CALL_REG, slowpathaddr) + mc.raw_call() + mc.AGHI(r.SP, l.imm(STD_FRAME_SIZE_IN_BYTES)) + # + # Check if it raised StackOverflow + mc.load_imm(r.SCRATCH, self.cpu.pos_exception()) + mc.LG(r.SCRATCH, l.addr(0, r.SCRATCH)) + # if this comparison is true, then everything is ok, + # else we have an exception + mc.cmp_op(r.SCRATCH, 0, imm=True) + # + # So we return to our caller, conditionally if "EQ" + mc.LG(r.r14, l.addr(14*WORD, r.SP)) + mc.BCR(c.EQ, r.r14) + # + # Else, jump to propagate_exception_path + assert self.propagate_exception_path + mc.b_abs(self.propagate_exception_path) + # + rawstart = mc.materialize(self.cpu, []) + self.stack_check_slowpath = rawstart def new_stack_loc(self, i, tp): base_ofs = self.cpu.get_baseofs_of_frame_field() @@ -573,7 +608,7 @@ self.write_pending_failure_recoveries() fullsize = self.mc.get_relative_pos() # - # TODO self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) rawstart = self.materialize_loop(original_loop_token) debug_bridge(descr_number, rawstart, codeendpos) self.patch_pending_failure_recoveries(rawstart) @@ -628,7 +663,7 @@ def propagate_memoryerror_if_r2_is_null(self): # if self.propagate_exception_path == 0 (tests), this may jump to 0 # and segfaults. too bad. the alternative is to continue anyway - # with r3==0, but that will segfault too. + # with r2==0, but that will segfault too. self.mc.cmp_op(r.r2, l.imm(0), imm=True) self.mc.load_imm(r.RETURN, self.propagate_exception_path) self.mc.BCR(c.EQ, r.RETURN) @@ -1048,6 +1083,29 @@ # exit function self._call_footer() + def _store_and_reset_exception(self, mc, excvalloc, exctploc=None): + """Reset the exception, after fetching it inside the two regs. + """ + mc.load_imm(r.r2, self.cpu.pos_exc_value()) + diff = self.cpu.pos_exception() - self.cpu.pos_exc_value() + assert check_imm_value(diff) + # Load the exception fields into the two registers + mc.load(excvalloc, r.r2, 0) + if exctploc is not None: + mc.load(exctploc, r.r2, diff) + # Zero out the exception fields + mc.LGHI(r.r0, l.imm(0)) + mc.STG(r.r0, l.addr(0, r.r2)) + mc.STG(r.r0, l.addr(diff, r.r2)) + + def _restore_exception(self, mc, excvalloc, exctploc): + mc.load_imm(r.r2, self.cpu.pos_exc_value()) + diff = self.cpu.pos_exception() - self.cpu.pos_exc_value() + assert check_imm_value(diff) + # Store the exception fields from the two registers + mc.STG(excvalloc, l.addr(0, r.r2)) + mc.STG(exctploc, l.addr(diff, r.r2)) + def load_gcmap(self, mc, reg, gcmap): # load the current gcmap into register 'reg' ptr = rffi.cast(lltype.Signed, gcmap) 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 @@ -126,6 +126,7 @@ if gcrootmap.is_shadow_stack and self.is_call_release_gil: # in this mode, RSHADOWOLD happens to contain the shadowstack # top at this point, so reuse it instead of loading it again + xxx ssreg = self.RSHADOWOLD self.asm._reload_frame_if_necessary(self.mc, shadowstack_reg=ssreg) 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 @@ -175,6 +175,16 @@ self.LGFI(dest_reg, l.imm(word & 0xFFFFffff)) self.IIHF(dest_reg, l.imm((word >> 32) & 0xFFFFffff)) + def load_imm_plus(self, dest_reg, word): + """Like load_imm(), but with one instruction less, and + leaves the loaded value off by some signed 16-bit difference. + Returns that difference.""" + diff = rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT, word)) + word -= diff + assert word & 0xFFFF == 0 + self.load_imm(dest_reg, word) + return diff + def sync(self): # see sync. section of the zarch manual! self.BCR_rr(0xf,0) 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 @@ -739,10 +739,7 @@ assert check_imm_value(diff) mc.LG(r.SCRATCH2, l.addr(diff, r.SCRATCH)) - if not loc.is_in_pool() and loc.is_imm(): - mc.cmp_op(r.SCRATCH2, loc, imm=True) - else: - mc.cmp_op(r.SCRATCH2, loc, pool=loc.is_in_pool()) + mc.cmp_op(r.SCRATCH2, loc) self.guard_success_cc = c.EQ self._emit_guard(op, failargs) @@ -752,6 +749,17 @@ mc.SG(r.SCRATCH2, l.addr(0, r.SCRATCH)) mc.SG(r.SCRATCH2, l.addr(diff, r.SCRATCH)) + def emit_save_exc_class(self, op, arglocs, regalloc): + [resloc] = arglocs + diff = self.mc.load_imm_plus(r.r2, self.cpu.pos_exception()) + self.mc.load(resloc, r.r2, diff) + + def emit_save_exception(self, op, arglocs, regalloc): + [resloc] = arglocs + self._store_and_reset_exception(self.mc, resloc) + + def emit_restore_exception(self, op, arglocs, regalloc): + self._restore_exception(self.mc, arglocs[1], arglocs[0]) class MemoryOpAssembler(object): _mixin_ = True diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py --- a/rpython/jit/backend/zarch/regalloc.py +++ b/rpython/jit/backend/zarch/regalloc.py @@ -1032,7 +1032,7 @@ return locs def prepare_guard_exception(self, op): - loc = self.ensure_reg(op.getarg(0)) + loc = self.ensure_reg(op.getarg(0), force_in_reg=True) if op in self.longevity: resloc = self.force_allocate_reg(op) else: @@ -1040,6 +1040,16 @@ arglocs = self._prepare_guard(op, [loc, resloc]) return arglocs + def prepare_save_exception(self, op): + res = self.rm.force_allocate_reg(op) + return [res] + prepare_save_exc_class = prepare_save_exception + + def prepare_restore_exception(self, op): + loc0 = self.ensure_reg(op.getarg(0), force_in_reg=True) + loc1 = self.ensure_reg(op.getarg(1), force_in_reg=True) + return [loc0, loc1] + def prepare_copystrcontent(self, op): src_ptr_loc = self.ensure_reg(op.getarg(0), force_in_reg=True) dst_ptr_loc = self.ensure_reg(op.getarg(1), force_in_reg=True) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit