+#ifdef USE_JUMP_TABLES
+
+#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
+
+typedef struct MonoJumpTableChunk {
+ guint32 total;
+ guint32 active;
+ struct MonoJumpTableChunk *previous;
+ /* gpointer entries[total]; */
+} MonoJumpTableChunk;
+
+static MonoJumpTableChunk* g_jumptable;
+#define mono_jumptable_lock() mono_mutex_lock (&jumptable_mutex)
+#define mono_jumptable_unlock() mono_mutex_unlock (&jumptable_mutex)
+static mono_mutex_t jumptable_mutex;
+
+static MonoJumpTableChunk*
+mono_create_jumptable_chunk (guint32 max_entries)
+{
+ guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
+ MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
+ chunk->total = max_entries;
+ return chunk;
+}
+
+void
+mono_jumptable_init (void)
+{
+ if (g_jumptable == NULL) {
+ mono_mutex_init_recursive (&jumptable_mutex);
+ g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
+ }
+}
+
+gpointer*
+mono_jumptable_add_entry (void)
+{
+ return mono_jumptable_add_entries (1);
+}
+
+gpointer*
+mono_jumptable_add_entries (guint32 entries)
+{
+ guint32 index;
+ gpointer *result;
+
+ mono_jumptable_init ();
+ mono_jumptable_lock ();
+ index = g_jumptable->active;
+ if (index + entries >= g_jumptable->total) {
+ /*
+ * Grow jumptable, by adding one more chunk.
+ * We cannot realloc jumptable, as there could be pointers
+ * to existing jump table entries in the code, so instead
+ * we just add one more chunk.
+ */
+ guint32 max_entries = entries;
+ MonoJumpTableChunk *new_chunk;
+
+ if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
+ max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
+ new_chunk = mono_create_jumptable_chunk (max_entries);
+ /* Link old jumptable, so that we could free it up later. */
+ new_chunk->previous = g_jumptable;
+ g_jumptable = new_chunk;
+ index = 0;
+ }
+ g_jumptable->active = index + entries;
+ result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
+ mono_jumptable_unlock();
+
+ return result;
+}
+
+void
+mono_jumptable_cleanup (void)
+{
+ if (g_jumptable) {
+ MonoJumpTableChunk *current = g_jumptable, *prev;
+ while (current != NULL) {
+ prev = current->previous;
+ g_free (current);
+ current = prev;
+ }
+ g_jumptable = NULL;
+ mono_mutex_destroy (&jumptable_mutex);
+ }
+}
+
+gpointer*
+mono_jumptable_get_entry (guint8 *code_ptr)
+{
+ return mono_arch_jumptable_entry_from_code (code_ptr);
+}
+
+#endif /* USE_JUMP_TABLES */
+