dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (l


From: Aleksey Demakov
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, cache-refactoring, updated. adb07727736e4c061f2bf4e2072af00f9a45acf2
Date: Tue, 16 Oct 2012 08:31:01 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET Just In Time compiler (libjit)".

The branch, cache-refactoring has been updated
       via  adb07727736e4c061f2bf4e2072af00f9a45acf2 (commit)
      from  ca560895bb9027748b7e3c7fbfaa027c252bfe47 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=adb07727736e4c061f2bf4e2072af00f9a45acf2

commit adb07727736e4c061f2bf4e2072af00f9a45acf2
Author: Aleksey Demakov <address@hidden>
Date:   Tue Oct 16 12:30:27 2012 +0400

    Add plugable memory manager interface.

diff --git a/ChangeLog b/ChangeLog
index 8f3514c..d6d1876 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-16  Aleksey Demakov  <address@hidden>
+
+       * include/jit/jit-memory.h: add file that defines pluggable memory
+       manager interface.
+       * jit-internal.h, jit/jit-memory.c: add a number of _jit_memory_*
+       pluggable memory wrapper functions. Replace with these wrappers
+       all _jit_cache_* calls.
+       * jit/jit-cache.c (jit_default_memory_manager): add function that
+       gets memory mamnager plugin interface.
+       * jit/jit-cache.h: remove file.
+       * include/jit/jit-context.h:
+       * jit/jit-context.c (jit_context_set_memory_manager): add function.
+
 2012-10-12  Aleksey Demakov  <address@hidden>
 
        * include/jit/jit-util.h, jit/jit-alloc.c (jit_malloc_exec)
diff --git a/include/jit/Makefile.am b/include/jit/Makefile.am
index 3e84067..f56e402 100644
--- a/include/jit/Makefile.am
+++ b/include/jit/Makefile.am
@@ -19,6 +19,7 @@ dist_libjitinclude_HEADERS = \
        jit-init.h \
        jit-insn.h \
        jit-intrinsic.h \
+       jit-memory.h \
        jit-meta.h \
        jit-objmodel.h \
        jit-objmodel-private.h \
diff --git a/include/jit/jit-context.h b/include/jit/jit-context.h
index cce58a6..cfa1ec0 100644
--- a/include/jit/jit-context.h
+++ b/include/jit/jit-context.h
@@ -22,6 +22,7 @@
 #define        _JIT_CONTEXT_H
 
 #include <jit/jit-common.h>
+#include <jit/jit-memory.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -29,11 +30,18 @@ extern      "C" {
 
 jit_context_t jit_context_create(void) JIT_NOTHROW;
 void jit_context_destroy(jit_context_t context) JIT_NOTHROW;
+
 void jit_context_build_start(jit_context_t context) JIT_NOTHROW;
 void jit_context_build_end(jit_context_t context) JIT_NOTHROW;
+
 void jit_context_set_on_demand_driver(
        jit_context_t context,
        jit_on_demand_driver_func driver) JIT_NOTHROW;
+
+void jit_context_set_memory_manager(
+       jit_context_t context,
+       jit_memory_manager_t manager) JIT_NOTHROW;
+
 int jit_context_set_meta
        (jit_context_t context, int type, void *data,
         jit_meta_free_func free_data) JIT_NOTHROW;
diff --git a/include/jit/jit-memory.h b/include/jit/jit-memory.h
new file mode 100644
index 0000000..1d8e68f
--- /dev/null
+++ b/include/jit/jit-memory.h
@@ -0,0 +1,79 @@
+/*
+ * jit-memory.h - Memory management.
+ *
+ * Copyright (C) 2012  Southern Storm Software, Pty Ltd.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _JIT_MEMORY_H
+#define        _JIT_MEMORY_H
+
+#include <jit/jit-defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Result values for "_jit_cache_start_function" and "_jit_cache_end_function".
+ */
+#define        JIT_MEMORY_OK           0       /* Function is OK */
+#define        JIT_MEMORY_RESTART      1       /* Restart is required */
+#define        JIT_MEMORY_TOO_BIG      2       /* Function is too big for the 
cache */
+#define JIT_MEMORY_ERROR       3       /* Other error */
+
+
+/* TODO: the proper place for this is jit-def.h and it's going to depend on 
the platform. */
+typedef unsigned int jit_size_t;
+
+typedef void *jit_memory_context_t;
+
+typedef struct jit_memory_manager const* jit_memory_manager_t;
+
+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);
+
+       jit_function_t (*alloc_function)(jit_memory_context_t memctx);
+       void (*free_function)(jit_memory_context_t memctx, jit_function_t func);
+
+       int (*start_function)(jit_memory_context_t memctx, jit_function_t func);
+       int (*end_function)(jit_memory_context_t memctx, int result);
+       int (*extend_limit)(jit_memory_context_t memctx, int count);
+
+       void * (*get_limit)(jit_memory_context_t memctx);
+       void * (*get_break)(jit_memory_context_t memctx);
+       void (*set_break)(jit_memory_context_t memctx, void *brk);
+
+       void * (*alloc_trampoline)(jit_memory_context_t memctx);
+       void (*free_trampoline)(jit_memory_context_t memctx, void *ptr);
+
+       void * (*alloc_closure)(jit_memory_context_t memctx);
+       void (*free_closure)(jit_memory_context_t memctx, void *ptr);
+
+       void * (*alloc_data)(jit_memory_context_t memctx, jit_size_t size, 
jit_size_t align);
+};
+
+jit_memory_manager_t jit_default_memory_manager(void) JIT_NOTHROW;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _JIT_MEMORY_H */
diff --git a/jit/Makefile.am b/jit/Makefile.am
index eda454c..f61bda7 100644
--- a/jit/Makefile.am
+++ b/jit/Makefile.am
@@ -17,7 +17,6 @@ libjit_la_SOURCES = \
        jit-bitset.h \
        jit-bitset.c \
        jit-block.c \
-       jit-cache.h \
        jit-cache.c \
        jit-compile.c \
        jit-config.h \
@@ -45,6 +44,7 @@ libjit_la_SOURCES = \
        jit-interp-opcode.c \
        jit-intrinsic.c \
        jit-live.c \
+       jit-memory.c \
        jit-meta.c \
        jit-opcode-apply.c \
        jit-objmodel.c \
