Author: Richard Plangger <[email protected]>
Branch: vmprof-native
Changeset: r90031:8ed69cf08956
Date: 2017-02-10 16:01 +0100
http://bitbucket.org/pypy/pypy/changeset/8ed69cf08956/
Log: add new test that registers dynamically allocated code for libunwind
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
@@ -250,6 +250,8 @@
def _was_registered(CodeClass):
return hasattr(CodeClass, '_vmprof_unique_id')
+def register_jit_page(addr, end_addr, splits):
+ pass
_vmprof_instance = None
diff --git a/rpython/rlib/rvmprof/src/shared/vmp_dynamic.c
b/rpython/rlib/rvmprof/src/shared/vmp_dynamic.c
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/src/shared/vmp_dynamic.c
@@ -0,0 +1,120 @@
+#include "vmp_dynamic.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+static int g_dyn_entry_count = 0;
+static int g_has_holes = -1;
+static int g_dyn_entry_count_max = 0;
+static unw_dyn_info_t ** g_dyn_entries = 0;
+
+int vmp_dyn_teardown(void)
+{
+ if (g_dyn_entries != NULL) {
+ free(g_dyn_entries);
+ }
+ g_dyn_entry_count = 0;
+ g_dyn_entry_count_max = 0;
+ g_has_holes = -1;
+ return 0;
+}
+
+static void _vmp_dyn_resize(void) {
+ if (g_dyn_entry_count_max == 0) {
+ g_dyn_entry_count_max = 128;
+ g_dyn_entries = (unw_dyn_info_t**)calloc(sizeof(unw_dyn_info_t*), 128);
+ }
+
+ if (g_dyn_entry_count + 1 >= g_dyn_entry_count_max) {
+ g_dyn_entry_count_max *= 2;
+ g_dyn_entries = (unw_dyn_info_t**)realloc(g_dyn_entries,
sizeof(unw_dyn_info_t*) * g_dyn_entry_count_max);
+ memset(g_dyn_entries + g_dyn_entry_count, 0,
+ sizeof(unw_dyn_info_t*)*g_dyn_entry_count_max -
g_dyn_entry_count);
+ }
+}
+
+static unw_dyn_info_t * _vmp_alloc_dyn_info(int * reference)
+{
+ unw_dyn_info_t * u;
+
+ u = (unw_dyn_info_t*)malloc(sizeof(unw_dyn_info_t));
+
+ int i = 0;
+ int ref = -1;
+ if (g_has_holes >= 0) {
+ i = g_has_holes;
+ while (i < g_dyn_entry_count) {
+ if (g_dyn_entries[i] == NULL) {
+ ref = i;
+ g_has_holes += 1;
+ }
+ }
+ if (i == g_dyn_entry_count) {
+ _vmp_dyn_resize();
+ ref = g_dyn_entry_count;
+ g_dyn_entry_count++;
+ }
+ } else {
+ _vmp_dyn_resize();
+ ref = g_dyn_entry_count;
+ g_dyn_entry_count++;
+ }
+ assert(ref != -1 && "ref position MUST be found");
+ g_dyn_entries[ref] = u;
+ *reference = ref;
+
+ return u;
+}
+
+static void _vmp_free_dyn_info(unw_dyn_info_t * u)
+{
+ free(u);
+}
+
+int vmp_dyn_register_jit_page(intptr_t addr, intptr_t end_addr,
+ const char * name)
+{
+ char * name_cpy = NULL;
+ int ref = -1;
+ unw_dyn_info_t * u = _vmp_alloc_dyn_info(&ref);
+ if (ref == -1) {
+ return -1; // fail, could not alloc
+ }
+ u->start_ip = (unw_word_t)addr;
+ u->end_ip = (unw_word_t)end_addr;
+ u->format = UNW_INFO_FORMAT_DYNAMIC;
+ if (name != NULL) {
+ name_cpy = strdup(name);
+ }
+ unw_dyn_proc_info_t * ip = (unw_dyn_proc_info_t*)&(u->u);
+ ip->name_ptr = (unw_word_t)name_cpy;
+ ip->handler = 0;
+ ip->flags = 0;
+ ip->regions = NULL;
+
+ _U_dyn_register(u);
+
+ return ref;
+}
+
+int vmp_dyn_cancel(int ref) {
+ unw_dyn_info_t * u;
+
+ if (ref >= g_dyn_entry_count || ref < 0) {
+ return 1;
+ }
+
+ u = g_dyn_entries[ref];
+ if (u != NULL) {
+ g_dyn_entries[ref] = NULL;
+ if (g_has_holes > ref) {
+ g_has_holes = ref;
+ }
+
+ _U_dyn_cancel(u);
+ }
+
+ _vmp_free_dyn_info(u);
+ return 0;
+}
diff --git a/rpython/rlib/rvmprof/src/shared/vmp_dynamic.h
b/rpython/rlib/rvmprof/src/shared/vmp_dynamic.h
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/src/shared/vmp_dynamic.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include <stdint.h>
+#include <libunwind.h>
+
+int vmp_dyn_register_jit_page(intptr_t addr, intptr_t end_addr,
+ const char * name);
+int vmp_dyn_cancel(int ref);
+int vmp_dyn_teardown(void);
+
diff --git a/rpython/rlib/rvmprof/src/shared/vmp_stack.c
b/rpython/rlib/rvmprof/src/shared/vmp_stack.c
--- a/rpython/rlib/rvmprof/src/shared/vmp_stack.c
+++ b/rpython/rlib/rvmprof/src/shared/vmp_stack.c
@@ -241,7 +241,7 @@
// this is possible because compiler align to 8 bytes.
//
#ifdef PYPY_JIT_CODEMAP
- if (func_addr == 0 && top_most_frame->kind == VMPROF_JITTED_TAG) {
+ if (top_most_frame->kind == VMPROF_JITTED_TAG) {
intptr_t pc = ((intptr_t*)(top_most_frame->value -
sizeof(intptr_t)))[0];
depth = vmprof_write_header_for_jit_addr(result, depth, pc,
max_depth);
frame = FRAME_STEP(frame);
@@ -291,9 +291,7 @@
// the native stack?
#ifdef RPYTHON_VMPROF
if (strstr(name, "libpypy-c.so") != NULL
- || strstr(name, "pypy-c") != NULL
- || strstr(name, "pypy") != NULL) {
- printf("ignoring %s\n", name);
+ || strstr(name, "pypy-c") != NULL) {
return 1;
}
#else
diff --git a/rpython/rlib/rvmprof/test/test_dynamic.py
b/rpython/rlib/rvmprof/test/test_dynamic.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/test/test_dynamic.py
@@ -0,0 +1,47 @@
+import py
+import sys
+try:
+ import cffi
+except ImportError:
+ py.test.skip('cffi required')
+
+from rpython.rlib import rvmprof
+srcdir = py.path.local(rvmprof.__file__).join("..", "src")
+
+
[email protected]("sys.platform == 'win32'")
+class TestDirect(object):
+ def setup_class(clz):
+ ffi = cffi.FFI()
+ ffi.cdef("""
+ int vmp_dyn_register_jit_page(intptr_t addr, intptr_t end_addr, const
char * name);
+ int vmp_dyn_cancel(int ref);
+ """)
+
+ with open(str(srcdir.join("shared/vmp_dynamic.c"))) as fd:
+ ffi.set_source("rpython.rlib.rvmprof.test._test_dynamic",
fd.read(),
+ include_dirs=[str(srcdir.join('shared'))],
+ libraries=['unwind'])
+
+ ffi.compile(verbose=True)
+
+ from rpython.rlib.rvmprof.test import _test_dynamic
+ clz.lib = _test_dynamic.lib
+ clz.ffi = _test_dynamic.ffi
+
+ def test_register_dynamic_code(self):
+ lib = self.lib
+ ffi = self.ffi
+
+ assert 1 == lib.vmp_dyn_cancel(100)
+ assert 1 == lib.vmp_dyn_cancel(0)
+ assert 1 == lib.vmp_dyn_cancel(-1)
+
+ s = ffi.new("char[]", "hello jit compiler")
+ assert 0 == lib.vmp_dyn_register_jit_page(0x100, 0x200, ffi.NULL)
+ assert 1 == lib.vmp_dyn_register_jit_page(0x200, 0x300, s)
+
+ lib.vmp_dyn_cancel(0)
+ lib.vmp_dyn_cancel(1)
+
+
diff --git a/rpython/rlib/rvmprof/test/test_rvmprof.py
b/rpython/rlib/rvmprof/test/test_rvmprof.py
--- a/rpython/rlib/rvmprof/test/test_rvmprof.py
+++ b/rpython/rlib/rvmprof/test/test_rvmprof.py
@@ -237,3 +237,4 @@
finally:
assert os.path.exists(tmpfilename)
os.unlink(tmpfilename)
+
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit