[pypy-commit] pypy jitframe-on-heap: uh, fix the bug

fijal noreply at buildbot.pypy.org
Mon Jan 21 08:43:17 CET 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r60269:ef194d2932d8
Date: 2013-01-21 09:42 +0200
http://bitbucket.org/pypy/pypy/changeset/ef194d2932d8/

Log:	uh, fix the bug

diff --git a/pypy/TODO b/pypy/TODO
--- a/pypy/TODO
+++ b/pypy/TODO
@@ -1,6 +1,8 @@
 
 * 32bit x86
 * ARM
-* shadowstack + asmgcc
+* shadowstack + asmgcc (shadowstack needs reloading of ebp after frame
+  got potentially moved, which is after each potentially collecting call
+  or slowpath malloc)
 * kill jit2gc on translator
 * fix test_singlefloats in test_calling_conventions
\ No newline at end of file
diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -1,4 +1,5 @@
 from rpython.rlib.rarithmetic import ovfcheck
+from rpython.rlib import rgc
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.jit.metainterp import history
 from rpython.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr
@@ -142,6 +143,7 @@
         lgt_box = history.BoxInt()
         frame = history.BoxPtr()
         jfi = loop_token.compiled_loop_token.frame_info
+        rgc._make_sure_does_not_move(jfi)
         llref = lltype.cast_opaque_ptr(llmemory.GCREF, jfi)
         op0 = ResOperation(rop.GETFIELD_GC, [history.ConstPtr(llref)], lgt_box,
                            descr=descrs.jfi_frame_depth)
@@ -154,6 +156,10 @@
         op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstPtr(llref)],
                            None, descr=descrs.jf_frame_info)
         self.newops.append(op2)
+        llref = lltype.cast_opaque_ptr(llmemory.GCREF, jfi.jfi_gcmap)
+        op3 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstPtr(llref)],
+                           None, descr=descrs.jf_gcmap)
+        self.newops.append(op3)
         for i, arg in enumerate(op.getarglist()):
             index, descr = self.cpu.getarraydescr_for_frame(arg.type, i)
             self.newops.append(ResOperation(rop.SETARRAYITEM_GC,
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
@@ -556,7 +556,7 @@
                                              operations,
                                              self.current_clt.allgcrefs,
                                              self.current_clt.frame_info)
-        stack_check_patch_ofs = self._check_frame_depth()
+        stack_check_patch_ofs = self._check_frame_depth(self.mc)
         frame_depth = self._assemble(regalloc, inputargs, operations)
         codeendpos = self.mc.get_relative_pos()
         self.write_pending_failure_recoveries()
@@ -638,7 +638,7 @@
                 mc.writeimm32(self.error_trampoline_64 - pos_after_jz)
                 mc.copy_to_raw_memory(rawstart + pos_after_jz - 4)
 
-    def _check_frame_depth(self):
+    def _check_frame_depth(self, mc):
         """ check if the frame is of enough depth to follow this bridge.
         Otherwise reallocate the frame in a helper.
         There are other potential solutions
@@ -647,16 +647,16 @@
         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
+        mc.CMP_bi(ofs - base_ofs, 0xffffff)
+        stack_check_cmp_ofs = mc.get_relative_pos() - 4
         assert not IS_X86_32
-        self.mc.J_il8(rx86.Conditions['GE'], 0)
-        jg_location = self.mc.get_relative_pos()
-        self.mc.CALL(imm(self._stack_check_failure))
+        mc.J_il8(rx86.Conditions['GE'], 0)
+        jg_location = mc.get_relative_pos()
+        mc.CALL(imm(self._stack_check_failure))
         # patch the JG above
-        offset = self.mc.get_relative_pos() - jg_location
+        offset = mc.get_relative_pos() - jg_location
         assert 0 < offset <= 127
-        self.mc.overwrite(jg_location-1, chr(offset))
+        mc.overwrite(jg_location-1, chr(offset))
         return stack_check_cmp_ofs
 
     def _insert_frame_adjustment(self, frame_info):
@@ -882,6 +882,11 @@
         # Ideally we should rather patch all existing CALLs, but well.
         oldadr = oldlooptoken._x86_function_addr
         target = newlooptoken._x86_function_addr
+        # copy frame-info data
+        old_fi = oldlooptoken.compiled_loop_token.frame_info
+        new_fi = newlooptoken.compiled_loop_token.frame_info
+        old_fi.jfi_frame_depth = new_fi.jfi_frame_depth
+        old_fi.jfi_gcmap = new_fi.jfi_gcmap
         mc = codebuf.MachineCodeBlockWrapper()
         mc.JMP(imm(target))
         if WORD == 4:         # keep in sync with prepare_loop()
@@ -1857,12 +1862,12 @@
         if WORD == 4:
             mc.PUSH(imm(fail_descr))
             mc.PUSH(imm(gcpattern))
-            mc.JMP(imm(target))
+            mc.CALL(imm(target))
         else:
             mc.MOV_ri64(X86_64_SCRATCH_REG.value, target)
             mc.PUSH(imm(fail_descr))
             mc.PUSH(imm(gcpattern))
-            mc.JMP_r(X86_64_SCRATCH_REG.value)
+            self.mc.JMP_r(X86_64_SCRATCH_REG.value)
         return startpos
 
     def rebuild_faillocs_from_descr(self, descr, inputargs):


More information about the pypy-commit mailing list