[pypy-commit] pypy vmprof-newstack: start working on the JIT support

fijal pypy.commits at gmail.com
Sun Jan 10 08:27:14 EST 2016


Author: fijal
Branch: vmprof-newstack
Changeset: r81651:00aa9b847f85
Date: 2016-01-10 15:26 +0200
http://bitbucket.org/pypy/pypy/changeset/00aa9b847f85/

Log:	start working on the JIT support

diff --git a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py
@@ -32,7 +32,7 @@
             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:
+                if s % 32423423423 == 0 and s > 0 == 0:
                     print s
                 i += 1
             return s
@@ -51,7 +51,7 @@
             os.close(fd)
             return 0
         
-        def check_vmprof_output(self):
+        def check_vmprof_output():
             from vmprof import read_profile
             tmpfile = str(udir.join('test_rvmprof'))
             stats = read_profile(tmpfile)
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
@@ -843,23 +843,20 @@
         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_ri(ecx.value, stack)
-        self.mc.MOV_rm(ecx.value, (ecx.value, 0))
+        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_ri(ecx.value, stack)
-        self.mc.MOV_mr((ecx.value, 0), eax.value)
+        self.mc.MOV(heap(stack), eax)
 
     def _call_footer_vmprof(self):
         stack = rffi.cast(lltype.Signed, _get_vmprof().cintf.vmprof_address_of_global_stack())
         # *stack = stack->next
-        self.mc.MOV_ri(ecx.value, stack)
-        self.mc.MOV_rm(eax.value, (ecx.value, 0))
+        self.mc.MOV(eax, heap(stack))
         self.mc.MOV_rm(eax.value, (eax.value, 0))
-        self.mc.MOV_mr((ecx.value, 0), eax.value)
+        self.mc.MOV(heap(stack), eax)
 
     def _call_header(self):
         self.mc.SUB_ri(esp.value, FRAME_FIXED_SIZE * WORD)
diff --git a/rpython/jit/backend/x86/test/test_zvmprof.py b/rpython/jit/backend/x86/test/test_zrpy_vmprof.py
copy from rpython/jit/backend/x86/test/test_zvmprof.py
copy to rpython/jit/backend/x86/test/test_zrpy_vmprof.py
diff --git a/rpython/rlib/rvmprof/src/rvmprof.h b/rpython/rlib/rvmprof/src/rvmprof.h
--- a/rpython/rlib/rvmprof/src/rvmprof.h
+++ b/rpython/rlib/rvmprof/src/rvmprof.h
@@ -7,4 +7,5 @@
 RPY_EXTERN void* vmprof_stack_new(void);
 RPY_EXTERN int vmprof_stack_append(void*, long);
 RPY_EXTERN long vmprof_stack_pop(void*);
-RPY_EXTERN void vmprof_stack_free(void*);
\ No newline at end of file
+RPY_EXTERN void vmprof_stack_free(void*);
+RPY_EXTERN void* vmprof_address_of_global_stack(void);
\ No newline at end of file
diff --git a/rpython/rlib/rvmprof/src/vmprof_get_custom_offset.h b/rpython/rlib/rvmprof/src/vmprof_get_custom_offset.h
--- a/rpython/rlib/rvmprof/src/vmprof_get_custom_offset.h
+++ b/rpython/rlib/rvmprof/src/vmprof_get_custom_offset.h
@@ -1,39 +1,32 @@
 
-#ifdef PYPY_JIT_CODEMAP
 void *pypy_find_codemap_at_addr(long addr, long *start_addr);
 long pypy_yield_codemap_at_addr(void *codemap_raw, long addr,
                                 long *current_pos_addr);
 long pypy_jit_stack_depth_at_loc(long loc);