diff --git a/jit/jit-apply.c b/jit/jit-apply.c
index 0b4ecef..393658d 100644
--- a/jit/jit-apply.c
+++ b/jit/jit-apply.c
@@ -23,7 +23,6 @@
 #include "jit-internal.h"
 #include "jit-apply-rules.h"
 #include "jit-apply-func.h"
-#include "jit-cache.h"
 #if HAVE_STDLIB_H
        #include <stdlib.h>
 #endif
@@ -872,7 +871,6 @@ void *
 jit_closure_create(jit_context_t context, jit_type_t signature, 
jit_closure_func func, void *user_data)
 {
 #ifdef jit_closure_size
-       jit_cache_t cache;
        jit_closure_t closure;
 
        /* Validate the parameters */
@@ -881,21 +879,19 @@ jit_closure_create(jit_context_t context, jit_type_t 
signature, jit_closure_func
                return 0;
        }
 
-       /* Acquire the cache lock while we do this */
-       jit_mutex_lock(&context->cache_lock);
-
-       /* Allocate space for the closure within the context's function cache */
-       cache = _jit_context_get_cache(context);
-       if(!cache)
+       /* Acquire the memory context */
+       _jit_memory_lock(context);
+       if(!_jit_memory_ensure(context))
        {
-               jit_mutex_unlock(&context->cache_lock);
+               _jit_memory_unlock(context);
                return 0;
        }
 
-       closure = (jit_closure_t)_jit_cache_alloc_closure(cache);
+       /* Allocate memory space for the closure */
+       closure = (jit_closure_t) _jit_memory_alloc_closure(context);
        if(!closure)
        {
-               jit_mutex_unlock(&context->cache_lock);
+               _jit_memory_unlock(context);
                return 0;
        }
 
@@ -905,12 +901,12 @@ jit_closure_create(jit_context_t context, jit_type_t 
signature, jit_closure_func
        closure->func = func;
        closure->user_data = user_data;
 
+       /* Release the memory context, as we are finished with it */
+       _jit_memory_unlock(context);
+
        /* Perform a cache flush on the closure's code */
        _jit_flush_exec(closure->buf, sizeof(closure->buf));
 
-       /* Unlock the cache, as we are finished with it */
-       jit_mutex_unlock(&context->cache_lock);
-
        /* Return the completed closure to the caller */
        return closure;
 
diff --git a/jit/jit-cache.c b/jit/jit-cache.c
index 62536ce..58ec608 100644
--- a/jit/jit-cache.c
+++ b/jit/jit-cache.c
@@ -25,7 +25,6 @@ See the bottom of this file for documentation on the cache 
system.
 */
 
 #include "jit-internal.h"
-#include "jit-cache.h"
 #include "jit-apply-func.h"
 
 #include <stddef.h> /* for offsetof */
@@ -76,7 +75,7 @@ struct jit_cache_page
 /*
  * Structure of the method cache.
  */
-#define        JIT_CACHE_DEBUG_SIZE            64
+typedef struct jit_cache *jit_cache_t;
 struct jit_cache
 {
        struct jit_cache_page   *pages;         /* List of pages currently in 
the cache */
@@ -117,6 +116,8 @@ struct jit_cache
 #define        SetBlack(node)  \
        ((node)->left = (jit_cache_method_t)(((jit_nuint)(node)->left) & 
~((jit_nuint)1)))
 
+void _jit_cache_destroy(jit_cache_t cache);
+
 /*
  * Allocate a cache page and add it to the cache.
  */
@@ -517,13 +518,13 @@ _jit_cache_start_function(jit_cache_t cache, 
jit_function_t func)
        /* Bail out if there is a started function already */
        if(cache->method)
        {
-               return JIT_CACHE_ERROR;
+               return JIT_MEMORY_ERROR;
        }
 
        /* Bail out if the cache is already full */
        if(!cache->free_start)
        {
-               return JIT_CACHE_TOO_BIG;
+               return JIT_MEMORY_TOO_BIG;
        }
 
        /* Save the cache position */
@@ -540,7 +541,7 @@ _jit_cache_start_function(jit_cache_t cache, jit_function_t 
func)
        cache->method->left = 0;
        cache->method->right = 0;
 
-       return JIT_CACHE_OK;
+       return JIT_MEMORY_OK;
 }
 
 int
@@ -549,17 +550,17 @@ _jit_cache_end_function(jit_cache_t cache, int result)
        /* Bail out if there is no started function */
        if(!cache->method)
        {
-               return JIT_CACHE_ERROR;
+               return JIT_MEMORY_ERROR;
        }
 
        /* Determine if we ran out of space while writing the function */
-       if(result != JIT_CACHE_OK || cache->free_start >= cache->free_end)
+       if(result != JIT_MEMORY_OK || cache->free_start >= cache->free_end)
        {
                /* Restore the saved cache position */
                cache->free_start = cache->prev_start;
                cache->free_end = cache->prev_end;
                cache->method = 0;
-               return JIT_CACHE_RESTART;
+               return JIT_MEMORY_RESTART;
        }
 
        /* Update the method region block and then add it to the lookup tree */
@@ -568,7 +569,7 @@ _jit_cache_end_function(jit_cache_t cache, int result)
        cache->method = 0;
 
        /* The method is ready to go */
-       return JIT_CACHE_OK;
+       return JIT_MEMORY_OK;
 }
 
 void *
@@ -797,6 +798,30 @@ _jit_cache_get_function(jit_cache_t cache, void *pc)
        return 0;
 }
 
