[pypy-commit] pypy vmprof: One new test passes

arigo noreply at buildbot.pypy.org
Thu Mar 12 11:00:50 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: vmprof
Changeset: r76338:402728053b00
Date: 2015-03-12 11:00 +0100
http://bitbucket.org/pypy/pypy/changeset/402728053b00/

Log:	One new test passes

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
@@ -9,6 +9,7 @@
 
 """
 
+import os
 from rpython.rlib import rgc
 from rpython.rlib.objectmodel import specialize, we_are_translated
 from rpython.rlib.entrypoint import jit_entrypoint
@@ -16,6 +17,10 @@
 from rpython.rlib.rbisect import bisect_left, bisect_left_addr
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.translator import cdir
+
+
+INT_LIST_PTR = rffi.CArrayPtr(lltype.Signed)
 
 
 eci = ExternalCompilationInfo(post_include_bits=["""
@@ -23,7 +28,11 @@
                                      unsigned int machine_code_size,
                                      long *bytecode_info,
                                      unsigned int bytecode_info_size);
-RPY_EXTERN void pypy_jit_codemap_del(uintptr_t addr);
+RPY_EXTERN long *pypy_jit_codemap_del(uintptr_t addr);
+RPY_EXTERN uintptr_t pypy_jit_codemap_firstkey(void);
+RPY_EXTERN void *pypy_find_codemap_at_addr(long addr);
+RPY_EXTERN long pypy_yield_codemap_at_addr(void *codemap_raw, long addr,
+                                           long *current_pos_addr);
 
 RPY_EXTERN long pypy_jit_depthmap_add(uintptr_t addr, unsigned int size,
                                       unsigned int stackdepth);
