]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Restore the ability to allocate memory for recompiled functions.
authorAleksey Demakov <ademakov@gmail.com>
Tue, 6 Nov 2012 00:52:32 +0000 (03:52 +0300)
committerAleksey Demakov <ademakov@gmail.com>
Tue, 6 Nov 2012 00:52:32 +0000 (03:52 +0300)
ChangeLog
include/jit/jit-memory.h
jit/jit-compile.c
jit/jit-except.c
jit/jit-function.c
jit/jit-internal.h
jit/jit-memory-cache.c
jit/jit-memory.c
jit/jit-unwind.c

index 483ca5e91b947a313d6a100661c5e1f20544760b..0a945a0033efc58fc293a359d28f95876391a085 100644 (file)
--- a/ChangeLog
+++ b/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.
index 418b42bd0e682f5c9809cd20f3c863cdef49c80d..01487c377375540091f94cad5e3727b1c5b87083 100644 (file)
@@ -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);
index a443b9e3a5da8675164dc328a78977913c31c928..f66059c9886b08fec0fd4ff497000f7f4f54c2be 100644 (file)
@@ -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);
index a24389e4dbabb5e2863b4e03e4bf3c3ac4f33261..39da8ae68ff4d00a33f155ab104bc5172264e534 100644 (file)
@@ -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);
 }
 
 /*@
index edad6d7d36f9318870c613656d5fa319d7af6f67..0f886421f236c1dc6d5e722d0c7a477ed2495b8c 100644 (file)
@@ -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
 }
 
index 6e42e40f0311d951984529b721b273ae61c93c53..581bf1cee90c2a838f7962e99d3bc5d0be0c02f1 100644 (file)
@@ -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);
index 319955aff42f8b38fdf59afc7467531137c2ffaa..a17d6d7dc4ca5a1b5a4a697b8859b2e6d737702a 100644 (file)
@@ -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))
index 8e8a25ea0b79db71c0c7dee6cf5af07af4d77752..1fe7006e64ec11fec1eca3cce5677091d54712b9 100644 (file)
@@ -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
index 5276a2b442a58cbb60b903e8b1d6a905d9082fda..28623c32e69c607a366207495997d4ccc2e72344 100644 (file)
@@ -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);
 }