[pypy-commit] pypy vmprof-newstack: Fix the jit to use thread-locals

arigo pypy.commits at gmail.com
Fri Jan 15 06:36:10 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: vmprof-newstack
Changeset: r81789:195b2ba3887b
Date: 2016-01-15 12:35 +0100
http://bitbucket.org/pypy/pypy/changeset/195b2ba3887b/

Log:	Fix the jit to use thread-locals

diff --git a/rpython/jit/backend/test/test_rvmprof.py b/rpython/jit/backend/test/test_rvmprof.py
--- a/rpython/jit/backend/test/test_rvmprof.py
+++ b/rpython/jit/backend/test/test_rvmprof.py
@@ -1,22 +1,22 @@
-
+import py
 from rpython.rlib import jit
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib.rvmprof import _get_vmprof
+from rpython.rlib.rvmprof import cintf
 from rpython.jit.backend.x86.arch import WORD
 from rpython.jit.codewriter.policy import JitPolicy
 
 class BaseRVMProfTest(object):
     def test_one(self):
+        py.test.skip("needs thread-locals in the JIT, which is only available "
+                     "after translation")
         visited = []
 
         def helper():
-            stackp = _get_vmprof().cintf.vmprof_address_of_global_stack()[0]
-            if stackp:
+            stack = cintf.vmprof_tl_stack.getraw()
+            if stack:
                 # not during tracing
-                stack = rffi.cast(rffi.CArrayPtr(lltype.Signed), stackp)
-                item = rffi.cast(rffi.CArrayPtr(lltype.Signed), stack[1] - WORD)[0]
-                visited.append(item)
+                visited.append(stack.c_value)
             else:
                 visited.append(0)
 
@@ -37,12 +37,13 @@
 
         hooks = Hooks()
 
-        stackp = _get_vmprof().cintf.vmprof_address_of_global_stack()
-        stackp[0] = 0 # make it empty
+        null = lltype.nullptr(cintf.VMPROFSTACK)
+        cintf.vmprof_tl_stack.setraw(null)   # make it empty
         self.meta_interp(f, [10], policy=JitPolicy(hooks))
         v = set(visited)
         assert 0 in v
         v.remove(0)
         assert len(v) == 1
         assert 0 <= list(v)[0] - hooks.raw_start <= 10*1024
-        assert stackp[0] == 0 # make sure we didn't leave anything dangling
+        assert cintf.vmprof_tl_stack.getraw() == null
+        # ^^^ make sure we didn't leave anything dangling
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
@@ -31,7 +31,7 @@
 
 if WORD == 4:
     # ebp + ebx + esi + edi + 15 extra words = 19 words
-    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof
+    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof, XXX make more compact!
     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,
@@ -41,7 +41,7 @@
     THREADLOCAL_OFS = (FRAME_FIXED_SIZE + 2) * WORD
 else:
     # rbp + rbx + r12 + r13 + r14 + r15 + threadlocal + 12 extra words = 19
-    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof
+    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof, XXX make more compact!
     PASS_ON_MY_FRAME = 12
     JITFRAME_FIXED_SIZE = 28 # 13 GPR + 15 XMM
     # 'threadlocal_addr' is passed as 2nd argument in %esi,
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
@@ -40,7 +40,6 @@
 from rpython.jit.codewriter import longlong
 from rpython.rlib.rarithmetic import intmask, r_uint
 from rpython.rlib.objectmodel import compute_unique_id
-from rpython.rlib.rvmprof.rvmprof import _get_vmprof, VMPROF_JITTED_TAG
 
 
 class Assembler386(BaseAssembler, VectorAssemblerMixin):
@@ -839,28 +838,49 @@
         return frame_depth
 
     def _call_header_vmprof(self):
-        stack = rffi.cast(lltype.Signed, _get_vmprof().cintf.vmprof_address_of_global_stack())
+        from rpython.rlib.rvmprof.rvmprof import cintf, VMPROF_JITTED_TAG
+
+        # tloc = address of pypy_threadlocal_s
+        if IS_X86_32:
+            # Can't use esi here, its old value is not saved yet.
+            # But we can use eax and ecx.
+            self.mc.MOV_rs(edx.value, THREADLOCAL_OFS)
+            tloc = edx
+            old = ecx
+        else:
+            # The thread-local value is already in esi.
+            # We should avoid if possible to use ecx or edx because they
+            # would be used to pass arguments #3 and #4 (even though, so
+            # far, the assembler only receives two arguments).
+            tloc = esi
+            old = r11
+        # eax = address in the stack of a 3-words struct vmprof_stack_s
         self.mc.LEA_rs(eax.value, (FRAME_FIXED_SIZE - 4) * WORD)
-        # next
-        self.mc.MOV(ecx, heap(stack))
-        self.mc.MOV_mr((eax.value, 0), ecx.value)
-        # value
+        # old = current value of vmprof_tl_stack
+        self.mc.MOV_rm(old.value, (tloc.value, cintf.vmprof_tl_stack.offset))
+        # eax->next = old
+        self.mc.MOV_mr((eax.value, 0), old.value)
+        # eax->value = my esp
         self.mc.MOV_mr((eax.value, WORD), esp.value)
-        # kind
+        # eax->kind = VMPROF_JITTED_TAG
         self.mc.MOV_mi((eax.value, WORD * 2), VMPROF_JITTED_TAG)
-        self.mc.MOV(heap(stack), eax)
+        # save in vmprof_tl_stack the new eax
+        self.mc.MOV_mr((tloc.value, cintf.vmprof_tl_stack.offset), eax.value)
 
     def _call_footer_vmprof(self):
-        stack = rffi.cast(lltype.Signed, _get_vmprof().cintf.vmprof_address_of_global_stack())
-        # *stack = stack->next
-        self.mc.MOV(eax, heap(stack))
-        self.mc.MOV_rm(eax.value, (eax.value, 0))
-        self.mc.MOV(heap(stack), eax)
+        from rpython.rlib.rvmprof.rvmprof import cintf
+        # edx = address of pypy_threadlocal_s
+        self.mc.MOV_rs(edx.value, THREADLOCAL_OFS)
+        # eax = (our local vmprof_tl_stack).next
+        self.mc.MOV_rs(eax.value, (FRAME_FIXED_SIZE - 4 + 0) * WORD)
+        # save in vmprof_tl_stack the value eax
+        self.mc.MOV_mr((edx.value, cintf.vmprof_tl_stack.offset), eax.value)
 
     def _call_header(self):
         self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD)
         self.mc.MOV_sr(PASS_ON_MY_FRAME * WORD, ebp.value)
-        self._call_header_vmprof()
+        if self.cpu.translate_support_code:
+            self._call_header_vmprof()     # on X86_64, this uses esi
         if IS_X86_64:
             self.mc.MOV_sr(THREADLOCAL_OFS, esi.value)
             self.mc.MOV_rr(ebp.value, edi.value)
@@ -894,7 +914,8 @@
 
     def _call_footer(self):
         # the return value is the jitframe
-        self._call_footer_vmprof()
+        if self.cpu.translate_support_code:
+            self._call_footer_vmprof()
         self.mc.MOV_rr(eax.value, ebp.value)
 
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -57,9 +57,6 @@
                                             [rffi.INT], lltype.Void,
                                             compilation_info=eci,
                                             _nowrapper=True)
-    vmprof_address_of_global_stack = rffi.llexternal(
-        "vmprof_address_of_global_stack", [], rffi.CArrayPtr(lltype.Signed),
-        compilation_info=eci, _nowrapper=True)
     return CInterface(locals())
 
 


More information about the pypy-commit mailing list