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

Reply via email to