-#endif
 
 
-#ifdef CPYTHON_GET_CUSTOM_OFFSET
-static void *tramp_start, *tramp_end;
-#endif
-
-static long vmprof_write_header_for_jit_addr(void **result, long n,
-                                             void *ip, int max_depth)
+static long vmprof_write_header_for_jit_addr(intptr_t *result, long n,
+                                             intptr_t ip, int max_depth)
 {
-#ifdef PYPY_JIT_CODEMAP
     void *codemap;
     long current_pos = 0;
     intptr_t id;
     long start_addr = 0;
     intptr_t addr = (intptr_t)ip;
     int start, k;
-    void *tmp;
+    intptr_t tmp;
 
     codemap = pypy_find_codemap_at_addr(addr, &start_addr);
-    if (codemap == NULL)
-        // not a jit code at all
+    if (codemap == NULL || n >= max_depth - 2)
+        // not a jit code at all or almost max depth
         return n;
 
     // modify the last entry to point to start address and not the random one
     // in the middle
-    result[n - 1] = (void*)start_addr;
-    result[n] = (void*)2;
-    n++;
-    start = n;
+    result[n] = VMPROF_ASSEMBLER_TAG;
+    result[n + 1] = start_addr;
+    n += 2;
+    start = n + 2;
     while (n < max_depth) {
         id = pypy_yield_codemap_at_addr(codemap, addr, &current_pos);
         if (id == -1)
@@ -41,7 +34,8 @@
             break;
         if (id == 0)
             continue; // not main codemap
-        result[n++] = (void *)id;
+        result[n++] = VMPROF_JITTED_TAG;
+        result[n++] = id;
     }
     k = 0;
     while (k < (n - start) / 2) {
@@ -50,9 +44,5 @@
         result[n - k - 1] = tmp;
         k++;
     }
-    if (n < max_depth) {
-        result[n++] = (void*)3;
-    }
-#endif
     return n;
 }
diff --git a/rpython/rlib/rvmprof/src/vmprof_getpc.h b/rpython/rlib/rvmprof/src/vmprof_getpc.h
--- a/rpython/rlib/rvmprof/src/vmprof_getpc.h
+++ b/rpython/rlib/rvmprof/src/vmprof_getpc.h
@@ -134,7 +134,7 @@
   }
 };
 
-void* GetPC(ucontext_t *signal_ucontext) {
+intptr_t GetPC(ucontext_t *signal_ucontext) {
   // See comment above struct CallUnrollInfo.  Only try instruction
   // flow matching if both eip and esp looks reasonable.
   const int eip = signal_ucontext->uc_mcontext.gregs[REG_EIP];
@@ -146,12 +146,12 @@
       if (!memcmp(eip_char + callunrollinfo[i].pc_offset,
                   callunrollinfo[i].ins, callunrollinfo[i].ins_size)) {
         // We have a match.
-        void **retaddr = (void**)(esp + callunrollinfo[i].return_sp_offset);
+        intptr_t *retaddr = (intptr_t*)(esp + callunrollinfo[i].return_sp_offset);
         return *retaddr;
       }
     }
   }
-  return (void*)eip;
+  return eip;
 }
 
 // Special case #2: Windows, which has to do something totally different.
@@ -170,7 +170,7 @@
 typedef int ucontext_t;
 #endif
 
