#include <mono/metadata/mono-config.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/mono-debug.h>
-#include <mono/metadata/gc-internal.h>
+#include <mono/metadata/gc-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/verify.h>
#include <mono/metadata/verify-internals.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
-#include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-path.h>
#include <mono/utils/mono-tls.h>
#include "mini-gc.h"
#include "debugger-agent.h"
+#include "llvm-runtime.h"
MonoTraceSpec *mono_jit_trace_calls;
MonoMethodDesc *mono_inject_async_exc_method;
#define mono_jit_unlock() mono_mutex_unlock (&jit_mutex)
static mono_mutex_t jit_mutex;
+MonoBackend *current_backend;
+
+#ifndef DISABLE_JIT
+
gpointer
mono_realloc_native_code (MonoCompile *cfg)
{
}
#endif /* __native_client_codegen__ */
+#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 */
+
typedef struct {
MonoExceptionClause *clause;
MonoBasicBlock *basic_block;
return -1;
}
-static guint
-mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
-{
- type = mini_get_underlying_type (type);
- if (cfg->gshared && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
- g_assert (mini_type_var_is_vt (type));
- return CEE_LDOBJ;
- }
- return mono_type_to_ldind (type);
-}
-
-#ifndef DISABLE_JIT
-
guint
mini_type_to_stind (MonoCompile* cfg, MonoType *type)
{
bb->max_vreg = MAX (bb->max_vreg, cfg->next_vreg);
}
-#endif
-
static void
set_vreg_to_inst (MonoCompile *cfg, int vreg, MonoInst *inst)
{
#define mono_type_is_long(type) (!(type)->byref && ((mono_type_get_underlying_type (type)->type == MONO_TYPE_I8) || (mono_type_get_underlying_type (type)->type == MONO_TYPE_U8)))
#define mono_type_is_float(type) (!(type)->byref && (((type)->type == MONO_TYPE_R8) || ((type)->type == MONO_TYPE_R4)))
-#ifdef DISABLE_JIT
-
-MonoInst*
-mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
-{
- return NULL;
-}
-
-#else
-
MonoInst*
mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, int vreg)
{
return mono_compile_create_var_for_vreg (cfg, type, opcode, dreg);
}
-/*
- * Transform a MonoInst into a load from the variable of index var_index.
- */
-void
-mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index)
-{
- memset (dest, 0, sizeof (MonoInst));
- dest->inst_i0 = cfg->varinfo [var_index];
- dest->opcode = mini_type_to_ldind (cfg, dest->inst_i0->inst_vtype);
- type_to_eval_stack_type (cfg, dest->inst_i0->inst_vtype, dest);
- dest->klass = dest->inst_i0->klass;
-}
-
MonoInst*
mini_get_int_to_float_spill_area (MonoCompile *cfg)
{
#endif
}
-#endif
-
void
mono_mark_vreg_as_ref (MonoCompile *cfg, int vreg)
{
}
static MonoType*
-type_from_stack_type (MonoInst *ins) {
+type_from_stack_type (MonoInst *ins)
+{
switch (ins->type) {
case STACK_I4: return &mono_defaults.int32_class->byval_arg;
case STACK_I8: return &mono_defaults.int64_class->byval_arg;
}
MonoType*
-mono_type_from_stack_type (MonoInst *ins) {
+mono_type_from_stack_type (MonoInst *ins)
+{
return type_from_stack_type (ins);
}
return 1;
}
-#ifndef DISABLE_JIT
-
#if 0
#define LSCAN_DEBUG(a) do { a; } while (0)
#else
return offsets;
}
-#else
-
-gint32*
-mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-#endif /* DISABLE_JIT */
-
#define EMUL_HIT_SHIFT 3
#define EMUL_HIT_MASK ((1 << EMUL_HIT_SHIFT) - 1)
/* small hit bitmap cache */
}
static void
-print_dfn (MonoCompile *cfg) {
+print_dfn (MonoCompile *cfg)
+{
int i, j;
char *code;
MonoBasicBlock *bb;
void
mono_destroy_compile (MonoCompile *cfg)
{
-#ifndef DISABLE_JIT
GSList *l;
if (cfg->header)
g_free (cfg->vars);
g_free (cfg->exception_message);
g_free (cfg);
-#endif
}
-#ifndef DISABLE_JIT
-
static MonoInst*
mono_create_tls_get_offset (MonoCompile *cfg, int offset)
{
MonoInst* ins;
- if (!MONO_ARCH_HAVE_TLS_GET)
+ if (!cfg->backend->have_tls_get)
return NULL;
if (offset == -1)
gboolean
mini_tls_get_supported (MonoCompile *cfg, MonoTlsKey key)
{
- if (!MONO_ARCH_HAVE_TLS_GET)
+ if (!cfg->backend->have_tls_get)
return FALSE;
if (cfg->compile_aot)
- return ARCH_HAVE_TLS_GET_REG;
+ return cfg->backend->have_tls_get_reg;
else
return mini_get_tls_offset (key) != -1;
}
MonoInst*
mono_create_tls_get (MonoCompile *cfg, MonoTlsKey key)
{
- if (!MONO_ARCH_HAVE_TLS_GET)
+ if (!cfg->backend->have_tls_get)
return NULL;
/*
* use a different opcode.
*/
if (cfg->compile_aot) {
- if (ARCH_HAVE_TLS_GET_REG) {
+ if (cfg->backend->have_tls_get_reg) {
MonoInst *ins, *c;
EMIT_NEW_TLS_OFFSETCONST (cfg, c, key);
return mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
}
-#endif /* !DISABLE_JIT */
-
-
void
mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
{
cfg->rgctx_loclist = g_slist_append_mempool (cfg->mempool, cfg->rgctx_loclist, entry);
}
-#ifndef DISABLE_JIT
-
static void
mono_compile_create_vars (MonoCompile *cfg)
{
}
}
-#endif /* #ifndef DISABLE_JIT */
-
-static MonoJitInfo*
-create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
-{
- MonoDomain *domain = mono_get_root_domain ();
- MonoJitInfo *jinfo;
- guint8 *uw_info;
- guint32 info_len;
-
- if (info->uw_info) {
- uw_info = info->uw_info;
- info_len = info->uw_info_len;
- } else {
- uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
- }
-
- jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
- jinfo->d.method = wrapper;
- jinfo->code_start = info->code;
- jinfo->code_size = info->code_size;
- jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
-
- if (!info->uw_info)
- g_free (uw_info);
-
- return jinfo;
-}
-
-#ifndef DISABLE_JIT
-
static MonoJitInfo*
create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
{
* Extend the try block backwards to include parts of the previous call
* instruction.
*/
- ei->try_start = (guint8*)ei->try_start - MONO_ARCH_MONITOR_ENTER_ADJUSTMENT;
+ ei->try_start = (guint8*)ei->try_start - cfg->backend->monitor_enter_adjustment;
}
tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len];
g_assert (tblock);
return jinfo;
}
-#endif
/* Return whenever METHOD is a gsharedvt method */
static gboolean
return FALSE;
}
-#ifndef DISABLE_JIT
-
-#if defined(__native_client_codegen__) || USE_COOP_GC
-
static void
mono_create_gc_safepoint (MonoCompile *cfg, MonoBasicBlock *bblock)
{
#if defined(__native_client_codegen__)
NEW_AOTCONST (cfg, poll_addr, MONO_PATCH_INFO_GC_SAFE_POINT_FLAG, (gpointer)&__nacl_thread_suspension_needed);
#else
+ g_assert (mono_threads_is_coop_enabled ());
NEW_AOTCONST (cfg, poll_addr, MONO_PATCH_INFO_GC_SAFE_POINT_FLAG, (gpointer)&mono_polling_required);
#endif
mono_insert_safepoints (MonoCompile *cfg)
{
MonoBasicBlock *bb;
+
+#if !defined(__native_client_codegen__)
+ if (!mono_threads_is_coop_enabled ())
+ return;
+#endif
+
if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
#if defined(__native_client__) || defined(__native_client_codegen__)
gpointer poll_func = &mono_nacl_gc;
-#elif defined(USE_COOP_GC)
- gpointer poll_func = &mono_threads_state_poll;
#else
- gpointer poll_func = NULL;
+ g_assert (mono_threads_is_coop_enabled ());
+ gpointer poll_func = &mono_threads_state_poll;
#endif
if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER && info->d.icall.func == poll_func) {
}
}
+ if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
+ if (cfg->verbose_level > 1)
+ printf ("SKIPPING SAFEPOINTS for native-to-managed wrappers.\n");
+ return;
+ }
+
+ if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
+
+ if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER &&
+ (info->d.icall.func == mono_thread_interruption_checkpoint ||
+ info->d.icall.func == mono_threads_finish_blocking ||
+ info->d.icall.func == mono_threads_reset_blocking_start)) {
+ /* These wrappers are called from the wrapper for the polling function, leading to potential stack overflow */
+ if (cfg->verbose_level > 1)
+ printf ("SKIPPING SAFEPOINTS for wrapper %s\n", cfg->method->name);
+ return;
+ }
+ }
if (cfg->verbose_level > 1)
printf ("INSERTING SAFEPOINTS\n");
}
-#else
-
static void
-mono_insert_safepoints (MonoCompile *cfg)
+init_backend (MonoBackend *backend)
{
-}
-
+#ifdef MONO_ARCH_NEED_GOT_VAR
+ backend->need_got_var = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_CARD_TABLE_WBARRIER
+ backend->have_card_table_wb = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT
+ backend->have_op_generic_class_init = 1;
+#endif
+#ifdef MONO_ARCH_EMULATE_MUL_DIV
+ backend->emulate_mul_div = 1;
#endif
+#ifdef MONO_ARCH_EMULATE_DIV
+ backend->emulate_div = 1;
+#endif
+#if !defined(MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS)
+ backend->emulate_long_shift_opts = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_OBJC_GET_SELECTOR
+ backend->have_objc_get_selector = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK
+ backend->have_generalized_imt_thunk = 1;
+#endif
+#ifdef MONO_ARCH_GSHARED_SUPPORTED
+ backend->gshared_supported = 1;
+#endif
+ if (MONO_ARCH_HAVE_TLS_GET)
+ backend->have_tls_get = 1;
+#ifdef MONO_ARCH_HAVE_TLS_GET_REG
+ backend->have_tls_get_reg = 1;
+#endif
+ if (MONO_ARCH_USE_FPSTACK)
+ backend->use_fpstack = 1;
+#ifdef MONO_ARCH_HAVE_LIVERANGE_OPS
+ backend->have_liverange_ops = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_OP_TAIL_CALL
+ backend->have_op_tail_call = 1;
+#endif
+#ifndef MONO_ARCH_MONITOR_ENTER_ADJUSTMENT
+ backend->monitor_enter_adjustment = 1;
+#else
+ backend->monitor_enter_adjustment = MONO_ARCH_MONITOR_ENTER_ADJUSTMENT;
+#endif
+#if defined(__mono_ilp32__)
+ backend->ilp32 = 1;
+#endif
+#ifdef MONO_ARCH_HAVE_DUMMY_INIT
+ backend->have_dummy_init = 1;
+#endif
+#ifdef MONO_ARCH_NEED_DIV_CHECK
+ backend->need_div_check = 1;
+#endif
+#ifdef NO_UNALIGNED_ACCESS
+ backend->no_unaligned_access = 1;
+#endif
+#ifdef MONO_ARCH_DYN_CALL_PARAM_AREA
+ backend->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA;
+#endif
+}
/*
* mini_method_compile:
cfg->orig_method = method;
cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points;
cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
+ cfg->llvm_only = (flags & JIT_FLAG_LLVM_ONLY) != 0;
+ cfg->backend = current_backend;
#ifdef PLATFORM_ANDROID
if (cfg->method->wrapper_type != MONO_WRAPPER_NONE) {
}
#endif
/* coop / nacl requires loop detection to happen */
-#if defined(__native_client_codegen__) || defined(USE_COOP_GC)
+#if defined(__native_client_codegen__)
cfg->opt |= MONO_OPT_LOOP;
+#else
+ if (mono_threads_is_coop_enabled ())
+ cfg->opt |= MONO_OPT_LOOP;
#endif
-
- cfg->explicit_null_checks = debug_options.explicit_null_checks;
+ cfg->explicit_null_checks = debug_options.explicit_null_checks || (flags & JIT_FLAG_EXPLICIT_NULL_CHECKS);
cfg->soft_breakpoints = debug_options.soft_breakpoints;
cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv;
cfg->disable_direct_icalls = disable_direct_icalls;
if (cfg->compile_aot)
cfg->method_index = aot_method_index;
+ /*
if (!mono_debug_count ())
cfg->opt &= ~MONO_OPT_FLOAT32;
+ */
+ if (cfg->llvm_only)
+ cfg->opt &= ~MONO_OPT_SIMD;
cfg->r4fp = (cfg->opt & MONO_OPT_FLOAT32) ? 1 : 0;
cfg->r4_stack_type = cfg->r4fp ? STACK_R4 : STACK_R8;
if (COMPILE_LLVM (cfg)) {
mono_llvm_check_method_supported (cfg);
if (cfg->disable_llvm) {
- if (cfg->verbose_level >= 1) {
+ if (cfg->verbose_level >= cfg->llvm_only ? 0 : 1) {
//nm = mono_method_full_name (cfg->method, TRUE);
printf ("LLVM failed for '%s': %s\n", method->name, cfg->exception_message);
//g_free (nm);
}
+ if (cfg->llvm_only) {
+ cfg->disable_aot = TRUE;
+ return cfg;
+ }
mono_destroy_compile (cfg);
try_llvm = FALSE;
goto restart_compile;
if (!COMPILE_LLVM (cfg))
mono_if_conversion (cfg);
- MONO_SUSPEND_CHECK ();
+ mono_threads_safepoint ();
/* Depth-first ordering on basic blocks */
cfg->bblocks = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1));
if (!cfg->disable_llvm)
mono_llvm_emit_method (cfg);
if (cfg->disable_llvm) {
- if (cfg->verbose_level >= 1) {
+ if (cfg->verbose_level >= cfg->llvm_only ? 0 : 1) {
//nm = mono_method_full_name (cfg->method, TRUE);
printf ("LLVM failed for '%s': %s\n", method->name, cfg->exception_message);
//g_free (nm);
}
+ if (cfg->llvm_only) {
+ cfg->disable_aot = TRUE;
+ return cfg;
+ }
mono_destroy_compile (cfg);
try_llvm = FALSE;
goto restart_compile;
return cfg;
}
-#else
+void*
+mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
+{
+ return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
+}
-MonoCompile*
-mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
+void
+mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
{
- g_assert_not_reached ();
- return NULL;
+ TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
+ hole->clause = clause;
+ hole->start_offset = start - cfg->native_code;
+ hole->basic_block = bb;
+
+ cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
+}
+
+void
+mono_cfg_set_exception (MonoCompile *cfg, int type)
+{
+ cfg->exception_type = type;
}
#endif /* DISABLE_JIT */
+static MonoJitInfo*
+create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
+{
+ MonoDomain *domain = mono_get_root_domain ();
+ MonoJitInfo *jinfo;
+ guint8 *uw_info;
+ guint32 info_len;
+
+ if (info->uw_info) {
+ uw_info = info->uw_info;
+ info_len = info->uw_info_len;
+ } else {
+ uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+ }
+
+ jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
+ jinfo->d.method = wrapper;
+ jinfo->code_start = info->code;
+ jinfo->code_size = info->code_size;
+ jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
+
+ if (!info->uw_info)
+ g_free (uw_info);
+
+ return jinfo;
+}
+
+/*
+ * mono_jit_compile_method_inner:
+ *
+ * Main entry point for the JIT.
+ */
gpointer
mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex)
{
*/
return mono_get_addr_from_ftnptr ((gpointer)mono_icall_get_wrapper_full (mi, TRUE));
} else if (*name == 'I' && (strcmp (name, "Invoke") == 0)) {
+ if (mono_llvm_only) {
+ nm = mono_marshal_get_delegate_invoke (method, NULL);
+ return mono_get_addr_from_ftnptr (mono_compile_method (nm));
+ }
return mono_create_delegate_trampoline (target_domain, method->klass);
} else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) {
nm = mono_marshal_get_delegate_begin_invoke (method);
return code;
}
-#ifndef DISABLE_JIT
-
-void*
-mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) {
- return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
-}
-
-void
-mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
+/*
+ * mini_get_underlying_type:
+ *
+ * Return the type the JIT will use during compilation.
+ * Handles: byref, enums, native types, generic sharing.
+ * For gsharedvt types, it will return the original VAR/MVAR.
+ */
+MonoType*
+mini_get_underlying_type (MonoType *type)
{
- TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
- hole->clause = clause;
- hole->start_offset = start - cfg->native_code;
- hole->basic_block = bb;
-
- cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
+ return mini_type_get_underlying_type (type);
}
void
-mono_cfg_set_exception (MonoCompile *cfg, int type)
+mini_jit_init (void)
{
- cfg->exception_type = type;
-}
-
+ mono_mutex_init_recursive (&jit_mutex);
+#ifndef DISABLE_JIT
+ current_backend = g_new0 (MonoBackend, 1);
+ init_backend (current_backend);
#endif
-
-/* Dummy versions of some arch specific functions to avoid ifdefs at call sites */
-
-#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
-
-gboolean
-mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig)
-{
- return FALSE;
}
-gpointer
-mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-gpointer
-mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-gpointer
-mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
+void
+mini_jit_cleanup (void)
{
- g_assert_not_reached ();
- return NULL;
-}
-
+#ifndef DISABLE_JIT
+ g_free (emul_opcode_map);
+ g_free (emul_opcode_opcodes);
#endif
-
-#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) && !defined(ENABLE_GSHAREDVT)
-
-gboolean
-mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig)
-{
- return FALSE;
-}
-
-gpointer
-mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
-{
- NOT_IMPLEMENTED;
- return NULL;
}
-#endif
-
#ifndef ENABLE_LLVM
void
mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
{
g_assert_not_reached ();
}
-#endif
-
-#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();
+#endif
- return result;
-}
+#if !defined(ENABLE_LLVM_RUNTIME) && !defined(ENABLE_LLVM)
void
-mono_jumptable_cleanup (void)
+mono_llvm_cpp_throw_exception (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);
- }
+ g_assert_not_reached ();
}
-gpointer*
-mono_jumptable_get_entry (guint8 *code_ptr)
-{
- return mono_arch_jumptable_entry_from_code (code_ptr);
-}
#endif
-/*
- * mini_get_underlying_type:
- *
- * Return the type the JIT will use during compilation.
- * Handles: byref, enums, native types, generic sharing.
- * For gsharedvt types, it will return the original VAR/MVAR.
- */
-MonoType*
-mini_get_underlying_type (MonoType *type)
+#ifdef DISABLE_JIT
+
+MonoCompile*
+mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
{
- return mini_type_get_underlying_type (type);
+ g_assert_not_reached ();
+ return NULL;
}
void
-mini_jit_init (void)
+mono_destroy_compile (MonoCompile *cfg)
{
- mono_mutex_init_recursive (&jit_mutex);
+ g_assert_not_reached ();
}
void
-mini_jit_cleanup (void)
+mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
{
- g_free (emul_opcode_map);
- g_free (emul_opcode_opcodes);
+ g_assert_not_reached ();
}
+
+#endif /* DISABLE_JIT */