+jit_memory_manager_t
+jit_default_memory_manager(void)
+{
+       static const struct jit_memory_manager mm = {
+               &_jit_cache_create,
+               &_jit_cache_destroy,
+               &_jit_cache_get_function,
+               &_jit_cache_alloc_function,
+               &_jit_cache_free_function,
+               &_jit_cache_start_function,
+               &_jit_cache_end_function,
+               &_jit_cache_extend,
+               &_jit_cache_get_code_limit,
+               &_jit_cache_get_code_break,
+               &_jit_cache_set_code_break,
+               &_jit_cache_alloc_trampoline,
+               &_jit_cache_free_trampoline,
+               &_jit_cache_alloc_closure,
+               &_jit_cache_free_closure,
+               &_jit_cache_alloc_data
+       };
+       return &mm;
+}
+
 /*
 
 Using the cache
diff --git a/jit/jit-cache.h b/jit/jit-cache.h
deleted file mode 100644
index 5f23d02..0000000
--- a/jit/jit-cache.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * jit-cache.h - Translated function cache implementation.
- *
- * Copyright (C) 2002, 2004, 2008  Southern Storm Software, Pty Ltd.
- *
- * This file is part of the libjit library.
- *
- * The libjit library is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation, either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * The libjit library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the libjit library.  If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        _JIT_CACHE_H
-#define        _JIT_CACHE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Result values for "_jit_cache_start_function" and "_jit_cache_end_function".
- */
-#define        JIT_CACHE_OK            0       /* Function is OK */
-#define        JIT_CACHE_RESTART       1       /* Restart is required */
-#define        JIT_CACHE_TOO_BIG       2       /* Function is too big for the 
cache */
-#define JIT_CACHE_ERROR                3       /* Other error */
-
-/*
- * Create a code cache.  Returns NULL if out of memory.
- * If "limit" is non-zero, then it specifies the maximum
- * size of the cache in bytes.  If "cache_page_size" is
- * non-zero, then it indicates the dafault/minimum cache
- * page size.  If "max_page_factor" is not zero, then it
- * indicates the maximum cache page size as multiple of
- * "max_page_factor" and "cache_page_size".
- */
-jit_cache_t _jit_cache_create(jit_context_t context);
-
-/*
- * Destroy a code cache.
- */
-void _jit_cache_destroy(jit_cache_t cache);
-
-/*
- * Request to allocate more code cache space.
- *
- * The "count" value should normally be zero except if just after the last
- * call a function is being recompiled again because it is still too big
- * to fit into the available cache space. In this case the "count" value
- * should gradually increase.
- */
-void _jit_cache_extend(jit_cache_t cache, int count);
-
-/*
- * Allocate a function information structure.
- */
-jit_function_t _jit_cache_alloc_function(jit_cache_t cache);
-
-/*
- * Release a function information structure.
- */
-void _jit_cache_free_function(jit_cache_t cache, jit_function_t func);
-
-/*
- * Start output of a function.
- */
-int _jit_cache_start_function(jit_cache_t cache, jit_function_t func);
-
-/*
- * End output of a function. 
- */
-int _jit_cache_end_function(jit_cache_t cache, int result);
-
-/*
- * Get the start address of memory available for function code generation.
- *
- * This function is only called betweed _jit_cache_start_function() and
- * corresponding _jit_cache_end_function() calls.
- *
- * Initially it should return the start address of the allocated memory.
- * Then the address may be moved forward with _jit_cache_set_code_break()
- * calls.
- */
-void *_jit_cache_get_code_break(jit_cache_t cache);
-
-/*
- * Set the address of memory yet available for function code generation.
- *
- * This function is only called betweed _jit_cache_start_function() and
- * corresponding _jit_cache_end_function() calls.
- *
- * The given address must be greater than or equal to its last value as
- * returned by the _jit_cache_get_code_break() call and also less than or
- * equal to the memory the address returned by _jit_cache_get_code_limit()
- * call.
- *
- * This function is to be used in two cases.  First, on the end of code
- * generation just before the _jit_cache_end_function() call. Second,
- * before allocating data with _jit_cache_alloc_data() calls. This lets
- * the cache know how much space was actually used and how much is still
- * free.
- */
-void _jit_cache_set_code_break(jit_cache_t cache, void *ptr);
-
-/*
- * Get the end address of memory available for function code generation.
- *
- * This function is only called betweed _jit_cache_start_function() and
- * corresponding _jit_cache_end_function() calls.
- *
- * The available memory may change if during code generation there were
- * _jit_cache_alloc_data() calls.  So after such calls available memory
- * should be rechecked.
- */
-void *_jit_cache_get_code_limit(jit_cache_t cache);
-
-/*
- * Allocate "size" bytes of memory in the data area.  Returns NULL if
- * there is insufficient space to satisfy the request.
- */
-void *_jit_cache_alloc_data(jit_cache_t cache,
-                           unsigned long size,
-                           unsigned long align);
-
-/*
- * 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_free_closure(jit_cache_t cache, void *closure);
-
-/*
- * Find the method that is associated with a particular
- * program counter.  Returns NULL if the PC is not associated
- * with a method within the cache.
- */
-jit_function_t _jit_cache_get_function(jit_cache_t cache, void *pc);
-
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* _JIT_CACHE_H */
diff --git a/jit/jit-compile.c b/jit/jit-compile.c
index 151e381..88b8946 100644
--- a/jit/jit-compile.c
+++ b/jit/jit-compile.c
@@ -385,15 +385,16 @@ cleanup_on_restart(jit_gencode_t gen, jit_function_t func)
 static void
 cache_acquire(_jit_compile_t *state)
 {
-       /* Acquire the cache lock */
-       jit_mutex_lock(&state->func->context->cache_lock);
+       /* Store the function's context as codegen context */
+       state->gen.context = state->func->context;
+
+       /* Acquire the memory context lock */
+       _jit_memory_lock(state->gen.context);
 
        /* Remember that the lock is acquired */
        state->cache_locked = 1;
 
-       /* Get the method cache */
-       state->gen.cache = _jit_context_get_cache(state->func->context);
-       if(!state->gen.cache)
+       if(!_jit_memory_ensure(state->gen.context))
        {
                jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
        }
@@ -408,7 +409,7 @@ cache_release(_jit_compile_t *state)
        /* Release the lock if it was previously acquired */
        if(state->cache_locked)
        {
-               jit_mutex_unlock(&state->func->context->cache_lock);
+               _jit_memory_unlock(state->gen.context);
                state->cache_locked = 0;
        }
 }
@@ -462,20 +463,20 @@ cache_alloc(_jit_compile_t *state)
        int result;
 
        /* First try with the current cache page */
-       result = _jit_cache_start_function(state->gen.cache, state->func);
-       if(result == JIT_CACHE_RESTART)
+       result = _jit_memory_start_function(state->gen.context, state->func);
+       if(result == JIT_MEMORY_RESTART)
        {
                /* No space left on the current cache page.  Allocate a new 
one. */
-               _jit_cache_extend(state->gen.cache, state->page_factor++);
-               result = _jit_cache_start_function(state->gen.cache, 
state->func);
+               _jit_memory_extend_limit(state->gen.context, 
state->page_factor++);
+               result = _jit_memory_start_function(state->gen.context, 
state->func);
        }
-       if(result != JIT_CACHE_OK)
+       if(result != JIT_MEMORY_OK)
        {
                /* Failed to allocate any cache space */
                jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
        }
-       state->gen.ptr = _jit_cache_get_code_break(state->gen.cache);
-       state->gen.limit = _jit_cache_get_code_limit(state->gen.cache); 
+       state->gen.ptr = _jit_memory_get_break(state->gen.context);
+       state->gen.limit = _jit_memory_get_limit(state->gen.context); 
 
        /* Align the function code. */
        cache_align(state, JIT_FUNCTION_ALIGNMENT, JIT_FUNCTION_ALIGNMENT, 0);
@@ -500,13 +501,13 @@ cache_flush(_jit_compile_t *state)
                state->cache_started = 0;
 
                /* Let the cache know where we are */
-               _jit_cache_set_code_break(state->gen.cache, state->gen.ptr);
+               _jit_memory_set_break(state->gen.context, state->gen.ptr);
 
                /* End the function's output process */
-               result = _jit_cache_end_function(state->gen.cache, 
JIT_CACHE_OK);
-               if(result != JIT_CACHE_OK)
+               result = _jit_memory_end_function(state->gen.context, 
JIT_MEMORY_OK);
+               if(result != JIT_MEMORY_OK)
                {
-                       if(result == JIT_CACHE_RESTART)
+                       if(result == JIT_MEMORY_RESTART)
                        {
                                /* Throw an internal exception that causes
                                   a larger code space to be allocated and
@@ -547,7 +548,7 @@ cache_abort(_jit_compile_t *state)
                state->cache_started = 0;
 
                /* Release the cache space */
-               _jit_cache_end_function(state->gen.cache, JIT_CACHE_RESTART);
+               _jit_memory_end_function(state->gen.context, 
JIT_MEMORY_RESTART);
 
                /* Free encoded bytecode offset data */
                
_jit_varint_free_data(_jit_varint_get_data(&state->gen.offset_encoder));
@@ -567,15 +568,15 @@ cache_realloc(_jit_compile_t *state)
 
        /* Allocate a new cache page with the size that grows
           by factor of 2 on each reallocation */
-       _jit_cache_extend(state->gen.cache, state->page_factor++);
-       result = _jit_cache_start_function(state->gen.cache, state->func);
-       if(result != JIT_CACHE_OK)
+       _jit_memory_extend_limit(state->gen.context, state->page_factor++);
+       result = _jit_memory_start_function(state->gen.context, state->func);
+       if(result != JIT_MEMORY_OK)
        {
                /* Failed to allocate enough cache space */
                jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
        }
-       state->gen.ptr = _jit_cache_get_code_break(state->gen.cache);
-       state->gen.limit = _jit_cache_get_code_limit(state->gen.cache);
+       state->gen.ptr = _jit_memory_get_break(state->gen.context);
+       state->gen.limit = _jit_memory_get_limit(state->gen.context);
 
        /* Align the function code. */
        cache_align(state, JIT_FUNCTION_ALIGNMENT, JIT_FUNCTION_ALIGNMENT, 0);
@@ -1015,14 +1016,11 @@ unsigned long
 _jit_function_get_bytecode(jit_function_t func, void *pc, int exact)
 {
        unsigned long offset = JIT_CACHE_NO_OFFSET;
-       jit_cache_t cache;
        void *start;
        unsigned long native_offset;
        jit_varint_decoder_t decoder;
        jit_uint off, noff;
 
-       cache = _jit_context_get_cache(func->context);
-
 #ifdef JIT_PROLOG_SIZE
        start = func->code_start;
 #else
diff --git a/jit/jit-context.c b/jit/jit-context.c
index db66fc4..a38d93f 100644
--- a/jit/jit-context.c
+++ b/jit/jit-context.c
@@ -21,7 +21,6 @@
  */
 
 #include "jit-internal.h"
-#include "jit-cache.h"
 
 /*@
 
@@ -71,7 +70,8 @@ ultimately destroy JIT contexts:
  * if out of memory.
  * @end deftypefun
 @*/
-jit_context_t jit_context_create(void)
+jit_context_t
+jit_context_create(void)
 {
        jit_context_t context;
 
@@ -86,11 +86,12 @@ jit_context_t jit_context_create(void)
        }
 
        /* Initialize the context and return it */
-       jit_mutex_create(&(context->builder_lock));
-       jit_mutex_create(&(context->cache_lock));
+       jit_mutex_create(&context->memory_lock);
+       jit_mutex_create(&context->builder_lock);
        context->functions = 0;
        context->last_function = 0;
        context->on_demand_driver = _jit_function_compile_on_demand;
+       context->memory_manager = jit_default_memory_manager();
        return context;
 }
 
@@ -101,28 +102,33 @@ jit_context_t jit_context_create(void)
  * running compiled code when this function is called.
  * @end deftypefun
 @*/
-void jit_context_destroy(jit_context_t context)
+void
+jit_context_destroy(jit_context_t context)
 {
        int sym;
-       if(context)
+
+       if(!context)
+       {
+               return;
+       }
+
+       for(sym = 0; sym < context->num_registered_symbols; ++sym)
+       {
+               jit_free(context->registered_symbols[sym]);
+       }
+       jit_free(context->registered_symbols);
+
+       while(context->functions != 0)
        {
-               while(context->functions != 0)
-               {
-                       _jit_function_destroy(context->functions);
-               }
-               if(context->cache)
-               {
-                       _jit_cache_destroy(context->cache);
-               }
-               for(sym = 0; sym < context->num_registered_symbols; ++sym)
-               {
-                       jit_free(context->registered_symbols[sym]);
-               }
-               jit_free(context->registered_symbols);
-               jit_mutex_destroy(&(context->cache_lock));
-               jit_mutex_destroy(&(context->builder_lock));
-               jit_free(context);
+               _jit_function_destroy(context->functions);
        }
+
+       _jit_memory_destroy(context);
+
+       jit_mutex_destroy(&context->memory_lock);
+       jit_mutex_destroy(&context->builder_lock);
+
+       jit_free(context);
 }
 
 /*@
@@ -133,9 +139,10 @@ void jit_context_destroy(jit_context_t context)
  * can be performing build operations at any one time.
  * @end deftypefun
 @*/
-void jit_context_build_start(jit_context_t context)
+void
+jit_context_build_start(jit_context_t context)
 {
-       jit_mutex_lock(&(context->builder_lock));
+       jit_mutex_lock(&context->builder_lock);
 }
 
 /*@
@@ -146,9 +153,10 @@ void jit_context_build_start(jit_context_t context)
  * that are waiting on the builder to proceed.
  * @end deftypefun
 @*/
-void jit_context_build_end(jit_context_t context)
+void
+jit_context_build_end(jit_context_t context)
 {
-       jit_mutex_unlock(&(context->builder_lock));
+       jit_mutex_unlock(&context->builder_lock);
 }
 
 /*@
@@ -185,8 +193,7 @@ void jit_context_build_end(jit_context_t context)
  * or @code{JIT_RESULT_OUT_OF_MEMORY} will be thrown.
  *
  * @item
- * The entry point of the compiled function is returned from the
- * driver.
+ * The entry point of the compiled function is returned from the driver.
  * @end enumerate
  *
  * You may need to provide your own driver if some additional actions
@@ -194,7 +201,8 @@ void jit_context_build_end(jit_context_t context)
  *
  * @end deftypefun
 @*/
-void jit_context_set_on_demand_driver(jit_context_t context, 
jit_on_demand_driver_func driver)
+void
+jit_context_set_on_demand_driver(jit_context_t context, 
jit_on_demand_driver_func driver)
 {
        if (driver)
        {
@@ -207,6 +215,31 @@ void jit_context_set_on_demand_driver(jit_context_t 
context, jit_on_demand_drive
 }
 
 /*@
+ * @deftypefun void jit_context_set_memory_manager (jit_context_t 
@var{context}, jit_memory_manager_t @var{manager})
+ * Specify the memory manager plug-in.
+ * @end deftypefun
address@hidden/
+void
+jit_context_set_memory_manager(jit_context_t context, jit_memory_manager_t 
manager)
+{
+       /* Bail out if there is already an established memory context */
+       if (context->memory_context)
+       {
+               return;
+       }
+
+       /* Set the context memory manager */
+       if (manager)
+       {
+               context->memory_manager = manager;
+       }
+       else
+       {
+               context->memory_manager = jit_default_memory_manager();
+       }
+}
+
+/*@
  * @deftypefun int jit_context_set_meta (jit_context_t @var{context}, int 
@var{type}, void address@hidden, jit_meta_free_func @var{free_data})
  * Tag a context with some metadata.  Returns zero if out of memory.
  *
@@ -220,9 +253,8 @@ void jit_context_set_on_demand_driver(jit_context_t 
context, jit_on_demand_drive
  * the previous value will be freed.
  * @end deftypefun
 @*/
-int jit_context_set_meta
-       (jit_context_t context, int type, void *data,
-        jit_meta_free_func free_data)
+int
+jit_context_set_meta(jit_context_t context, int type, void *data, 
jit_meta_free_func free_data)
 {
        return jit_meta_set(&(context->meta), type, data, free_data, 0);
 }
@@ -272,8 +304,8 @@ int jit_context_set_meta
  * Metadata type values of 10000 or greater are reserved for internal use.
  * @end deftypefun
 @*/
-int jit_context_set_meta_numeric
-       (jit_context_t context, int type, jit_nuint data)
+int
+jit_context_set_meta_numeric(jit_context_t context, int type, jit_nuint data)
 {
        return jit_meta_set(&(context->meta), type, (void *)data, 0, 0);
 }
@@ -284,7 +316,8 @@ int jit_context_set_meta_numeric
  * if @var{type} does not have any metadata associated with it.
  * @end deftypefun
 @*/
-void *jit_context_get_meta(jit_context_t context, int type)
+void *
+jit_context_get_meta(jit_context_t context, int type)
 {
        return jit_meta_get(context->meta, type);
 }
@@ -296,7 +329,8 @@ void *jit_context_get_meta(jit_context_t context, int type)
  * This version is more convenient for the pre-defined numeric option values.
  * @end deftypefun
 @*/
-jit_nuint jit_context_get_meta_numeric(jit_context_t context, int type)
+jit_nuint
+jit_context_get_meta_numeric(jit_context_t context, int type)
 {
        return (jit_nuint)jit_meta_get(context->meta, type);
 }
@@ -307,17 +341,8 @@ jit_nuint jit_context_get_meta_numeric(jit_context_t 
context, int type)
  * the @var{type} does not have any metadata associated with it.
  * @end deftypefun
 @*/
-void jit_context_free_meta(jit_context_t context, int type)
+void
+jit_context_free_meta(jit_context_t context, int type)
 {
        jit_meta_free(&(context->meta), type);
 }
-
-struct jit_cache *
-_jit_context_get_cache(jit_context_t context)
-{
-       if(!context->cache)
-       {
-               context->cache = _jit_cache_create(context);
-       }
-       return context->cache;
-}
diff --git a/jit/jit-elf-read.c b/jit/jit-elf-read.c
index 7d23e46..bb1d670 100644
--- a/jit/jit-elf-read.c
+++ b/jit/jit-elf-read.c
@@ -1422,10 +1422,13 @@ void jit_readelf_add_to_context(jit_readelf_t readelf, 
jit_context_t context)
        {
                return;
        }
-       jit_mutex_lock(&(context->cache_lock));
+
+       _jit_memory_lock(context);
+
        readelf->next = context->elf_binaries;
        context->elf_binaries = readelf;
-       jit_mutex_unlock(&(context->cache_lock));
+
+       _jit_memory_unlock(context);
 }
 
 /*
@@ -1773,13 +1776,15 @@ static int perform_relocations
 @*/
 int jit_readelf_resolve_all(jit_context_t context, int print_failures)
 {
-       jit_readelf_t readelf;
        int ok = 1;
+       jit_readelf_t readelf;
        if(!context)
        {
                return 0;
        }
-       jit_mutex_lock(&(context->cache_lock));
+
+       _jit_memory_lock(context);
+
        readelf = context->elf_binaries;
        while(readelf != 0)
        {
@@ -1793,7 +1798,8 @@ int jit_readelf_resolve_all(jit_context_t context, int 
print_failures)
                }
                readelf = readelf->next;
        }
-       jit_mutex_unlock(&(context->cache_lock));
+
+       _jit_memory_unlock(context);
        return ok;
 }
 
diff --git a/jit/jit-except.c b/jit/jit-except.c
index 91054e7..a24389e 100644
--- a/jit/jit-except.c
+++ b/jit/jit-except.c
@@ -392,16 +392,12 @@ unsigned int jit_stack_trace_get_size(jit_stack_trace_t 
trace)
  * @var{posn} within the stack trace.
  * @end deftypefun
 @*/
-jit_function_t jit_stack_trace_get_function
-       (jit_context_t context, jit_stack_trace_t trace, unsigned int posn)
+jit_function_t
+jit_stack_trace_get_function(jit_context_t context, jit_stack_trace_t trace, 
unsigned int posn)
 {
        if(trace && posn < trace->size)
        {
-               jit_cache_t cache = _jit_context_get_cache(context);
-               if(cache)
-               {
-                       return _jit_cache_get_function(cache, 
trace->items[posn]);
-               }
+               return _jit_memory_find_function(context, trace->items[posn]);
        }
        return 0;
 }
@@ -433,19 +429,15 @@ void *jit_stack_trace_get_pc
  * is no bytecode offset associated with @var{posn}.
  * @end deftypefun
 @*/
-unsigned int jit_stack_trace_get_offset
-       (jit_context_t context, jit_stack_trace_t trace, unsigned int posn)
+unsigned int
+jit_stack_trace_get_offset(jit_context_t context, jit_stack_trace_t trace, 
unsigned int posn)
 {
        if(trace && posn < trace->size)
        {
-               jit_cache_t cache = _jit_context_get_cache(context);
-               if(cache)
+               jit_function_t func = _jit_memory_find_function(context, 
trace->items[posn]);
+               if (func)
                {
-                       jit_function_t func = _jit_cache_get_function(cache, 
trace->items[posn]);
-                       if (func)
-                       {
-                               return _jit_function_get_bytecode(func, 
trace->items[posn], 0);
-                       }
+                       return _jit_function_get_bytecode(func, 
trace->items[posn], 0);
                }
        }
        return JIT_NO_OFFSET;
diff --git a/jit/jit-function.c b/jit/jit-function.c
index b8c5768..edad6d7 100644
--- a/jit/jit-function.c
+++ b/jit/jit-function.c
@@ -22,7 +22,6 @@
 
 #include "jit-internal.h"
 #include "jit-apply-func.h"
-#include "jit-cache.h"
 #include "jit-rules.h"
 #include "jit-setjmp.h"
 
@@ -48,36 +47,32 @@ jit_function_t
 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);
-
-       /* Get the method cache */
-       cache = _jit_context_get_cache(context);
-       if(!cache)
+       /* Acquire the memory context */
+       _jit_memory_lock(context);
+       if(!_jit_memory_ensure(context))
        {
-               jit_mutex_unlock(&context->cache_lock);
+               _jit_memory_unlock(context);
                return 0;
        }
 
        /* Allocate memory for the function and clear it */
-       func = _jit_cache_alloc_function(cache);
+       func = _jit_memory_alloc_function(context);
        if(!func)
        {
-               jit_mutex_unlock(&context->cache_lock);
+               _jit_memory_unlock(context);
                return 0;
        }
 
 #if !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || 
defined(jit_indirector_size))
-       trampoline = (unsigned char *) _jit_cache_alloc_trampoline(cache);
+       trampoline = (unsigned char *) _jit_memory_alloc_trampoline(context);
        if(!trampoline)
        {
-               _jit_cache_free_function(cache, func);
-               jit_mutex_unlock(&context->cache_lock);
+               _jit_memory_free_function(context, func);
+               _jit_memory_unlock(context);
                return 0;
        }
 # if defined(jit_redirector_size)
