[pypy-commit] pypy vmprof: in-progress

arigo noreply at buildbot.pypy.org
Wed Mar 11 21:24:11 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: vmprof
Changeset: r76333:17b356ba6aa7
Date: 2015-03-11 20:30 +0100
http://bitbucket.org/pypy/pypy/changeset/17b356ba6aa7/

Log:	in-progress

diff --git a/pypy/module/_vmprof/src/get_custom_offset.c b/pypy/module/_vmprof/src/get_custom_offset.c
--- a/pypy/module/_vmprof/src/get_custom_offset.c
+++ b/pypy/module/_vmprof/src/get_custom_offset.c
@@ -2,8 +2,8 @@
 long pypy_jit_start_addr();
 long pypy_jit_end_addr();
 long pypy_jit_stack_depth_at_loc(long);
-long pypy_find_codemap_at_addr(long);
-long pypy_yield_codemap_at_addr(long, long, long*);
+void *pypy_find_codemap_at_addr(long);
+long pypy_yield_codemap_at_addr(void *, long, long *);
 
 extern volatile int pypy_codemap_currently_invalid;
 
@@ -28,26 +28,20 @@
 static long vmprof_write_header_for_jit_addr(void **result, long n,
 											 void *ip, int max_depth)
 {
-	long codemap_pos;
+	void *codemap;
 	long current_pos = 0;
 	intptr_t id;
 	intptr_t addr = (intptr_t)ip;
 
-	if (addr < pypy_jit_start_addr() || addr > pypy_jit_end_addr()) {
+	codemap = pypy_find_codemap_at_addr(addr);
+	if (codemap == NULL)
 		return n;
+
+	while (n < max_depth) {
+		id = pypy_yield_codemap_at_addr(codemap, addr, &current_pos);
+		if (id == 0)
+			break;
+		result[n++] = (void *)id;
 	}
-	codemap_pos = pypy_find_codemap_at_addr(addr);
-	if (codemap_pos == -1) {
-		return n;
-	}
-	while (1) {
-		id = pypy_yield_codemap_at_addr(codemap_pos, addr, &current_pos);
-		if (id == 0) {
-			return n;
-		}
-		result[n++] = id;
-		if (n >= max_depth) {
-			return n;
-		}
-	}
+	return n;
 }
diff --git a/rpython/jit/backend/llsupport/codemap.py b/rpython/jit/backend/llsupport/codemap.py
--- a/rpython/jit/backend/llsupport/codemap.py
+++ b/rpython/jit/backend/llsupport/codemap.py
@@ -17,48 +17,13 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 
-INT_LIST = rffi.CArray(lltype.Signed)
-
-CODEMAP = lltype.Struct(
-    'pypy_codemap_item',
-    ('addr', lltype.Signed),
-    ('machine_code_size', lltype.Signed),
-    ('bytecode_info_size', lltype.Signed),
-    ('bytecode_info', lltype.Ptr(INT_LIST)),
-    hints=dict(external=True, c_name='pypy_codemap_item'))
-CODEMAP_LIST = rffi.CArray(CODEMAP)
-
-CODEMAP_STORAGE = lltype.Struct(
-    'pypy_codemap_storage',
-    ('jit_addr_map_used', lltype.Signed),
-    ('jit_frame_depth_map_used', lltype.Signed),
-    ('jit_codemap_used', lltype.Signed),
-    ('jit_addr_map', lltype.Ptr(INT_LIST)),
-    ('jit_frame_depth_map', lltype.Ptr(INT_LIST)),
-    ('jit_codemap', lltype.Ptr(CODEMAP_LIST)),
-    hints=dict(external=True, c_name='pypy_codemap_storage'))
-
-CODEMAP_GCARRAY = lltype.GcArray(CODEMAP)
-
-_codemap = None
 
 eci = ExternalCompilationInfo(post_include_bits=["""
-RPY_EXTERN volatile int pypy_codemap_currently_invalid;
-RPY_EXTERN void pypy_codemap_invalid_set(int);
+RPY_EXTERN long pypy_jit_codemap_add(uintptr_t addr, long machine_code_size,
+                                     long *bytecode_info,
+                                     long bytecode_info_size);
+RPY_EXTERN void pypy_jit_codemap_del(uintptr_t addr);
 
-typedef struct pypy_codemap_item {
-   long addr, machine_code_size, bytecode_info_size;
-   long* bytecode_info;
-} pypy_codemap_item;
-
-typedef struct pypy_codemap_storage {
-   long jit_addr_map_used;
-   long jit_frame_depth_map_used;
-   long jit_codemap_used;
-   long* jit_addr_map;
-   long* jit_frame_depth_map;
-   pypy_codemap_item* jit_codemap;
-} pypy_codemap_storage;
 
 RPY_EXTERN pypy_codemap_storage *pypy_get_codemap_storage();
 RPY_EXTERN long pypy_jit_stack_depth_at_loc(long loc);
@@ -67,98 +32,9 @@
 RPY_EXTERN long pypy_jit_end_addr(void);
 RPY_EXTERN long pypy_yield_codemap_at_addr(long, long, long*);
 
-"""], separate_module_sources=["""
-volatile int pypy_codemap_currently_invalid = 0;
-
-static pypy_codemap_storage pypy_cs_g;
-
-static long bisect_right(long *a, long x, long hi)
-{
-    long lo, mid;
-    lo = 0;
-    while (lo < hi) {
-        mid = (lo+hi) / 2;
-        if (x < a[mid]) { hi = mid; }
-        else { lo = mid+1; }
-    }
-    return lo;
-}
-
-static long bisect_right_addr(pypy_codemap_item *a, long x, long hi)
-{
-    long lo, mid;
-    lo = 0;
-    while (lo < hi) {
-        mid = (lo+hi) / 2;
-        if (x < a[mid].addr) { hi = mid; }
-        else { lo = mid+1; }
-    }
-    return lo;
-}
-
-long pypy_jit_stack_depth_at_loc(long loc)
-{
-    long pos;
-    pos = bisect_right(pypy_cs_g.jit_addr_map, loc,
-                       pypy_cs_g.jit_addr_map_used);
-    if (pos == 0)
-        return -1;
-    return pypy_cs_g.jit_frame_depth_map[pos - 1];
-}
-
-long pypy_find_codemap_at_addr(long addr)
-{
-    return bisect_right_addr(pypy_cs_g.jit_codemap, addr,
-                             pypy_cs_g.jit_codemap_used) - 1;
-}
-
-long pypy_jit_start_addr(void)
-{
-    return pypy_cs_g.jit_addr_map[0];
-}
-
-long pypy_jit_end_addr(void)
-{
-    return pypy_cs_g.jit_addr_map[pypy_cs_g.jit_addr_map_used - 1];
-}
-
-long pypy_yield_codemap_at_addr(long codemap_no, long addr,
-                                long* current_pos_addr)
-{
-    // will return consecutive unique_ids from codemap, starting from position
-    // `pos` until addr
-    pypy_codemap_item *codemap = &(pypy_cs_g.jit_codemap[codemap_no]);
-    long current_pos = *current_pos_addr;
-    long start_addr = codemap->addr;
-    long rel_addr = addr - start_addr;
-    long next_start, next_stop;
-
-    while (1) {
-        if (current_pos >= codemap->bytecode_info_size)
-            return 0;
-        next_start = codemap->bytecode_info[current_pos + 1];
-        if (next_start > rel_addr)
-            return 0;
-        next_stop = codemap->bytecode_info[current_pos + 2];
-        if (next_stop > rel_addr) {
-            *current_pos_addr = current_pos + 4;
-            return codemap->bytecode_info[current_pos];
-        }
-        // we need to skip potentially more than one
-        current_pos = codemap->bytecode_info[current_pos + 3];
-    }
-}
-
-pypy_codemap_storage *pypy_get_codemap_storage(void)
-{
-    return &pypy_cs_g;
-}
-
-void pypy_codemap_invalid_set(int value)
-{
-    pypy_codemap_currently_invalid = value;
-}
-"""])
+"""], separate_module_files=[
+    os.path.join(os.path.dirname(__file__), 'src', 'codemap.c')
+])
 
 def llexternal(name, args, res):
     return rffi.llexternal(name, args, res, compilation_info=eci,
@@ -190,15 +66,11 @@
         dest[di] = source[si] + baseline
 
 class ListStorageMixin(object):
-    # XXX this code has wrong complexity, we should come up with a better
-    #     data structure ideally
     _mixin_ = True
-    jit_addr_map_allocated = 0
-    jit_codemap_allocated = 0
-    jit_frame_depth_map_allocated = 0
 
     @specialize.arg(1)
     def extend_with(self, name, to_insert, pos, baseline=0):
+        xxxx
         # first check if we need to reallocate
         g = pypy_get_codemap_storage()
         used = getattr(g, name + '_used')
@@ -328,22 +200,13 @@
                              start)
         pypy_codemap_invalid_set(0)
 
-    def register_codemap(self, codemap):
-        start = codemap[0]
-        g = pypy_get_codemap_storage()
-        pos = bisect_left_addr(g.jit_codemap, start, g.jit_codemap_used)
-        items = lltype.malloc(INT_LIST, len(codemap[2]), flavor='raw',
+    def register_codemap(self, (start, size, l)):
+        items = lltype.malloc(INT_LIST, len(l), flavor='raw',
                               track_allocation=False)
-        for i in range(len(codemap[2])):
-            items[i] = codemap[2][i]
-        s = lltype.malloc(CODEMAP_GCARRAY, 1)
-        s[0].addr = codemap[0]
-        s[0].machine_code_size = codemap[1]
-        s[0].bytecode_info = items
-        s[0].bytecode_info_size = len(codemap[2])
-        pypy_codemap_invalid_set(1)
-        self.extend_with('jit_codemap', s, pos)
-        pypy_codemap_invalid_set(0)
+        for i in range(len(l)):
+            items[i] = l[i]
+        if pypy_jit_codemap_add(start, size, items, len(l)) < 0:
+            lltype.free(items, flavor='raw', track_allocation=False)
 
     def finish_once(self):
         self.free()
diff --git a/rpython/jit/backend/llsupport/src/codemap.c b/rpython/jit/backend/llsupport/src/codemap.c
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/src/codemap.c
@@ -0,0 +1,133 @@
+#include "skiplist.c"
+
+volatile int pypy_codemap_currently_invalid = 0;
+
+void pypy_codemap_invalid_set(int value)
+{
+    if (value)
+        __sync_lock_test_and_set(&pypy_codemap_currently_invalid, 1);
+    else
+        __sync_lock_release(&pypy_codemap_currently_invalid);
+}
+
+
+/************************************************************/
+/***  codemap storage                                     ***/
+/************************************************************/
+
+typedef struct {
+    long machine_code_size;
+    long *bytecode_info;
+    long bytecode_info_size;
+} codemap_data_t;
+
+static skipnode_t jit_codemap_head;
+
+/*** interface used from codemap.py ***/
+
+long pypy_jit_codemap_add(uintptr_t addr, long machine_code_size,
+                          long *bytecode_info, long bytecode_info_size)
+{
+    skipnode_t *new = skiplist_malloc(sizeof(codemap_data_t));
+    codemap_data_t *data;
+    if (new == NULL)
+        return -1;   /* too bad */
+
+    new->key = addr;
+    data = (codemap_data_t *)new->data;
+    data->machine_code_size = machine_code_size;
+    data->bytecode_info = bytecode_info;
+    data->bytecode_info_size = bytecode_info_size;
+
+    pypy_codemap_invalid_set(1);
+    skiplist_insert(&jit_codemap_head, new);
+    pypy_codemap_invalid_set(0);
+    return 0;
+}
+
+void pypy_jit_codemap_del(uintptr_t addr)
+{
+    skiplist_remove(&jit_codemap_head, addr);
+}
+
+/*** interface used from pypy/module/_vmprof ***/
+
+void *pypy_find_codemap_at_addr(long addr)
+{
+    skiplist_t *codemap = skiplist_search(&jit_codemap_head, addr);
+    codemap_data_t *data;
+    uintptr_t rel_addr;
+
+    if (codemap->key == NULL)
+        return NULL;
+
+    rel_addr = (uintptr_t)addr - codemap->key;
+    data = (codemap_data_t *)codemap->data;
+    if (rel_addr >= data->machine_code_size)
+        return NULL;
+
+    return (void *)codemap;
+}
+
+long pypy_yield_codemap_at_addr(void *codemap_raw, long addr,
+                                long *current_pos_addr)
+{
+    // will return consecutive unique_ids from codemap, starting from position
+    // `pos` until addr
+    skiplist_t *codemap = (skiplist_t *)codemap_raw;
+    long current_pos = *current_pos_addr;
+    long rel_addr = addr - codemap->key;
+    long next_start, next_stop;
+    codemap_data_t *data = (codemap_data_t *)codemap->data;
+
+    while (1) {
+        if (current_pos >= data->bytecode_info_size)
+            return 0;
+        next_start = data->bytecode_info[current_pos + 1];
+        if (next_start > rel_addr)
+            return 0;
+        next_stop = data->bytecode_info[current_pos + 2];
+        if (next_stop > rel_addr) {
+            *current_pos_addr = current_pos + 4;
+            return data->bytecode_info[current_pos];
+        }
+        // we need to skip potentially more than one
+        current_pos = data->bytecode_info[current_pos + 3];
+    }
+}
+
+/************************************************************/
+
+
+
+long pypy_jit_stack_depth_at_loc(long loc)
+{
+    long pos;
+    pos = bisect_right(pypy_cs_g.jit_addr_map, loc,
+                       pypy_cs_g.jit_addr_map_used);
+    if (pos == 0)
+        return -1;
+    return pypy_cs_g.jit_frame_depth_map[pos - 1];
+}
+
+long pypy_find_codemap_at_addr(long addr)
+{
+    return bisect_right_addr(pypy_cs_g.jit_codemap, addr,
+                             pypy_cs_g.jit_codemap_used) - 1;
+}
+
+long pypy_jit_start_addr(void)
+{
+    return pypy_cs_g.jit_addr_map[0];
+}
+
+long pypy_jit_end_addr(void)
+{
+    return pypy_cs_g.jit_addr_map[pypy_cs_g.jit_addr_map_used - 1];
+}
+
+
+pypy_codemap_storage *pypy_get_codemap_storage(void)
+{
+    return &pypy_cs_g;
+}


More information about the pypy-commit mailing list