From 5fa0d600d9a7ba685a3684f61f70b26fd98cff67 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Mon, 8 Oct 2012 21:38:26 +0400 Subject: [PATCH] Add functions to alloc and free trampoline and closure code memory. --- ChangeLog | 14 +++++++ include/jit/jit-apply.h | 2 - include/jit/jit-init.h | 7 ++++ jit/jit-apply.c | 54 ++++++++++++++++++++++++--- jit/jit-cache.c | 82 ++++++++++++++++++++++++++++++++++++++++- jit/jit-cache.h | 30 ++++++++++++--- jit/jit-function.c | 30 ++++++++------- 7 files changed, 191 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5eeeac..90fa0bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2012-10-08 Aleksey Demakov + + * jit/jit-cache.c, jit/jit-cache.c(_jit_cache_alloc_trampoline) + (_jit_cache_free_trampoline, _jit_cache_alloc_closure) + (_jit_cache_free_closure): add functions. + * jit/jit-function.c (jit_function_create, _jit_function_destroy): + use trampoline alloc/free functions. + + * jit/jit-apply.c, include/jit/jit-init.h (jit_get_closure_size) + (jit_get_closure_alignment, jit_get_trampoline_size) + (jit_get_trampoline_alignment): add functions. + * jit/jit-apply.c (jit_closures_supported): for consistency rename + function to jit_supports_closures. + 2012-10-07 Aleksey Demakov * jit/jit-function.c (jit_function_create, _jit_function_destroy): diff --git a/include/jit/jit-apply.h b/include/jit/jit-apply.h index 404a109..639d723 100644 --- a/include/jit/jit-apply.h +++ b/include/jit/jit-apply.h @@ -53,8 +53,6 @@ int jit_raw_supported(jit_type_t signature); void *jit_closure_create(jit_context_t context, jit_type_t signature, jit_closure_func func, void *user_data); -int jit_closures_supported(void); - jit_nint jit_closure_va_get_nint(jit_closure_va_list_t va); jit_nuint jit_closure_va_get_nuint(jit_closure_va_list_t va); jit_long jit_closure_va_get_long(jit_closure_va_list_t va); diff --git a/include/jit/jit-init.h b/include/jit/jit-init.h index e213bf2..5d1ce1e 100644 --- a/include/jit/jit-init.h +++ b/include/jit/jit-init.h @@ -35,6 +35,13 @@ int jit_supports_threads(void) JIT_NOTHROW; int jit_supports_virtual_memory(void) JIT_NOTHROW; +int jit_supports_closures(void); + +unsigned int jit_get_closure_size(void); +unsigned int jit_get_closure_alignment(void); +unsigned int jit_get_trampoline_size(void); +unsigned int jit_get_trampoline_alignment(void); + #ifdef __cplusplus }; #endif diff --git a/jit/jit-apply.c b/jit/jit-apply.c index 78e3ca3..4ace866 100644 --- a/jit/jit-apply.c +++ b/jit/jit-apply.c @@ -893,7 +893,7 @@ jit_closure_create(jit_context_t context, jit_type_t signature, jit_closure_func return 0; } - closure = (jit_closure_t)_jit_cache_alloc_no_method(cache, sizeof(struct jit_closure), jit_closure_align); + closure = (jit_closure_t)_jit_cache_alloc_closure(cache); if(!closure) { jit_mutex_unlock(&context->cache_lock); @@ -922,11 +922,12 @@ jit_closure_create(jit_context_t context, jit_type_t signature, jit_closure_func } /*@ - * @deftypefun int jit_closures_supported (void) + * @deftypefun int jit_supports_closures (void) * Determine if this platform has support for closures. * @end deftypefun @*/ -int jit_closures_supported(void) +int +jit_supports_closures(void) { #ifdef jit_closure_size return 1; @@ -935,6 +936,49 @@ int jit_closures_supported(void) #endif } +unsigned int +jit_get_closure_size(void) +{ +#ifdef jit_closure_size + return jit_closure_size; +#else + return 0; +#endif +} + +unsigned int +jit_get_closure_alignment(void) +{ +#ifdef jit_closure_size + return jit_closure_align; +#else + return 0; +#endif +} + +unsigned int +jit_get_trampoline_size(void) +{ + int size = 0; +#if defined(jit_redirector_size) + size += jit_redirector_size; +#endif +#if defined(jit_indirector_size) + size += jit_indirector_size; +#endif + return size; +} + +unsigned int +jit_get_trampoline_alignment(void) +{ +#if defined(jit_redirector_size) || defined(jit_indirector_size) + return 1; +#else + return 0; +#endif +} + /*@ * @deftypefun jit_nint jit_closure_va_get_nint (jit_closure_va_list_t @var{va}) * @deftypefunx jit_nuint jit_closure_va_get_nuint (jit_closure_va_list_t @var{va}) @@ -1009,8 +1053,8 @@ void *jit_closure_va_get_ptr(jit_closure_va_list_t va) * variable arguments, and copy it into @var{buf}. * @end deftypefun @*/ -void jit_closure_va_get_struct - (jit_closure_va_list_t va, void *buf, jit_type_t type) +void +jit_closure_va_get_struct(jit_closure_va_list_t va, void *buf, jit_type_t type) { #ifdef HAVE_JIT_BUILTIN_APPLY_STRUCT _jit_builtin_apply_get_struct(&(va->builder), buf, type); diff --git a/jit/jit-cache.c b/jit/jit-cache.c index bbc404f..1dac30c 100644 --- a/jit/jit-cache.c +++ b/jit/jit-cache.c @@ -521,7 +521,7 @@ _jit_cache_start_function(jit_cache_t cache, jit_function_t func) cache->prev_start = cache->free_start; cache->prev_end = cache->free_end; - /* Allocate memory for the function information block */ + /* Get the function information block */ cache->method = (jit_cache_method_t) (((char *) func) - offsetof(struct jit_cache_method, func)); @@ -631,6 +631,84 @@ _jit_cache_alloc_data(jit_cache_t cache, unsigned long size, unsigned long align return ptr; } +static void * +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) + { + return 0; + } + /* Bail out if there is no cache available */ + if(!cache->free_start) + { + return 0; + } + + /* Allocate aligned memory. */ + ptr = cache->free_start; + if(align > 1) + { + jit_nuint p = ((jit_nuint) ptr + align - 1) & ~(align - 1); + ptr = (unsigned char *) p; + } + + /* Do we need to allocate a new cache page? */ + if((ptr + size) > cache->free_end) + { + /* Allocate a new page */ + AllocCachePage(cache, 0); + + /* Bail out if the cache is full */ + if(!cache->free_start) + { + return 0; + } + + /* Allocate memory from the new page */ + ptr = cache->free_start; + if(align > 1) + { + jit_nuint p = ((jit_nuint) ptr + align - 1) & ~(align - 1); + ptr = (unsigned char *) p; + } + } + + /* Allocate the block and return it */ + cache->free_start = ptr + size; + return (void *) ptr; +} + +void * +_jit_cache_alloc_trampoline(jit_cache_t cache) +{ + return alloc_code(cache, + jit_get_trampoline_size(), + jit_get_trampoline_alignment()); +} + +void +_jit_cache_free_trampoline(jit_cache_t cache, void *trampoline) +{ + /* not supported yet */ +} + +void * +_jit_cache_alloc_closure(jit_cache_t cache) +{ + return alloc_code(cache, + jit_get_closure_size(), + jit_get_closure_alignment()); +} + +void +_jit_cache_free_closure(jit_cache_t cache, void *closure) +{ + /* not supported yet */ +} + void * _jit_cache_alloc_no_method(jit_cache_t cache, unsigned long size, unsigned long align) { @@ -680,7 +758,7 @@ _jit_cache_alloc_no_method(jit_cache_t cache, unsigned long size, unsigned long ptr = cache->free_end - size; ptr = (unsigned char *) (((jit_nuint) ptr) & ~((jit_nuint) align - 1)); } - + /* Allocate the block and return it */ cache->free_end = ptr; return (void *)ptr; diff --git a/jit/jit-cache.h b/jit/jit-cache.h index adf1d63..88889ef 100644 --- a/jit/jit-cache.h +++ b/jit/jit-cache.h @@ -64,12 +64,12 @@ void _jit_cache_destroy(jit_cache_t cache); void _jit_cache_extend(jit_cache_t cache, int count); /* - * Allocate a function description structure. + * Allocate a function information structure. */ jit_function_t _jit_cache_alloc_function(jit_cache_t cache); /* - * Release a function description structure. + * Release a function information structure. */ void _jit_cache_free_function(jit_cache_t cache, jit_function_t func); @@ -135,10 +135,30 @@ void *_jit_cache_alloc_data(jit_cache_t cache, unsigned long align); /* - * Allocate "size" bytes of storage when we aren't currently - * translating a method. + * Allocate memory for a trampoline. + * + * The required size and alignment can be determined with these functions: + * jit_get_trampoline_size(), jit_get_trampoline_alignment(). + */ +void *_jit_cache_alloc_trampoline(jit_cache_t cache); + +/* + * Free memory used by a trampoline. + */ +void _jit_cache_free_trampoline(jit_cache_t cache, void *trampoline); + +/* + * Allocate memory for a closure. + * + * The required size and alignment can be determined with these functions: + * jit_get_closure_size(), jit_get_closure_alignment(). + */ +void *_jit_cache_alloc_closure(jit_cache_t cache); + +/* + * Free memory used by a closure. */ -void *_jit_cache_alloc_no_method(jit_cache_t cache, unsigned long size, unsigned long align); +void _jit_cache_free_closure(jit_cache_t cache, void *closure); /* * Find the method that is associated with a particular diff --git a/jit/jit-function.c b/jit/jit-function.c index 65228fb..6a05958 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -49,6 +49,9 @@ jit_function_create(jit_context_t context, jit_type_t signature) { jit_function_t func; jit_cache_t cache; +#if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) + unsigned char *trampoline; +#endif /* We need the cache lock. */ jit_mutex_lock(&context->cache_lock); @@ -70,27 +73,19 @@ jit_function_create(jit_context_t context, jit_type_t signature) } #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 */ -# if defined(jit_redirector_size) - /* Allocate redirector buffer */ - func->redirector = _jit_cache_alloc_no_method(cache, jit_redirector_size, 1); - if(!func->redirector) + trampoline = (unsigned char *) _jit_cache_alloc_trampoline(cache); + if(!trampoline) { _jit_cache_free_function(cache, func); jit_mutex_unlock(&context->cache_lock); return 0; } +# if defined(jit_redirector_size) + func->redirector = trampoline; + trampoline += jit_redirector_size; # endif # if defined(jit_indirector_size) - /* Allocate indirector buffer */ - func->indirector = _jit_cache_alloc_no_method(cache, jit_indirector_size, 1); - if(!func->indirector) - { - _jit_cache_free_function(cache, func); - jit_mutex_unlock(&context->cache_lock); - return 0; - } + func->indirector = trampoline; # endif #endif /* !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) */ @@ -267,6 +262,13 @@ _jit_function_destroy(jit_function_t func) jit_type_free(func->signature); jit_mutex_lock(&context->cache_lock); +#if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || defined(jit_indirector_size)) +# if defined(jit_redirector_size) + _jit_cache_free_trampoline(context->cache, func->redirector); +# else + _jit_cache_free_trampoline(context->cache, func->indirector); +# endif +#endif _jit_cache_free_function(context->cache, func); jit_mutex_unlock(&context->cache_lock); } -- 2.47.3