@@ -31,16 +40,21 @@
 
 """], separate_module_files=[
     os.path.join(os.path.dirname(__file__), 'src', 'codemap.c')
-])
+], include_dirs=[cdir])
 
 def llexternal(name, args, res):
     return rffi.llexternal(name, args, res, compilation_info=eci,
                            releasegil=False)
 
-ll_pypy_codemap_invalid_set = llexternal('pypy_codemap_invalid_set',
-                                         [rffi.INT], lltype.Void)
-pypy_get_codemap_storage = llexternal('pypy_get_codemap_storage',
-                                      [], lltype.Ptr(CODEMAP_STORAGE))
+pypy_jit_codemap_add = llexternal('pypy_jit_codemap_add',
+                                  [lltype.Signed, lltype.Signed,
+                                   INT_LIST_PTR, lltype.Signed],
+                                  lltype.Signed)
+pypy_jit_codemap_del = llexternal('pypy_jit_codemap_del',
+                                  [lltype.Signed], INT_LIST_PTR)
+pypy_jit_codemap_firstkey = llexternal('pypy_jit_codemap_firstkey',
+                                       [], lltype.Signed)
+
 stack_depth_at_loc = llexternal('pypy_jit_stack_depth_at_loc',
                                 [lltype.Signed], lltype.Signed)
 find_codemap_at_addr = llexternal('pypy_find_codemap_at_addr',
@@ -50,10 +64,6 @@
                                      rffi.CArrayPtr(lltype.Signed)],
                                      lltype.Signed)
 
-def pypy_codemap_invalid_set(val):
-    #if we_are_translated():
-    ll_pypy_codemap_invalid_set(val)
-
 @specialize.ll()
 def copy_item(source, dest, si, di, baseline=0):
     TP = lltype.typeOf(dest)
@@ -62,100 +72,23 @@
     else:
         dest[di] = source[si] + baseline
 
-class ListStorageMixin(object):
-    _mixin_ = True
 
-    @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')
-        allocated = getattr(self, name + '_allocated')
-        lst = getattr(g, name)
-        if used + len(to_insert) > allocated or pos != used:
-            old_lst = lst
-            if used + len(to_insert) > allocated:
-                new_size = max(4 * allocated,
-                               (allocated + len(to_insert)) * 2)
-            else:
-                new_size = allocated
-            lst = lltype.malloc(lltype.typeOf(lst).TO, new_size,
-                                flavor='raw',
-                                track_allocation=False)
-            setattr(self, name + '_allocated', new_size)
-            for i in range(0, pos):
-                copy_item(old_lst, lst, i, i)
-            j = 0
-            for i in range(pos, pos + len(to_insert)):
-                copy_item(to_insert, lst, j, i, baseline)
-                j += 1
-            j = pos
-            for i in range(pos + len(to_insert), len(to_insert) + used):
-                copy_item(old_lst, lst, j, i)
-                j += 1
-            self.free_lst(name, old_lst)
-        else:
-            for i in range(len(to_insert)):
-                copy_item(to_insert, lst, i, i + pos, baseline)
-        setattr(g, name, lst)
-        setattr(g, name + '_used', len(to_insert) + used)
-
-    @specialize.arg(1)
-    def remove(self, name, start, end):
-        g = pypy_get_codemap_storage()
-        lst = getattr(g, name)
-        used = getattr(g, name + '_used')
-        j = end
-        for i in range(start, used - (end - start)):
-            info = lltype.nullptr(INT_LIST)
-            if name == 'jit_codemap':
-                if i < end:
-                    info = lst[i].bytecode_info
-            copy_item(lst, lst, j, i)
-            if name == 'jit_codemap':
-                if info:
-                    lltype.free(info, flavor='raw', track_allocation=False)
-            j += 1
-        setattr(g, name + '_used', used - (end - start))
-
-    def free(self):
-        g = pypy_get_codemap_storage()
-        # if setup has not been called
-        if g.jit_addr_map_used:
-            lltype.free(g.jit_addr_map, flavor='raw', track_allocation=False)
-            g.jit_addr_map_used = 0
-            g.jit_addr_map = lltype.nullptr(INT_LIST)
-        i = 0
-        while i < g.jit_codemap_used:
-            lltype.free(g.jit_codemap[i].bytecode_info, flavor='raw',
-                        track_allocation=False)
-            i += 1
-        if g.jit_codemap_used:
-            lltype.free(g.jit_codemap, flavor='raw',
-                        track_allocation=False)
-            g.jit_codemap_used = 0
-            g.jit_codemap = lltype.nullptr(CODEMAP_LIST)
-        if g.jit_frame_depth_map_used:
-            lltype.free(g.jit_frame_depth_map, flavor='raw',
-                        track_allocation=False)
-            g.jit_frame_depth_map_used = 0
-            g.jit_frame_depth_map = lltype.nullptr(INT_LIST)
-
-    @specialize.arg(1)
-    def free_lst(self, name, lst):
-        if lst:
-            lltype.free(lst, flavor='raw', track_allocation=False)
-
-class CodemapStorage(ListStorageMixin):
+class CodemapStorage(object):
     """ An immortal wrapper around underlaying jit codemap data
     """
     def setup(self):
-        g = pypy_get_codemap_storage()
-        if g.jit_addr_map_used != 0:
-             # someone failed to call free(), in tests only anyway
+        if not we_are_translated():
+             # in case someone failed to call free(), in tests only anyway
              self.free()
 
+    def free(self):
+        while True:
+            key = pypy_jit_codemap_firstkey()
+            if not key:
+                break
+            items = pypy_jit_codemap_del(key)
+            lltype.free(items, flavor='raw', track_allocation=False)
+
     def free_asm_block(self, start, stop):
         # fix up jit_addr_map
         g = pypy_get_codemap_storage()
@@ -198,7 +131,7 @@
         pypy_codemap_invalid_set(0)
 
     def register_codemap(self, (start, size, l)):
-        items = lltype.malloc(INT_LIST, len(l), flavor='raw',
+        items = lltype.malloc(INT_LIST_PTR.TO, len(l), flavor='raw',
                               track_allocation=False)
         for i in range(len(l)):
             items[i] = l[i]
@@ -209,14 +142,14 @@
         self.free()
 
 def unpack_traceback(addr):
-    codemap_pos = find_codemap_at_addr(addr)
-    if codemap_pos == -1:
+    codemap_raw = find_codemap_at_addr(addr)
+    if not codemap_raw:
         return [] # no codemap for that position
     storage = lltype.malloc(rffi.CArray(lltype.Signed), 1, flavor='raw')
     storage[0] = 0
     res = []
     while True:
-        item = yield_bytecode_at_addr(codemap_pos, addr, storage)
+        item = yield_bytecode_at_addr(codemap_raw, addr, storage)
         if item == 0:
             break
         res.append(item)
diff --git a/rpython/jit/backend/llsupport/src/codemap.c b/rpython/jit/backend/llsupport/src/codemap.c
--- a/rpython/jit/backend/llsupport/src/codemap.c
+++ b/rpython/jit/backend/llsupport/src/codemap.c
@@ -1,3 +1,4 @@
+#include "src/precommondefs.h"
 #include "skiplist.c"
 
 volatile int pypy_codemap_currently_invalid = 0;
@@ -25,6 +26,7 @@
 
 /*** interface used from codemap.py ***/
 
+RPY_EXTERN
 long pypy_jit_codemap_add(uintptr_t addr, unsigned int machine_code_size,
                           long *bytecode_info, unsigned int bytecode_info_size)
 {
@@ -45,18 +47,35 @@
     return 0;
 }
 
-void pypy_jit_codemap_del(uintptr_t addr)
+RPY_EXTERN
+long *pypy_jit_codemap_del(uintptr_t addr)
 {
+    long *result;
+    skipnode_t *node;
+
     pypy_codemap_invalid_set(1);
-    skiplist_remove(&jit_codemap_head, addr);
+    node = skiplist_remove(&jit_codemap_head, addr);
     pypy_codemap_invalid_set(0);
+
+    if (node == NULL)
+        return NULL;
+    result = ((codemap_data_t *)node->data)->bytecode_info;
+    free(node);
+    return result;
+}
+
+RPY_EXTERN
+uintptr_t pypy_jit_codemap_firstkey(void)
+{
+    return skiplist_firstkey(&jit_codemap_head);
 }
 
 /*** interface used from pypy/module/_vmprof ***/
 
+RPY_EXTERN
 void *pypy_find_codemap_at_addr(long addr)
 {
-    skiplist_t *codemap = skiplist_search(&jit_codemap_head, addr);
+    skipnode_t *codemap = skiplist_search(&jit_codemap_head, addr);
     codemap_data_t *data;
     uintptr_t rel_addr;
 
@@ -71,12 +90,13 @@
     return (void *)codemap;
 }
 
+RPY_EXTERN
 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;
+    skipnode_t *codemap = (skipnode_t *)codemap_raw;
     long current_pos = *current_pos_addr;
     long rel_addr = addr - codemap->key;
     long next_start, next_stop;
@@ -132,6 +152,8 @@
 
 void pypy_jit_depthmap_clear(uintptr_t addr, unsigned int size)
 {
+    abort();
+#if 0
     uintptr_t search_key = addr + size - 1;
     if (size == 0)
         return;
@@ -145,13 +167,14 @@
         skiplist_remove(&jit_depthmap_head, node->addr);
     }
     pypy_codemap_invalid_set(0);
+#endif
 }
 
 /*** interface used from pypy/module/_vmprof ***/
 
 long pypy_jit_stack_depth_at_loc(long loc)
 {
-    skiplist_t *depthmap = skiplist_search(&jit_depthmap_head, (uintptr_t)loc);
+    skipnode_t *depthmap = skiplist_search(&jit_depthmap_head, (uintptr_t)loc);
     depthmap_data_t *data;
     uintptr_t rel_addr;
 
diff --git a/rpython/jit/backend/llsupport/src/skiplist.c b/rpython/jit/backend/llsupport/src/skiplist.c
--- a/rpython/jit/backend/llsupport/src/skiplist.c
+++ b/rpython/jit/backend/llsupport/src/skiplist.c
@@ -72,7 +72,7 @@
     }
 }
 
-static void skiplist_remove(skipnode_t *head, uintptr_t exact_key)
+static skipnode_t *skiplist_remove(skipnode_t *head, uintptr_t exact_key)
 {
     uintptr_t level = SKIPLIST_HEIGHT - 1;
     while (1) {
@@ -81,15 +81,23 @@
             if (next->key == exact_key) {
                 head->next[level] = next->next[level];
                 if (level == 0)
-                    return;    /* successfully removed */
+                    return next;    /* successfully removed */
                 level -= 1;
             }
             else
                 head = next;
         }
         else {
-            assert(level > 0);   /* else, 'exact_key' not found! */
+            if (level == 0)
+                return NULL;    /* 'exact_key' not found! */
             level -= 1;
         }
     }
 }
+
+static uintptr_t skiplist_firstkey(skipnode_t *head)
+{
+    if (head->next[0] == NULL)
+        return 0;
+    return head->next[0]->key;
+}
diff --git a/rpython/jit/backend/llsupport/test/test_codemap.py b/rpython/jit/backend/llsupport/test/test_codemap.py
--- a/rpython/jit/backend/llsupport/test/test_codemap.py
+++ b/rpython/jit/backend/llsupport/test/test_codemap.py
@@ -1,10 +1,28 @@
 
 from rpython.jit.backend.llsupport.codemap import stack_depth_at_loc
-from rpython.jit.backend.llsupport.codemap import CodemapStorage,\
-     ListStorageMixin, CodemapBuilder, unpack_traceback,\
-     pypy_get_codemap_storage
+from rpython.jit.backend.llsupport.codemap import CodemapStorage, \
+     CodemapBuilder, unpack_traceback, find_codemap_at_addr
 
-g = pypy_get_codemap_storage()
+def test_register_codemap():
+    codemap = CodemapStorage()
+    codemap.setup()
+    codemap.register_codemap((100, 20, [13, 14, 15]))
+    codemap.register_codemap((300, 30, [16, 17, 18]))
+    codemap.register_codemap((200, 100, [19, 20, 21, 22, 23]))
+    #
+    raw100 = find_codemap_at_addr(100)
+    assert find_codemap_at_addr(119) == raw100
+    assert not find_codemap_at_addr(120)
+    #
+    raw200 = find_codemap_at_addr(200)
+    assert raw200 != raw100
+    assert find_codemap_at_addr(299) == raw200
+    #
+    raw300 = find_codemap_at_addr(329)
+    assert raw300 != raw100 and raw300 != raw200
+    assert find_codemap_at_addr(300) == raw300
+    #
+    codemap.free()
 
 def test_list_storage_mixin():
     class X(ListStorageMixin):
diff --git a/rpython/jit/backend/llsupport/test/test_skiplist.py b/rpython/jit/backend/llsupport/test/test_skiplist.py
--- a/rpython/jit/backend/llsupport/test/test_skiplist.py
+++ b/rpython/jit/backend/llsupport/test/test_skiplist.py
@@ -13,7 +13,8 @@
 skipnode_t *skiplist_malloc(uintptr_t datasize);
 skipnode_t *skiplist_search(skipnode_t *head, uintptr_t searchkey);
 void skiplist_insert(skipnode_t *head, skipnode_t *new);
-void skiplist_remove(skipnode_t *head, uintptr_t exact_key);
+skipnode_t *skiplist_remove(skipnode_t *head, uintptr_t exact_key);
+uintptr_t skiplist_firstkey(skipnode_t *head);
 """)
 
 filename = os.path.join(os.path.dirname(__file__), '..', 'src', 'skiplist.c')
@@ -68,11 +69,14 @@
         next = following[node.key]
         following[prev] = next
         preceeding[next] = prev
-        lib.skiplist_remove(my_head, node.key)
+        res = lib.skiplist_remove(my_head, node.key)
+        assert res == node
         if prev == 0:
             assert lib.skiplist_search(my_head, node.key) == my_head
         else:
             assert lib.skiplist_search(my_head, node.key) == nodes[prev]
+        res = lib.skiplist_remove(my_head, node.key)
+        assert res == ffi.NULL
     #
     for i in range(100000):
         random_key = random.randrange(2, 10**9)


More information about the pypy-commit mailing list