diff --git a/ChangeLog b/ChangeLog index 483ca5e..0a945a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-11-06 Aleksey Demakov + + * include/jit/jit-memory.h, jit/jit-internal.h, jit/jit-memory.c + * jit-cache.c: restore ability to allocate memory for recompiled + functions. + 2012-11-05 Aleksey Demakov * jitplus/jit-plus-function.cpp (create): free function signature. diff --git a/include/jit/jit-memory.h b/include/jit/jit-memory.h index 418b42b..01487c3 100644 --- a/include/jit/jit-memory.h +++ b/include/jit/jit-memory.h @@ -48,9 +48,10 @@ struct jit_memory_manager jit_memory_context_t (*create)(jit_context_t context); void (*destroy)(jit_memory_context_t memctx); - jit_function_t (*find_function)(jit_memory_context_t memctx, void *pc); - void * (*get_function_start)(jit_memory_context_t memctx, jit_function_t func); - void * (*get_function_end)(jit_memory_context_t memctx, jit_function_t func); + void * (*find_function_info)(jit_memory_context_t memctx, void *pc); + jit_function_t (*get_function)(jit_memory_context_t memctx, void *func_info); + void * (*get_function_start)(jit_memory_context_t memctx, void *func_info); + void * (*get_function_end)(jit_memory_context_t memctx, void *func_info); jit_function_t (*alloc_function)(jit_memory_context_t memctx); void (*free_function)(jit_memory_context_t memctx, jit_function_t func); diff --git a/jit/jit-compile.c b/jit/jit-compile.c index a443b9e..f66059c 100644 --- a/jit/jit-compile.c +++ b/jit/jit-compile.c @@ -1019,7 +1019,8 @@ _jit_function_compile_on_demand(jit_function_t func) #define JIT_CACHE_NO_OFFSET (~((unsigned long)0)) unsigned long -_jit_function_get_bytecode(jit_function_t func, void *pc, int exact) +_jit_function_get_bytecode(jit_function_t func, + void *func_info, void *pc, int exact) { unsigned long offset = JIT_CACHE_NO_OFFSET; void *start; @@ -1027,7 +1028,7 @@ _jit_function_get_bytecode(jit_function_t func, void *pc, int exact) jit_varint_decoder_t decoder; jit_uint off, noff; - start = _jit_memory_get_function_start(func->context, func); + start = _jit_memory_get_function_start(func->context, func_info); native_offset = pc - start; _jit_varint_init_decoder(&decoder, func->bytecode_offset); diff --git a/jit/jit-except.c b/jit/jit-except.c index a24389e..39da8ae 100644 --- a/jit/jit-except.c +++ b/jit/jit-except.c @@ -397,7 +397,11 @@ jit_stack_trace_get_function(jit_context_t context, jit_stack_trace_t trace, uns { if(trace && posn < trace->size) { - return _jit_memory_find_function(context, trace->items[posn]); + void *func_info = _jit_memory_find_function_info(context, trace->items[posn]); + if(func_info) + { + return _jit_memory_get_function(context, func_info); + } } return 0; } @@ -432,15 +436,26 @@ void *jit_stack_trace_get_pc unsigned int jit_stack_trace_get_offset(jit_context_t context, jit_stack_trace_t trace, unsigned int posn) { - if(trace && posn < trace->size) + void *func_info; + jit_function_t func; + + if(!trace || posn >= trace->size) { - jit_function_t func = _jit_memory_find_function(context, trace->items[posn]); - if (func) - { - return _jit_function_get_bytecode(func, trace->items[posn], 0); - } + return JIT_NO_OFFSET; } - return JIT_NO_OFFSET; + + func_info = _jit_memory_find_function_info(context, trace->items[posn]); + if(!func_info) + { + return JIT_NO_OFFSET; + } + func = _jit_memory_get_function(context, func_info); + if(!func) + { + return JIT_NO_OFFSET; + } + + return _jit_function_get_bytecode(func, func_info, trace->items[posn], 0); } /*@ diff --git a/jit/jit-function.c b/jit/jit-function.c index edad6d7..0f88642 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -648,11 +648,20 @@ void *jit_function_to_closure(jit_function_t func) jit_function_t jit_function_from_closure(jit_context_t context, void *closure) { + void *func_info; + if(!context) { return 0; } - return _jit_memory_find_function(context, closure); + + func_info = _jit_memory_find_function_info(context, closure); + if(!func_info) + { + return 0; + } + + return _jit_memory_get_function(context, func_info); } /*@ @@ -666,6 +675,7 @@ jit_function_from_closure(jit_context_t context, void *closure) jit_function_t jit_function_from_pc(jit_context_t context, void *pc, void **handler) { + void *func_info; jit_function_t func; if(!context) @@ -674,7 +684,12 @@ jit_function_from_pc(jit_context_t context, void *pc, void **handler) } /* Get the function and the exception handler cookie */ - func = _jit_memory_find_function(context, pc); + func_info = _jit_memory_find_function_info(context, pc); + if(!func_info) + { + return 0; + } + func = _jit_memory_get_function(context, func_info); if(!func) { return 0; @@ -751,11 +766,20 @@ jit_function_from_vtable_pointer(jit_context_t context, void *vtable_pointer) } return 0; #else + void *func_info; + if(!context) { return 0; } - return _jit_memory_find_function(context, vtable_pointer); + + func_info = _jit_memory_find_function_info(context, vtable_pointer); + if(!func_info) + { + return 0; + } + + return _jit_memory_get_function(context, func_info); #endif } diff --git a/jit/jit-internal.h b/jit/jit-internal.h index 6e42e40..581bf1c 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -541,7 +541,7 @@ void *_jit_function_compile_on_demand(jit_function_t func); * offset within a method. Returns JIT_CACHE_NO_OFFSET * if the bytecode offset could not be determined. */ -unsigned long _jit_function_get_bytecode(jit_function_t func, void *pc, int exact); +unsigned long _jit_function_get_bytecode(jit_function_t func, void *func_info, void *pc, int exact); /* * Information about a registered external symbol. @@ -599,9 +599,10 @@ void _jit_memory_unlock(jit_context_t context); int _jit_memory_ensure(jit_context_t context); void _jit_memory_destroy(jit_context_t context); -jit_function_t _jit_memory_find_function(jit_context_t context, void *pc); -void *_jit_memory_get_function_start(jit_context_t context, jit_function_t func); -void *_jit_memory_get_function_end(jit_context_t context, jit_function_t func); +void *_jit_memory_find_function_info(jit_context_t context, void *pc); +jit_function_t _jit_memory_get_function(jit_context_t context, void *func_info); +void *_jit_memory_get_function_start(jit_context_t context, void *func_info); +void *_jit_memory_get_function_end(jit_context_t context, void *func_info); jit_function_t _jit_memory_alloc_function(jit_context_t context); void _jit_memory_free_function(jit_context_t context, jit_function_t func); diff --git a/jit/jit-memory-cache.c b/jit/jit-memory-cache.c index 319955a..a17d6d7 100644 --- a/jit/jit-memory-cache.c +++ b/jit/jit-memory-cache.c @@ -55,14 +55,14 @@ extern "C" { * There may be more than one such block associated with a method * if the method contains exception regions. */ -typedef struct jit_cache_method *jit_cache_method_t; -struct jit_cache_method +typedef struct jit_cache_node *jit_cache_node_t; +struct jit_cache_node { - jit_cache_method_t left; /* Left sub-tree and red/black bit */ - jit_cache_method_t right; /* Right sub-tree */ + jit_cache_node_t left; /* Left sub-tree and red/black bit */ + jit_cache_node_t right; /* Right sub-tree */ unsigned char *start; /* Start of the cache region */ unsigned char *end; /* End of the cache region */ - struct _jit_function func; /* Function */ + jit_function_t func; /* Function info block slot */ }; /* @@ -90,20 +90,20 @@ struct jit_cache unsigned char *free_end; /* Current end of the free region */ unsigned char *prev_start; /* Previous start of the free region */ unsigned char *prev_end; /* Previous end of the free region */ - jit_cache_method_t method; /* Information for the current method */ - struct jit_cache_method head; /* Head of the lookup tree */ - struct jit_cache_method nil; /* Nil pointer for the lookup tree */ + jit_cache_node_t node; /* Information for the current function */ + struct jit_cache_node head; /* Head of the lookup tree */ + struct jit_cache_node nil; /* Nil pointer for the lookup tree */ }; /* * Get or set the sub-trees of a node. */ #define GetLeft(node) \ - ((jit_cache_method_t)(((jit_nuint)(node)->left) & ~((jit_nuint)1))) + ((jit_cache_node_t)(((jit_nuint)(node)->left) & ~((jit_nuint)1))) #define GetRight(node) \ ((node)->right) #define SetLeft(node,value) \ - ((node)->left = (jit_cache_method_t)(((jit_nuint)value) | \ + ((node)->left = (jit_cache_node_t)(((jit_nuint)value) | \ (((jit_nuint)(node)->left) & ((jit_nuint)1)))) #define SetRight(node,value) \ ((node)->right = (value)) @@ -114,11 +114,12 @@ struct jit_cache #define GetRed(node) \ ((((jit_nuint)((node)->left)) & ((jit_nuint)1)) != 0) #define SetRed(node) \ - ((node)->left = (jit_cache_method_t)(((jit_nuint)(node)->left) | ((jit_nuint)1))) + ((node)->left = (jit_cache_node_t)(((jit_nuint)(node)->left) | ((jit_nuint)1))) #define SetBlack(node) \ - ((node)->left = (jit_cache_method_t)(((jit_nuint)(node)->left) & ~((jit_nuint)1))) + ((node)->left = (jit_cache_node_t)(((jit_nuint)(node)->left) & ~((jit_nuint)1))) void _jit_cache_destroy(jit_cache_t cache); +void * _jit_cache_alloc_data(jit_cache_t cache, unsigned long size, unsigned long align); /* * Allocate a cache page and add it to the cache. @@ -208,7 +209,7 @@ AllocCachePage(jit_cache_t cache, int factor) * Compare a key against a node, being careful of sentinel nodes. */ static int -CacheCompare(jit_cache_t cache, unsigned char *key, jit_cache_method_t node) +CacheCompare(jit_cache_t cache, unsigned char *key, jit_cache_node_t node) { if(node == &cache->nil || node == &cache->head) { @@ -236,10 +237,10 @@ CacheCompare(jit_cache_t cache, unsigned char *key, jit_cache_method_t node) /* * Rotate a sub-tree around a specific node. */ -static jit_cache_method_t -CacheRotate(jit_cache_t cache, unsigned char *key, jit_cache_method_t around) +static jit_cache_node_t +CacheRotate(jit_cache_t cache, unsigned char *key, jit_cache_node_t around) { - jit_cache_method_t child, grandChild; + jit_cache_node_t child, grandChild; int setOnLeft; if(CacheCompare(cache, key, around) < 0) { @@ -300,14 +301,14 @@ CacheRotate(jit_cache_t cache, unsigned char *key, jit_cache_method_t around) * that is associated with a method cache. */ static void -AddToLookupTree(jit_cache_t cache, jit_cache_method_t method) +AddToLookupTree(jit_cache_t cache, jit_cache_node_t method) { unsigned char *key = method->start; - jit_cache_method_t temp; - jit_cache_method_t greatGrandParent; - jit_cache_method_t grandParent; - jit_cache_method_t parent; - jit_cache_method_t nil = &(cache->nil); + jit_cache_node_t temp; + jit_cache_node_t greatGrandParent; + jit_cache_node_t grandParent; + jit_cache_node_t parent; + jit_cache_node_t nil = &(cache->nil); int cmp; /* Search for the insert position */ @@ -347,7 +348,7 @@ AddToLookupTree(jit_cache_t cache, jit_cache_method_t method) } /* Insert the new node into the current position */ - method->left = (jit_cache_method_t)(((jit_nuint)nil) | ((jit_nuint)1)); + method->left = (jit_cache_node_t)(((jit_nuint)nil) | ((jit_nuint)1)); method->right = nil; if(CacheCompare(cache, key, parent) < 0) { @@ -423,11 +424,13 @@ _jit_cache_create(jit_context_t context) { cache->pagesLeft = -1; } - cache->method = 0; + cache->node = 0; cache->nil.left = &(cache->nil); cache->nil.right = &(cache->nil); + cache->nil.func = 0; cache->head.left = 0; cache->head.right = &(cache->nil); + cache->head.func = 0; /* Allocate the initial cache page */ AllocCachePage(cache, 0); @@ -468,7 +471,7 @@ _jit_cache_extend(jit_cache_t cache, int count) int factor = 1 << count; /* Bail out if there is a started function */ - if(cache->method) + if(cache->node) { return; } @@ -502,23 +505,20 @@ _jit_cache_extend(jit_cache_t cache, int count) jit_function_t _jit_cache_alloc_function(jit_cache_t cache) { - jit_cache_method_t method = jit_cnew(struct jit_cache_method); - return &method->func; + return jit_cnew(struct _jit_function); } void _jit_cache_free_function(jit_cache_t cache, jit_function_t func) { - jit_cache_method_t method = (jit_cache_method_t) - (((char *) func) - offsetof(struct jit_cache_method, func)); - jit_free(method); + jit_free(func); } int _jit_cache_start_function(jit_cache_t cache, jit_function_t func) { /* Bail out if there is a started function already */ - if(cache->method) + if(cache->node) { return JIT_MEMORY_ERROR; } @@ -533,15 +533,20 @@ _jit_cache_start_function(jit_cache_t cache, jit_function_t func) cache->prev_start = cache->free_start; cache->prev_end = cache->free_end; - /* Get the function information block */ - cache->method = (jit_cache_method_t) - (((char *) func) - offsetof(struct jit_cache_method, func)); + /* Allocate a new cache node */ + cache->node = _jit_cache_alloc_data( + cache, sizeof(struct jit_cache_node), sizeof(void *)); + if(!cache->node) + { + return JIT_MEMORY_TOO_BIG; + } + cache->node->func = func; /* Initialize the function information */ - cache->method->start = cache->free_start; - cache->method->end = 0; - cache->method->left = 0; - cache->method->right = 0; + cache->node->start = cache->free_start; + cache->node->end = 0; + cache->node->left = 0; + cache->node->right = 0; return JIT_MEMORY_OK; } @@ -550,7 +555,7 @@ int _jit_cache_end_function(jit_cache_t cache, int result) { /* Bail out if there is no started function */ - if(!cache->method) + if(!cache->node) { return JIT_MEMORY_ERROR; } @@ -561,14 +566,15 @@ _jit_cache_end_function(jit_cache_t cache, int result) /* Restore the saved cache position */ cache->free_start = cache->prev_start; cache->free_end = cache->prev_end; - cache->method = 0; + cache->node = 0; + return JIT_MEMORY_RESTART; } /* Update the method region block and then add it to the lookup tree */ - cache->method->end = cache->free_start; - AddToLookupTree(cache, cache->method); - cache->method = 0; + cache->node->end = cache->free_start; + AddToLookupTree(cache, cache->node); + cache->node = 0; /* The method is ready to go */ return JIT_MEMORY_OK; @@ -578,7 +584,7 @@ void * _jit_cache_get_code_break(jit_cache_t cache) { /* Bail out if there is no started function */ - if(!cache->method) + if(!cache->node) { return 0; } @@ -591,16 +597,16 @@ void _jit_cache_set_code_break(jit_cache_t cache, void *ptr) { /* Bail out if there is no started function */ - if(!cache->method) + if(!cache->node) { return; } /* Sanity checks */ - if ((unsigned char *) ptr < cache->free_start) + if((unsigned char *) ptr < cache->free_start) { return; } - if ((unsigned char *) ptr > cache->free_end) + if((unsigned char *) ptr > cache->free_end) { return; } @@ -613,7 +619,7 @@ void * _jit_cache_get_code_limit(jit_cache_t cache) { /* Bail out if there is no started function */ - if(!cache->method) + if(!cache->node) { return 0; } @@ -649,7 +655,7 @@ alloc_code(jit_cache_t cache, unsigned int size, unsigned int align) unsigned char *ptr; /* Bail out if there is a started function */ - if(cache->method) + if(cache->node) { return 0; } @@ -778,10 +784,10 @@ _jit_cache_alloc_no_method(jit_cache_t cache, unsigned long size, unsigned long } #endif -jit_function_t -_jit_cache_get_function(jit_cache_t cache, void *pc) +void * +_jit_cache_find_function_info(jit_cache_t cache, void *pc) { - jit_cache_method_t node = cache->head.right; + jit_cache_node_t node = cache->head.right; while(node != &(cache->nil)) { if(((unsigned char *)pc) < node->start) @@ -794,26 +800,43 @@ _jit_cache_get_function(jit_cache_t cache, void *pc) } else { - return &node->func; + return node; } } return 0; } +jit_function_t +_jit_cache_get_function(jit_cache_t cache, void *func_info) +{ + if (func_info) + { + jit_cache_node_t node = (jit_cache_node_t) func_info; + return node->func; + } + return 0; +} + void * -_jit_cache_get_function_start(jit_memory_context_t memctx, jit_function_t func) +_jit_cache_get_function_start(jit_memory_context_t memctx, void *func_info) { - jit_cache_method_t method = (jit_cache_method_t) - (((char *) func) - offsetof(struct jit_cache_method, func)); - return method->start; + if (func_info) + { + jit_cache_node_t node = (jit_cache_node_t) func_info; + return node->start; + } + return 0; } void * -_jit_cache_get_function_end(jit_memory_context_t memctx, jit_function_t func) +_jit_cache_get_function_end(jit_memory_context_t memctx, void *func_info) { - jit_cache_method_t method = (jit_cache_method_t) - (((char *) func) - offsetof(struct jit_cache_method, func)); - return method->end; + if (func_info) + { + jit_cache_node_t node = (jit_cache_node_t) func_info; + return node->end; + } + return 0; } jit_memory_manager_t @@ -827,13 +850,16 @@ jit_default_memory_manager(void) (void (*)(jit_memory_context_t)) &_jit_cache_destroy, + (void * (*)(jit_memory_context_t, void *)) + &_jit_cache_find_function_info, + (jit_function_t (*)(jit_memory_context_t, void *)) &_jit_cache_get_function, - (void * (*)(jit_memory_context_t, jit_function_t)) + (void * (*)(jit_memory_context_t, void *)) &_jit_cache_get_function_start, - (void * (*)(jit_memory_context_t, jit_function_t)) + (void * (*)(jit_memory_context_t, void *)) &_jit_cache_get_function_end, (jit_function_t (*)(jit_memory_context_t)) diff --git a/jit/jit-memory.c b/jit/jit-memory.c index 8e8a25e..1fe7006 100644 --- a/jit/jit-memory.c +++ b/jit/jit-memory.c @@ -52,29 +52,36 @@ _jit_memory_destroy(jit_context_t context) context->memory_manager->destroy(context->memory_context); } -jit_function_t -_jit_memory_find_function(jit_context_t context, void *pc) +void * +_jit_memory_find_function_info(jit_context_t context, void *pc) { if(!context->memory_context) { return 0; } /* TODO: read lock? */ - return context->memory_manager->find_function(context->memory_context, pc); + return context->memory_manager->find_function_info(context->memory_context, pc); +} + +jit_function_t +_jit_memory_get_function(jit_context_t context, void *func_info) +{ + /* TODO: read lock? */ + return context->memory_manager->get_function(context->memory_context, func_info); } void * -_jit_memory_get_function_start(jit_context_t context, jit_function_t func) +_jit_memory_get_function_start(jit_context_t context, void *func_info) { /* TODO: read lock? */ - return context->memory_manager->get_function_start(context->memory_context, func); + return context->memory_manager->get_function_start(context->memory_context, func_info); } void * -_jit_memory_get_function_end(jit_context_t context, jit_function_t func) +_jit_memory_get_function_end(jit_context_t context, void *func_info) { /* TODO: read lock? */ - return context->memory_manager->get_function_end(context->memory_context, func); + return context->memory_manager->get_function_end(context->memory_context, func_info); } jit_function_t diff --git a/jit/jit-unwind.c b/jit/jit-unwind.c index 5276a2b..28623c3 100644 --- a/jit/jit-unwind.c +++ b/jit/jit-unwind.c @@ -167,17 +167,17 @@ jit_unwind_get_function(jit_unwind_context_t *unwind) if(!unwind->cache) { void *pc = jit_unwind_get_pc(unwind); - unwind->cache = _jit_memory_find_function(unwind->context, pc); + unwind->cache = _jit_memory_find_function_info(unwind->context, pc); } - return (jit_function_t) unwind->cache; + return _jit_memory_get_function(unwind->context, unwind->cache); } unsigned int jit_unwind_get_offset(jit_unwind_context_t *unwind) { - jit_function_t func; void *pc; + jit_function_t func; if(!unwind || !unwind->frame || !unwind->context) { @@ -190,11 +190,15 @@ jit_unwind_get_offset(jit_unwind_context_t *unwind) return JIT_NO_OFFSET; } - func = jit_unwind_get_function(unwind); + if(!unwind->cache) + { + unwind->cache = _jit_memory_find_function_info(unwind->context, pc); + } + func = _jit_memory_get_function(unwind->context, unwind->cache); if(!func) { return JIT_NO_OFFSET; } - return _jit_function_get_bytecode(func, pc, 0); + return _jit_function_get_bytecode(func, unwind->cache, pc, 0); }