@@ -89,7 +84,8 @@ jit_function_create(jit_context_t context, jit_type_t 
signature)
 # endif
 #endif /* !defined(JIT_BACKEND_INTERP) && (defined(jit_redirector_size) || 
defined(jit_indirector_size)) */
 
-       jit_mutex_unlock(&context->cache_lock);
+       /* Release the memory context */
+       _jit_memory_unlock(context);
 
        /* Initialize the function block */
        func->context = context;
@@ -261,16 +257,18 @@ _jit_function_destroy(jit_function_t func)
        jit_meta_destroy(&func->meta);
        jit_type_free(func->signature);
 
-       jit_mutex_lock(&context->cache_lock);
+       _jit_memory_lock(context);
+
 #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);
+       _jit_memory_free_trampoline(context, func->redirector);
 # else
-       _jit_cache_free_trampoline(context->cache, func->indirector);
+       _jit_memory_free_trampoline(context, func->indirector);
 # endif
 #endif
-       _jit_cache_free_function(context->cache, func);
-       jit_mutex_unlock(&context->cache_lock);
+       _jit_memory_free_function(context, func);
+
+       _jit_memory_unlock(context);
 }
 
 /*@
@@ -647,13 +645,14 @@ void *jit_function_to_closure(jit_function_t func)
  * closure does not correspond to a function in the specified context.
  * @end deftypefun
 @*/