-void* GetPC(ucontext_t *signal_ucontext) {
+intptr_t GetPC(ucontext_t *signal_ucontext) {
   RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n");
   return NULL;
 }
@@ -180,11 +180,11 @@
 // the right value for your system, and add it to the list in
 // configure.ac (or set it manually in your config.h).
 #else
-void* GetPC(ucontext_t *signal_ucontext) {
+intptr_t GetPC(ucontext_t *signal_ucontext) {
 #ifdef __APPLE__
-  return (void*)(signal_ucontext->uc_mcontext->__ss.__rip);
+  return (signal_ucontext->uc_mcontext->__ss.__rip);
 #else
-  return (void*)signal_ucontext->PC_FROM_UCONTEXT;   // defined in config.h
+  return signal_ucontext->PC_FROM_UCONTEXT;   // defined in config.h
 #endif
 }
 
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
@@ -130,7 +130,7 @@
     char padding[sizeof(long) - 1];
     char marker;
     long count, depth;
-    void *stack[];
+    intptr_t stack[];
 };
 
 static long profile_interval_usec = 0;
@@ -144,13 +144,22 @@
  * *************************************************************
  */
 
-static int get_stack_trace(void **result, int max_depth, ucontext_t *ucontext)
+static int get_stack_trace(intptr_t *result, int max_depth, intptr_t pc, ucontext_t *ucontext)
 {
     struct vmprof_stack* stack = vmprof_global_stack;
     int n = 0;
+    intptr_t addr = 0;
+    int bottom_jitted = 0;
+    // check if the pc is in JIT
+    if (pypy_find_codemap_at_addr((intptr_t)pc, &addr)) {
+        // the bottom part is jitted, means we can fill up the first part
+        // from the JIT
+        n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth);
+        bottom_jitted = 1;
+    }
     while (n < max_depth - 1 && stack) {
-        result[n] = (void*)stack->kind;
-        result[n + 1] = (void*)stack->value;
+        result[n] = stack->kind;
+        result[n + 1] = stack->value;
         stack = stack->next;
         n += 2;
     }
@@ -205,7 +214,7 @@
 }
 #endif
 
-static void *get_current_thread_id(void)
+static intptr_t get_current_thread_id(void)
 {
     /* xxx This function is a hack on two fronts:
 
@@ -219,7 +228,7 @@
        An alternative would be to try to look if the information is
        available in the ucontext_t in the caller.
     */
-    return (void *)pthread_self();
+    return (intptr_t)pthread_self();
 }
 
 
@@ -247,7 +256,8 @@
             st->marker = MARKER_STACKTRACE;
             st->count = 1;
             //st->stack[0] = GetPC((ucontext_t*)ucontext);
-            depth = get_stack_trace(st->stack, MAX_STACK_DEPTH-2, ucontext);
+            depth = get_stack_trace(st->stack,
+                MAX_STACK_DEPTH-2, GetPC((ucontext_t*)ucontext), ucontext);
             //depth++;  // To account for pc value in stack[0];
             st->depth = depth;
             st->stack[depth++] = get_current_thread_id();
@@ -402,46 +412,11 @@
 
 static int close_profile(void)
 {
-    char buf[4096];
-    ssize_t size;
     unsigned char marker = MARKER_TRAILER;
 
     if (_write_all(&marker, 1) < 0)
         return -1;
 
-#ifdef __linux__
-    // copy /proc/self/maps to the end of the profile file
-    int srcfd = open("/proc/self/maps", O_RDONLY);
-    if (srcfd < 0)
-        return -1;
-
-    while ((size = read(srcfd, buf, sizeof buf)) > 0) {
-        if (_write_all(buf, size) < 0) {
-            close(srcfd);
-            return -1;
-        }
-    }
-    close(srcfd);
-#else
-    // freebsd and mac
-#if defined(__APPLE__)
-	sprintf(buf, "vmmap %d", getpid());
-#else
-    sprintf(buf, "procstat -v %d", getpid());
-#endif
-    FILE *srcf = popen(buf, "r");
-    if (!srcf)
-        return -1;
-
-    while ((size = fread(buf, 1, sizeof buf, srcf))) {
-        if (_write_all(buf, size) < 0) {
-            pclose(srcf);
-            return -1;
-        }
-    }
-    pclose(srcf);
-#endif
-
     /* don't close() the file descriptor from here */
     profile_file = -1;
     return 0;
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
@@ -4,12 +4,13 @@
 #define VMPROF_JITTED_TAG 3
 #define VMPROF_JITTING_TAG 4
 #define VMPROF_GC_TAG 5
+#define VMPROF_ASSEMBLER_TAG 6
 // whatever we want here
 
 typedef struct vmprof_stack {
     struct vmprof_stack* next;
-    long value;
-    long kind;
+    intptr_t value;
+    intptr_t kind;
 } vmprof_stack;
 
 // the kind is WORD so we consume exactly 3 WORDs and we don't have


More information about the pypy-commit mailing list