[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