]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add functions to alloc and free trampoline and closure code memory.
authorAleksey Demakov <ademakov@gmail.com>
Mon, 8 Oct 2012 17:38:26 +0000 (21:38 +0400)
committerAleksey Demakov <ademakov@gmail.com>
Mon, 8 Oct 2012 17:38:26 +0000 (21:38 +0400)
ChangeLog
include/jit/jit-apply.h
include/jit/jit-init.h
jit/jit-apply.c
jit/jit-cache.c
jit/jit-cache.h
jit/jit-function.c

index a5eeeacdb57721b54ae21b621abb99a8f046b45c..90fa0bbfdcdcbf5aa6e968132507c64cd6cad116 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2012-10-08  Aleksey Demakov  <ademakov@gmail.com>
+
+       * 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  <ademakov@gmail.com>
 
        * jit/jit-function.c (jit_function_create, _jit_function_destroy):
index 404a10909376828add39b01c7ce61591620d97a2..639d7238fb79396c13c8ee5a9daeaf28d1f68512 100644 (file)
@@ -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);
index e213bf240f426ed1c9d29c0f5702a2a4a8c2f1ea..5d1ce1e7d6865c3d625d05095706cae77e946d1a 100644 (file)
@@ -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
index 78e3ca3110068308fdfd3b9e27db57b6a494c396..4ace8668377e6364306bb657682549d258630c87 100644 (file)
@@ -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);
index bbc404f8ae1952ad4ca6dc4f1e95ec94c37bc8dc..1dac30ccc0779c7458a699029b3afc9b13d2e94c 100644 (file)
@@ -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;
index adf1d639003662c39acaf8da331e83b673dcc865..88889ef0abc44cbedd8e66a3bf37cdfd9ac578b7 100644 (file)
@@ -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
index 65228fbaa9d20464def68037d509810973d8594d..6a059584a2ddeed75e5f111288da5927d0ee7232 100644 (file)
@@ -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);
 }