Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit