From 6257ec334769bbffa3741497ac39362de131f94c Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 7 Oct 2012 15:19:16 +0400 Subject: [PATCH] Allocate jit_functions within cache. --- ChangeLog | 7 ++++++ jit/jit-cache.c | 49 ++++++++++++++++++++---------------- jit/jit-cache.h | 10 ++++++++ jit/jit-function.c | 63 +++++++++++++++++++++++++--------------------- 4 files changed, 80 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 036b35d..a5eeeac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-10-07 Aleksey Demakov + + * jit/jit-function.c (jit_function_create, _jit_function_destroy): + * jit/jit-cache.h, jit/jit-cache.c (_jit_cache_alloc_function) + (_jit_cache_free_function): allocate and free jit_function structs + within cache. + 2012-10-04 Aleksey Demakov * jit/jit-cache.h, jit/jit-cache.c (_jit_cache_start_function): diff --git a/jit/jit-cache.c b/jit/jit-cache.c index 5ab3cab..bbc404f 100644 --- a/jit/jit-cache.c +++ b/jit/jit-cache.c @@ -28,6 +28,8 @@ See the bottom of this file for documentation on the cache system. #include "jit-cache.h" #include "jit-apply-func.h" +#include /* for offsetof */ + #ifdef __cplusplus extern "C" { #endif @@ -57,9 +59,9 @@ extern "C" { typedef struct jit_cache_method *jit_cache_method_t; struct jit_cache_method { - jit_function_t func; /* Function */ jit_cache_method_t left; /* Left sub-tree and red/black bit */ jit_cache_method_t right; /* Right sub-tree */ + struct _jit_function func; /* Function */ }; /* @@ -213,11 +215,11 @@ CacheCompare(jit_cache_t cache, unsigned char *key, jit_cache_method_t node) else { /* Compare a regular node */ - if(key < node->func->code_start) + if(key < node->func.code_start) { return -1; } - else if(key > node->func->code_start) + else if(key > node->func.code_start) { return 1; } @@ -297,7 +299,7 @@ CacheRotate(jit_cache_t cache, unsigned char *key, jit_cache_method_t around) static void AddToLookupTree(jit_cache_t cache, jit_cache_method_t method) { - unsigned char *key = method->func->code_start; + unsigned char *key = method->func.code_start; jit_cache_method_t temp; jit_cache_method_t greatGrandParent; jit_cache_method_t grandParent; @@ -410,10 +412,8 @@ _jit_cache_create(long limit, long cache_page_size, int max_page_factor) cache->pagesLeft = -1; } cache->method = 0; - cache->nil.func = 0; cache->nil.left = &(cache->nil); cache->nil.right = &(cache->nil); - cache->head.func = 0; cache->head.left = 0; cache->head.right = &(cache->nil); @@ -487,6 +487,21 @@ _jit_cache_extend(jit_cache_t cache, int count) AllocCachePage(cache, factor); } +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; +} + +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); +} + int _jit_cache_start_function(jit_cache_t cache, jit_function_t func) { @@ -508,19 +523,11 @@ _jit_cache_start_function(jit_cache_t cache, jit_function_t func) /* Allocate memory for the function information block */ cache->method = (jit_cache_method_t) - _jit_cache_alloc_data(cache, - sizeof(struct jit_cache_method), - JIT_BEST_ALIGNMENT); - if(!cache->method) - { - /* There is insufficient space in this page */ - return JIT_CACHE_RESTART; - } + (((char *) func) - offsetof(struct jit_cache_method, func)); /* Initialize the function information */ - cache->method->func = func; - cache->method->func->code_start = cache->free_start; - cache->method->func->code_end = cache->free_start; + cache->method->func.code_start = cache->free_start; + cache->method->func.code_end = cache->free_start; cache->method->left = 0; cache->method->right = 0; @@ -547,7 +554,7 @@ _jit_cache_end_function(jit_cache_t cache, int result) } /* Update the method region block and then add it to the lookup tree */ - cache->method->func->code_end = cache->free_start; + cache->method->func.code_end = cache->free_start; AddToLookupTree(cache, cache->method); cache->method = 0; @@ -685,17 +692,17 @@ _jit_cache_get_function(jit_cache_t cache, void *pc) jit_cache_method_t node = cache->head.right; while(node != &(cache->nil)) { - if(((unsigned char *)pc) < node->func->code_start) + if(((unsigned char *)pc) < node->func.code_start) { node = GetLeft(node); } - else if(((unsigned char *)pc) >= node->func->code_end) + else if(((unsigned char *)pc) >= node->func.code_end) { node = GetRight(node); } else { - return node->func; + return &node->func; } } return 0; diff --git a/jit/jit-cache.h b/jit/jit-cache.h index 016f004..adf1d63 100644 --- a/jit/jit-cache.h +++ b/jit/jit-cache.h @@ -63,6 +63,16 @@ void _jit_cache_destroy(jit_cache_t cache); */ void _jit_cache_extend(jit_cache_t cache, int count); +/* + * Allocate a function description structure. + */ +jit_function_t _jit_cache_alloc_function(jit_cache_t cache); + +/* + * Release a function description structure. + */ +void _jit_cache_free_function(jit_cache_t cache, jit_function_t func); + /* * Start output of a function. */ diff --git a/jit/jit-function.c b/jit/jit-function.c index 96897d1..65228fb 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -44,43 +44,41 @@ * data structures within a multi-threaded environment. * @end deftypefun @*/ -jit_function_t jit_function_create(jit_context_t context, jit_type_t signature) +jit_function_t +jit_function_create(jit_context_t context, jit_type_t signature) { jit_function_t func; -#if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) jit_cache_t cache; -#endif + + /* We need the cache lock. */ + jit_mutex_lock(&context->cache_lock); + + /* Get the method cache */ + cache = _jit_context_get_cache(context); + if(!cache) + { + jit_mutex_unlock(&context->cache_lock); + return 0; + } /* Allocate memory for the function and clear it */ - func = jit_cnew(struct _jit_function); + func = _jit_cache_alloc_function(cache); if(!func) { + jit_mutex_unlock(&context->cache_lock); return 0; } #if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) /* TODO: if the function is destroyed the redirector and indirector memory is leaked */ - - /* We need the cache lock while we are allocating redirector and indirector */ - jit_mutex_lock(&(context->cache_lock)); - - /* Get the method cache */ - cache = _jit_context_get_cache(context); - if(!cache) - { - jit_mutex_unlock(&(context->cache_lock)); - jit_free(func); - return 0; - } - # if defined(jit_redirector_size) /* Allocate redirector buffer */ func->redirector = _jit_cache_alloc_no_method(cache, jit_redirector_size, 1); if(!func->redirector) { - jit_mutex_unlock(&(context->cache_lock)); - jit_free(func); + _jit_cache_free_function(cache, func); + jit_mutex_unlock(&context->cache_lock); return 0; } # endif @@ -89,15 +87,15 @@ jit_function_t jit_function_create(jit_context_t context, jit_type_t signature) func->indirector = _jit_cache_alloc_no_method(cache, jit_indirector_size, 1); if(!func->indirector) { - jit_mutex_unlock(&(context->cache_lock)); - jit_free(func); + _jit_cache_free_function(cache, func); + jit_mutex_unlock(&context->cache_lock); return 0; } # endif - - jit_mutex_unlock(&(context->cache_lock)); #endif /* !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) */ + jit_mutex_unlock(&context->cache_lock); + /* Initialize the function block */ func->context = context; func->signature = jit_type_copy(signature); @@ -235,19 +233,24 @@ void _jit_function_free_builder(jit_function_t func) } } -void _jit_function_destroy(jit_function_t func) +void +_jit_function_destroy(jit_function_t func) { + jit_context_t context; + if(!func) { return; } + + context = func->context; if(func->next) { func->next->prev = func->prev; } else { - func->context->last_function = func->prev; + context->last_function = func->prev; } if(func->prev) { @@ -255,13 +258,17 @@ void _jit_function_destroy(jit_function_t func) } else { - func->context->functions = func->next; + context->functions = func->next; } + _jit_function_free_builder(func); _jit_varint_free_data(func->bytecode_offset); - jit_meta_destroy(&(func->meta)); + jit_meta_destroy(&func->meta); jit_type_free(func->signature); - jit_free(func); + + jit_mutex_lock(&context->cache_lock); + _jit_cache_free_function(context->cache, func); + jit_mutex_unlock(&context->cache_lock); } /*@ -- 2.47.3