-jit_function_t jit_function_from_closure(jit_context_t context, void *closure)
+jit_function_t 
+jit_function_from_closure(jit_context_t context, void *closure)
 {
-       if(!context || !(context->cache))
+       if(!context)
        {
                return 0;
        }
-       return _jit_cache_get_function(context->cache, closure);
+       return _jit_memory_find_function(context, closure);
 }
 
 /*@
@@ -664,40 +663,37 @@ jit_function_t jit_function_from_closure(jit_context_t 
context, void *closure)
  * under the control of @var{context}.
  * @end deftypefun
 @*/
-jit_function_t jit_function_from_pc
-       (jit_context_t context, void *pc, void **handler)
+jit_function_t
+jit_function_from_pc(jit_context_t context, void *pc, void **handler)
 {
        jit_function_t func;
-       void *cookie;
 
-       /* Bail out if we don't have a function cache yet */
-       if(!context || !(context->cache))
+       if(!context)
        {
                return 0;
        }
 
        /* Get the function and the exception handler cookie */
-       func = _jit_cache_get_function(context->cache, pc);
+       func = _jit_memory_find_function(context, pc);
        if(!func)
        {
                return 0;
        }
-       cookie = func->cookie;
 
        /* Convert the cookie into a handler address */
        if(handler)
        {
 #if 0
-               if(cookie)
+               if(func->cookie)
                {
-                       *handler = ((jit_cache_eh_t)cookie)->handler;
+                       *handler = ((jit_cache_eh_t) func->cookie)->handler;
                }
                else
                {
                        *handler = 0;
                }
 #else
-               *handler = cookie;
+               *handler = func->cookie;
 #endif
        }
        return func;
@@ -716,7 +712,8 @@ jit_function_t jit_function_from_pc
  * guaranteed.  Closures can be used with @code{jit_insn_call_indirect}.
  * @end deftypefun
 @*/
-void *jit_function_to_vtable_pointer(jit_function_t func)
+void *
+jit_function_to_vtable_pointer(jit_function_t func)
 {
 #ifdef JIT_BACKEND_INTERP
        /* In the interpreted version, the function pointer is used in vtables 
*/
@@ -741,7 +738,8 @@ void *jit_function_to_vtable_pointer(jit_function_t func)
  * vtable_pointer does not correspond to a function in the specified context.
  * @end deftypefun
 @*/
-jit_function_t jit_function_from_vtable_pointer(jit_context_t context, void 
*vtable_pointer)
+jit_function_t
+jit_function_from_vtable_pointer(jit_context_t context, void *vtable_pointer)
 {
 #ifdef JIT_BACKEND_INTERP
        /* In the interpreted version, the function pointer is used in vtables 
*/
@@ -753,11 +751,11 @@ jit_function_t 
jit_function_from_vtable_pointer(jit_context_t context, void *vta
        }
        return 0;
 #else
-       if(!context || !(context->cache))
+       if(!context)
        {
                return 0;
        }
-       return _jit_cache_get_function(context->cache, vtable_pointer);
+       return _jit_memory_find_function(context, vtable_pointer);
 #endif
 }
 
diff --git a/jit/jit-internal.h b/jit/jit-internal.h
index fe68aef..bf32490 100644
--- a/jit/jit-internal.h
+++ b/jit/jit-internal.h
@@ -62,10 +62,6 @@
 # define jit_memchr(s, c, len)         (memchr((s), (c), (len)))
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
  * We need the apply rules for "jit_redirector_size".
  */
@@ -81,9 +77,9 @@ extern        "C" {
  */
 #include "jit-varint.h"
 
-void *_jit_malloc_exec(unsigned int size);
-void _jit_free_exec(void *ptr, unsigned int size);
-void _jit_flush_exec(void *ptr, unsigned int size);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
  * The following is some macro magic that attempts to detect
@@ -149,11 +145,6 @@ _JIT_ALIGN_CHECK_TYPE(jit_nfloat, nfloat);
 #define        JIT_ALIGN_PTR                   _JIT_ALIGN_FOR_TYPE(ptr)
 
 /*
- * Opaque function cache type.
- */
-typedef struct jit_cache *jit_cache_t;
-
-/*
  * Structure of a memory pool.
  */
 typedef struct jit_pool_block *jit_pool_block_t;
@@ -573,12 +564,14 @@ struct jit_regsym
  */
 struct _jit_context
 {
+       /* The context's memory control */
+       jit_memory_manager_t    memory_manager;
+       jit_memory_context_t    memory_context;
+       jit_mutex_t             memory_lock;
+
        /* Lock that controls access to the building process */
        jit_mutex_t             builder_lock;
 
-       /* Lock that controls access to the function code cache */
-       jit_mutex_t             cache_lock;
-
        /* List of functions that are currently registered with the context */
        jit_function_t          functions;
        jit_function_t          last_function;
@@ -586,9 +579,6 @@ struct _jit_context
        /* Metadata that is associated with the context */
        jit_meta_t              meta;
 
-       /* The context's function code cache */
-       struct jit_cache        *cache;
-
        /* ELF binaries that have been loaded into this context */
        jit_readelf_t           elf_binaries;
 
@@ -604,6 +594,32 @@ struct _jit_context
        jit_on_demand_driver_func       on_demand_driver;
 };
 
+void *_jit_malloc_exec(unsigned int size);
+void _jit_free_exec(void *ptr, unsigned int size);
+void _jit_flush_exec(void *ptr, unsigned int size);
+
+void _jit_memory_lock(jit_context_t context);
+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);
+
+jit_function_t _jit_memory_alloc_function(jit_context_t context);
+void _jit_memory_free_function(jit_context_t context, jit_function_t func);
+int _jit_memory_start_function(jit_context_t context, jit_function_t func);
+int _jit_memory_end_function(jit_context_t context, int result);
+int _jit_memory_extend_limit(jit_context_t context, int count);
+void *_jit_memory_get_limit(jit_context_t context);
+void *_jit_memory_get_break(jit_context_t context);
+void _jit_memory_set_break(jit_context_t context, void *brk);
+void *_jit_memory_alloc_trampoline(jit_context_t context);
+void _jit_memory_free_trampoline(jit_context_t context, void *ptr);
+void *_jit_memory_alloc_closure(jit_context_t context);
+void _jit_memory_free_closure(jit_context_t context, void *ptr);
+void *_jit_memory_alloc_data(jit_context_t context, jit_size_t size, 
jit_size_t align);
+
 /*
  * Backtrace control structure, for managing stack traces.
  * These structures must be allocated on the stack.
@@ -645,11 +661,6 @@ struct jit_thread_control
 };
 
 /*
- * Get the function code cache for a context, creating it if necessary.
- */
-struct jit_cache *_jit_context_get_cache(jit_context_t context);
-
-/*
  * Initialize the block list for a function.
  */
 int _jit_block_init(jit_function_t func);
diff --git a/jit/jit-memory.c b/jit/jit-memory.c
new file mode 100644
index 0000000..b743361
--- /dev/null
+++ b/jit/jit-memory.c
@@ -0,0 +1,142 @@
+/*
+ * jit-memory.c - Memory management.
+ *
+ * Copyright (C) 2012  Southern Storm Software, Pty Ltd.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "jit-internal.h"
+
+void
+_jit_memory_lock(jit_context_t context)
+{
+       jit_mutex_lock(&context->memory_lock);
+}
+
+void
+_jit_memory_unlock(jit_context_t context)
+{
+       jit_mutex_unlock(&context->memory_lock);
+}
+
+int
+_jit_memory_ensure(jit_context_t context)
+{
+       if(!context->memory_context)
+       {
+               context->memory_context = 
context->memory_manager->create(context);
+       }
+       return (context->memory_context != 0);
+}
+
+void 
+_jit_memory_destroy(jit_context_t context)
+{
+       if(!context->memory_context)
+       {
+               return;
+       }
+       context->memory_manager->destroy(context->memory_context);
+}
+
+jit_function_t
+_jit_memory_find_function(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);
+}
+
+jit_function_t
+_jit_memory_alloc_function(jit_context_t context)
+{
+       return context->memory_manager->alloc_function(context->memory_context);
+}
+
+void
+_jit_memory_free_function(jit_context_t context, jit_function_t func)
+{
+       context->memory_manager->free_function(context->memory_context, func);
+}
+
+int
+_jit_memory_start_function(jit_context_t context, jit_function_t func)
+{
+       return context->memory_manager->start_function(context->memory_context, 
func);
+}
+
+int
+_jit_memory_end_function(jit_context_t context, int result)
+{
+       return context->memory_manager->end_function(context->memory_context, 
result);
+}
+
+int
+_jit_memory_extend_limit(jit_context_t context, int count)
+{
+       return context->memory_manager->extend_limit(context->memory_context, 
count);
+}
+
+void *
+_jit_memory_get_limit(jit_context_t context)
+{
+       return context->memory_manager->get_limit(context->memory_context);
+}
+
+void *
+_jit_memory_get_break(jit_context_t context)
+{
+       return context->memory_manager->get_break(context->memory_context);
+}
+
+void
+_jit_memory_set_break(jit_context_t context, void *brk)
+{
+       context->memory_manager->set_break(context->memory_context, brk);
+}
+
+void *
+_jit_memory_alloc_trampoline(jit_context_t context)
+{
+       return 
context->memory_manager->alloc_trampoline(context->memory_context);
+}
+
+void
+_jit_memory_free_trampoline(jit_context_t context, void *ptr)
+{
+       context->memory_manager->free_trampoline(context->memory_context, ptr);
+}
+
+void *
+_jit_memory_alloc_closure(jit_context_t context)
+{
+       return context->memory_manager->alloc_closure(context->memory_context);
+}
+
+void
+_jit_memory_free_closure(jit_context_t context, void *ptr)
+{
+       context->memory_manager->free_closure(context->memory_context, ptr);
+}
+
+void *
+_jit_memory_alloc_data(jit_context_t context, jit_size_t size, jit_size_t 
align)
+{
+       return context->memory_manager->alloc_data(context->memory_context, 
size, align);
+}
diff --git a/jit/jit-rules.c b/jit/jit-rules.c
index 32f5a10..874f1cb 100644
--- a/jit/jit-rules.c
+++ b/jit/jit-rules.c
@@ -752,13 +752,13 @@ void *
 _jit_gen_alloc(jit_gencode_t gen, unsigned long size)
 {
        void *ptr;
-       _jit_cache_set_code_break(gen->cache, gen->ptr);
-       ptr = _jit_cache_alloc_data(gen->cache, size, JIT_BEST_ALIGNMENT);
+       _jit_memory_set_break(gen->context, gen->ptr);
+       ptr = _jit_memory_alloc_data(gen->context, size, JIT_BEST_ALIGNMENT);
        if(!ptr)
        {
                jit_exception_builtin(JIT_RESULT_CACHE_FULL);
        }
-       gen->limit = _jit_cache_get_code_limit(gen->cache);
+       gen->limit = _jit_memory_get_limit(gen->context);
        return ptr;
 }
 
diff --git a/jit/jit-rules.h b/jit/jit-rules.h
index 6af7e87..bc023b8 100644
--- a/jit/jit-rules.h
+++ b/jit/jit-rules.h
@@ -24,7 +24,6 @@
 #define        _JIT_RULES_H
 
 #include "jit-config.h"
-#include "jit-cache.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -159,7 +158,7 @@ struct jit_regcontents
 typedef struct jit_gencode *jit_gencode_t;
 struct jit_gencode
 {
-       jit_cache_t             cache;          /* Cache this position is 
attached to */
+       jit_context_t           context;        /* Context this position is 
attached to */
        unsigned char           *ptr;           /* Current code pointer */
        unsigned char           *limit;         /* Current code space limit */
        jit_regused_t           permanent;      /* Permanently allocated global 
regs */
diff --git a/jit/jit-unwind.c b/jit/jit-unwind.c
index 8e91fdf..5276a2b 100644
--- a/jit/jit-unwind.c
+++ b/jit/jit-unwind.c
@@ -21,7 +21,6 @@
  */
 
 #include "jit-internal.h"
-#include "jit-cache.h"
 #include "jit-rules.h"
 #include "jit-apply-rules.h"
 #include <jit/jit-unwind.h>
@@ -167,9 +166,8 @@ jit_unwind_get_function(jit_unwind_context_t *unwind)
 
        if(!unwind->cache)
        {
-               jit_cache_t cache = _jit_context_get_cache(unwind->context);
                void *pc = jit_unwind_get_pc(unwind);
-               unwind->cache = _jit_cache_get_function(cache, pc);
+               unwind->cache = _jit_memory_find_function(unwind->context, pc);
        }
 
        return (jit_function_t) unwind->cache;

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                 |   13 ++++
 include/jit/Makefile.am   |    1 +
 include/jit/jit-context.h |    8 ++
 include/jit/jit-memory.h  |   79 ++++++++++++++++++++
 jit/Makefile.am           |    2 +-
 jit/jit-apply.c           |   24 +++----
 jit/jit-cache.c           |   43 +++++++++---
 jit/jit-cache.h           |  173 ---------------------------------------------
 jit/jit-compile.c         |   50 ++++++-------
 jit/jit-context.c         |  119 +++++++++++++++++++------------
 jit/jit-elf-read.c        |   16 +++--
 jit/jit-except.c          |   24 ++----
 jit/jit-function.c        |   72 +++++++++----------
 jit/jit-internal.h        |   57 +++++++++------
 jit/jit-memory.c          |  142 +++++++++++++++++++++++++++++++++++++
 jit/jit-rules.c           |    6 +-
 jit/jit-rules.h           |    3 +-
 jit/jit-unwind.c          |    4 +-
 18 files changed, 477 insertions(+), 359 deletions(-)
 create mode 100644 include/jit/jit-memory.h
 delete mode 100644 jit/jit-cache.h
 create mode 100644 jit/jit-memory.c


hooks/post-receive
-- 
DotGNU Portable.NET Just In Time compiler (libjit)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]