Author: Richard Plangger <planri...@gmail.com> 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") + + +@py.test.mark.skipif("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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit