[pypy-commit] pypy vmprof-newstack: some progress on the JIT front - it's still unfinished, but we have a working test

fijal pypy.commits at gmail.com
Fri Jan 8 11:36:55 EST 2016


Author: fijal
Branch: vmprof-newstack
Changeset: r81628:09a93ad62225
Date: 2016-01-08 18:36 +0200
http://bitbucket.org/pypy/pypy/changeset/09a93ad62225/

Log:	some progress on the JIT front - it's still unfinished, but we have
	a working test

diff --git a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
@@ -0,0 +1,65 @@
+
+import os
+from rpython.jit.backend.test.support import CCompiledMixin
+from rpython.rlib.jit import JitDriver
+from rpython.tool.udir import udir
+from rpython.jit.backend.detect_cpu import getcpuclass
+
+class CompiledVmprofTest(CCompiledMixin):
+    CPUClass = getcpuclass()
+
+    def test_vmprof(self):
+        from rpython.rlib import rvmprof
+
+        class MyCode:
+            pass
+        def get_name(code):
+            return 'py:code:52:x'
+        try:
+            rvmprof.register_code_object_class(MyCode, get_name)
+        except rvmprof.VMProfPlatformUnsupported, e:
+            py.test.skip(str(e))
+
+        driver = JitDriver(greens = ['code'], reds = ['i', 's', 'num'])
+
+        @rvmprof.vmprof_execute_code("xcode13", lambda code, num: code)
+        def main(code, num):
+            return main_jitted(code, num)
+
+        def main_jitted(code, num):
+            s = 0
+            i = 0
+            while i < num:
+                driver.jit_merge_point(code=code, i=i, s=s, num=num)
+                s += (i << 1)
+                if s % 32423423423 and s > 0 == 0:
+                    print s
+                i += 1
+            return s
+
+        tmpfilename = str(udir.join('test_rvmprof'))
+
+        def f(num):
+            code = MyCode()
+            rvmprof.register_code(code, get_name)
+            fd = os.open(tmpfilename, os.O_WRONLY | os.O_CREAT, 0666)
+            period = 0.0001
+            rvmprof.enable(fd, period)
+            res = main(code, num)
+            #assert res == 499999500000
+            rvmprof.disable()
+            os.close(fd)
+            return 0
+        
+        def check_vmprof_output(self):
+            from vmprof import read_profile
+            tmpfile = str(udir.join('test_rvmprof'))
+            stats = read_profile(tmpfile)
+
+        self.meta_interp(f, [100000000])
+        try:
+            import vmprof
+        except ImportError:
+            pass
+        else:
+            check_vmprof_output()
\ No newline at end of file
diff --git a/rpython/jit/backend/test/test_rvmprof.py b/rpython/jit/backend/test/test_rvmprof.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/test/test_rvmprof.py
@@ -0,0 +1,44 @@
+
+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.jit.backend.x86.arch import WORD
+from rpython.jit.codewriter.policy import JitPolicy
+
+class BaseRVMProfTest(object):
+    def test_one(self):
+        visited = []
+
+        def helper():
+            stackp = _get_vmprof().cintf.vmprof_address_of_global_stack()[0]
+            if stackp:
+                # not during tracing
+                stack = rffi.cast(rffi.CArrayPtr(lltype.Signed), stackp)
+                visited.append(rffi.cast(rffi.CArrayPtr(lltype.Signed), stack[1] - WORD)[0])
+            else:
+                visited.append(0)
+
+        llfn = llhelper(lltype.Ptr(lltype.FuncType([], lltype.Void)), helper)
+
+        driver = jit.JitDriver(greens=[], reds='auto')
+
+        def f(n):
+            i = 0
+            while i < n:
+                driver.jit_merge_point()
+                i += 1
+                llfn()
+
+        class Hooks(jit.JitHookInterface):
+            def after_compile(self, debug_info):
+                self.raw_start = debug_info.asminfo.rawstart
+
+        hooks = Hooks()
+
+        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
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
+    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof
     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
+    FRAME_FIXED_SIZE = 19 + 4 # 4 for vmprof
     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
@@ -12,7 +12,7 @@
 from rpython.jit.metainterp.compile import ResumeGuardDescr
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 from rpython.rtyper import rclass
 from rpython.rlib.jit import AsmInfo
 from rpython.jit.backend.model import CompiledLoopToken
@@ -40,6 +40,7 @@
 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):
@@ -837,9 +838,23 @@
             frame_depth = max(frame_depth, target_frame_depth)
         return frame_depth
 
+    def _call_header_vmprof(self):
+        stack = _get_vmprof().cintf.vmprof_address_of_global_stack()
+        self.mc.MOV_rr(eax.value, esp.value)
+        self.mc.ADD_ri(eax.value, (FRAME_FIXED_SIZE - 4) * WORD) # er makes no sense
+        # next
+        self.mc.MOV(ecx, heap(stack))
+        self.mc.MOV_mr((eax.value, 0), ecx.value)
+        # value
+        self.mc.MOV_mr((eax.value, WORD), esp.value)
+        # kind
+        self.mc.MOV_mi((eax.value, WORD * 2), VMPROF_JITTED_TAG)
+        self.mc.MOV(heap(stack), eax)
+
     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 IS_X86_64:
             self.mc.MOV_sr(THREADLOCAL_OFS, esi.value)
             self.mc.MOV_rr(ebp.value, edi.value)
diff --git a/rpython/jit/backend/x86/test/test_rvmprof.py b/rpython/jit/backend/x86/test/test_rvmprof.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/x86/test/test_rvmprof.py
@@ -0,0 +1,7 @@
+
+import py
+from rpython.jit.backend.test.test_rvmprof import BaseRVMProfTest
+from rpython.jit.backend.x86.test.test_basic import Jit386Mixin
+
+class TestFfiCall(Jit386Mixin, BaseRVMProfTest):
+    pass
\ No newline at end of file
diff --git a/rpython/jit/backend/x86/test/test_zvmprof.py b/rpython/jit/backend/x86/test/test_zvmprof.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/x86/test/test_zvmprof.py
@@ -0,0 +1,7 @@
+
+from rpython.jit.backend.llsupport.test.zrpy_vmprof_test import CompiledVmprofTest
+
+class TestZVMprof(CompiledVmprofTest):
+    
+    gcrootfinder = "shadowstack"
+    gc = "incminimark"
\ No newline at end of file
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
@@ -56,6 +56,9 @@
                                             [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)
     return CInterface(locals())
 
 
@@ -106,6 +109,8 @@
 #include "src/precommondefs.h"
 #include "vmprof_stack.h"
 
+extern vmprof_stack* vmprof_global_stack;
+
 %(type)s %(cont_name)s(%(llargs)s);
 
 %(type)s %(tramp_name)s(%(llargs)s, long unique_id)
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -11,6 +11,12 @@
 
 # ____________________________________________________________
 
+# keep in sync with vmprof_stack.h
+VMPROF_CODE_TAG = 1
+VMPROF_BLACKHOLE_TAG = 2
+VMPROF_JITTED_TAG = 3
+VMPROF_JITTING_TAG = 4
+VMPROF_GC_TAG = 5
 
 class VMProfError(Exception):
     def __init__(self, msg):
diff --git a/rpython/rlib/rvmprof/src/vmprof_main.h b/rpython/rlib/rvmprof/src/vmprof_main.h
--- a/rpython/rlib/rvmprof/src/vmprof_main.h
+++ b/rpython/rlib/rvmprof/src/vmprof_main.h
@@ -55,6 +55,15 @@
 static int opened_profile(char *interp_name);
 static void flush_codes(void);
 
+
+
+RPY_EXTERN vmprof_stack* vmprof_global_stack;
+
+RPY_EXTERN void *vmprof_address_of_global_stack(void)
+{
+    return (void*)&vmprof_global_stack;
+}
+
 RPY_EXTERN
 char *vmprof_init(int fd, double interval, char *interp_name)
 {
diff --git a/rpython/rlib/rvmprof/src/vmprof_stack.h b/rpython/rlib/rvmprof/src/vmprof_stack.h
--- a/rpython/rlib/rvmprof/src/vmprof_stack.h
+++ b/rpython/rlib/rvmprof/src/vmprof_stack.h
@@ -16,10 +16,3 @@
 // to worry too much. There is a potential for squeezing it with bit
 // patterns into one WORD, but I don't want to care RIGHT NOW, potential
 // for future optimization potential
-
-RPY_EXTERN vmprof_stack* vmprof_global_stack;
-
-RPY_EXTERN void *vmprof_address_of_global_stack(void)
-{
-    return (void*)&vmprof_global_stack;
-}


More information about the pypy-commit mailing list