Browse Source

Restore the ability to allocate memory for recompiled functions.

pull/1/head
Aleksey Demakov 12 years ago
parent
commit
568424e04c
  1. 6
      ChangeLog
  2. 7
      include/jit/jit-memory.h
  3. 5
      jit/jit-compile.c
  4. 31
      jit/jit-except.c
  5. 30
      jit/jit-function.c
  6. 9
      jit/jit-internal.h
  7. 152
      jit/jit-memory-cache.c
  8. 21
      jit/jit-memory.c
  9. 14
      jit/jit-unwind.c

6
ChangeLog

@ -1,3 +1,9 @@
2012-11-06 Aleksey Demakov <ademakov@gmail.com>
* 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 <ademakov@gmail.com>
* jitplus/jit-plus-function.cpp (create): free function signature.

7
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);

5
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);

31
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);
}
/*@

30
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
}

9
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);

152
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))

21
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

14
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);
}

Loading…
Cancel
Save