[pypy-commit] pypy stackroot-speedup-2: Untested code

arigo noreply at buildbot.pypy.org
Wed Feb 4 19:43:27 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stackroot-speedup-2
Changeset: r75710:1c9c0cc23c80
Date: 2015-02-04 19:01 +0100
http://bitbucket.org/pypy/pypy/changeset/1c9c0cc23c80/

Log:	Untested code

diff --git a/rpython/jit/backend/x86/arch.py b/rpython/jit/backend/x86/arch.py
--- a/rpython/jit/backend/x86/arch.py
+++ b/rpython/jit/backend/x86/arch.py
@@ -35,7 +35,9 @@
     PASS_ON_MY_FRAME = 15
     JITFRAME_FIXED_SIZE = 6 + 8 * 2 # 6 GPR + 8 XMM * 2 WORDS/float
     # 'threadlocal_addr' is passed as 2nd argument on the stack,
-    # and it can be left here for when it is needed
+    # and it can be left here for when it is needed.  As an additional hack,
+    # with asmgcc, it is made odd-valued to mean "already seen this frame
+    # during the previous minor collection".
     THREADLOCAL_OFS = (FRAME_FIXED_SIZE + 2) * WORD
 else:
     # rbp + rbx + r12 + r13 + r14 + r15 + threadlocal + 12 extra words = 19
@@ -43,7 +45,9 @@
     PASS_ON_MY_FRAME = 12
     JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM
     # 'threadlocal_addr' is passed as 2nd argument in %esi,
-    # and is moved into this frame location
+    # and is moved into this frame location.  As an additional hack,
+    # with asmgcc, it is made odd-valued to mean "already seen this frame
+    # during the previous minor collection".
     THREADLOCAL_OFS = (FRAME_FIXED_SIZE - 1) * WORD
 
 assert PASS_ON_MY_FRAME >= 12       # asmgcc needs at least JIT_USE_WORDS + 3
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
@@ -1980,6 +1980,23 @@
 
     def _call_assembler_emit_call(self, addr, argloc, _):
         threadlocal_loc = RawEspLoc(THREADLOCAL_OFS, INT)
+        if self._is_asmgcc():
+            # We need to remove the bit "already seen during the
+            # previous minor collection" instead of passing this
+            # value directly.
+            if IS_X86_64:
+                tmploc = esi    # already the correct place
+                if argloc is tmploc:
+                    self.mc.MOV_rr(esi.value, edi.value)
+                    argloc = edi
+            else:
+                tmploc = eax
+                if tmploc is argloc:
+                    tmploc = edx
+            self.mc.MOV(tmploc, threadlocal_ofs)
+            self.mc.AND_ri(tmploc.value, ~1)
+            threadlocal_ofs = tmploc
+        #
         self.simple_call(addr, [argloc, threadlocal_loc])
 
     def _call_assembler_emit_helper_call(self, addr, arglocs, result_loc):
@@ -2355,6 +2372,8 @@
         assert self.cpu.translate_support_code
         assert isinstance(resloc, RegLoc)
         self.mc.MOV_rs(resloc.value, THREADLOCAL_OFS)
+        if self._is_asmgcc():
+            self.mc.AND_ri(resloc.value, ~1)
         self.load_from_mem(resloc, addr_add_const(resloc, offset),
                            imm(size), imm(sign))
 
diff --git a/rpython/jit/backend/x86/callbuilder.py b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -167,6 +167,8 @@
                 self.tlofs_reg = r12
             self.mc.MOV_rs(self.tlofs_reg.value,
                            THREADLOCAL_OFS - self.current_esp)
+            if self.asm._is_asmgcc():
+                self.mc.AND_ri(self.tlofs_reg.value, ~1)
         return self.tlofs_reg
 
     def save_stack_position(self):
diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py
--- a/rpython/memory/gctransform/asmgcroot.py
+++ b/rpython/memory/gctransform/asmgcroot.py
@@ -343,6 +343,7 @@
     def walk_stack_roots(self, collect_stack_root, is_minor=False):
         gcdata = self.gcdata
         gcdata._gc_collect_stack_root = collect_stack_root
+        gcdata._gc_collect_is_minor = is_minor
         pypy_asm_stackwalk(llhelper(ASM_CALLBACK_PTR, self._asm_callback),
                            gcrootanchor)
 
@@ -477,6 +478,14 @@
             addr = self.getlocation(callee, ebp_in_caller, location)
             caller.regs_stored_at[reg] = addr
             reg -= 1
+        #
+        # small hack: the JIT reserves THREADLOCAL_OFS's last bit for
+        # us.  We use it to store an "already traced past this frame"
+        # flag.
+        if self._with_jit:
+            is_minor = self.gcdata._gc_collect_is_minor
+            if self.mark_jit_frame_can_stop(callee, is_minor):
+                return False
 
         location = self._shape_decompressor.next()
         caller.frame_address = self.getlocation(callee, ebp_in_caller,
@@ -548,6 +557,23 @@
         else:  # kind == LOC_EBP_MINUS:   at -N(%ebp)
             return ebp_in_caller - offset
 
+    def mark_jit_frame_can_stop(self, callee, is_minor):
+        location = self._shape_decompressor.get_threadlocal_loc()
+        if location == LOC_NOWHERE:
+            return False
+        addr = self.getlocation(callee, llmemory.NULL, location)
+        #
+        x = addr.signed[0]
+        if is_minor:
+            if x & 1:
+                return True            # this JIT stack frame is already marked!
+            else:
+                addr.signed[0] = x | 1    # otherwise, mark it but don't stop
+                return False
+        else:
+            addr.signed[0] = x & ~1    # 'is_minor' is False, remove the marks
+            return False
+
 
 LOC_REG       = 0
 LOC_ESP_PLUS  = 1
@@ -729,6 +755,19 @@
             llop.debug_fatalerror(lltype.Void, "asmgcroot: invalid index")
             return 0   # annotator fix
 
+    def get_threadlocal_loc(self):
+        index = self.jit_index
+        if index < 0:
+            return LOC_NOWHERE     # case "outside the jit"
+        else:
+            # case "in the jit"
+            from rpython.jit.backend.x86.arch import THREADLOCAL_OFS
+            from rpython.jit.backend.x86.arch import PASS_ON_MY_FRAME
+            stack_depth = PASS_ON_MY_FRAME + self.extra_stack_depth
+            return (LOC_ESP_PLUS |
+                    ((THREADLOCAL_OFS // WORD + self.extra_stack_depth) << 2))
+
+
 # ____________________________________________________________
 
 #


More information about the pypy-commit mailing list