[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, ¤t_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