gboolean mono_compile_aot = FALSE;
/* If this is set, no code is generated dynamically, everything is taken from AOT files */
gboolean mono_aot_only = FALSE;
+MonoAotMode mono_aot_mode = MONO_AOT_MODE_NONE;
const char *mono_build_date;
gboolean mono_do_signal_chaining;
gsctx = mono_jit_info_get_generic_sharing_context (ji);
shared_type = "";
if (gsctx) {
- if (gsctx->var_is_vt || gsctx->mvar_is_vt)
+ if (gsctx->is_gsharedvt)
shared_type = "gsharedvt ";
else
shared_type = "gshared ";
MonoMethod *wrapper;
gconstpointer trampoline;
MonoDomain *domain = mono_get_root_domain ();
- gboolean check_exc = check_for_pending_exc;
+ gboolean check_exc = TRUE;
if (callinfo->wrapper) {
return callinfo->wrapper;
static void
register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, const char *symbol, gboolean no_throw)
{
- return mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw);
+ mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw);
}
/*
mini_get_tls_offset (MonoTlsKey key)
{
int offset;
+ g_assert (MONO_ARCH_HAVE_TLS_GET);
switch (key) {
case TLS_KEY_THREAD:
case MONO_PATCH_INFO_CLASS:
case MONO_PATCH_INFO_IID:
case MONO_PATCH_INFO_ADJUSTED_IID:
- case MONO_PATCH_INFO_CLASS_INIT:
- case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
case MONO_PATCH_INFO_METHODCONST:
case MONO_PATCH_INFO_METHOD:
case MONO_PATCH_INFO_METHOD_JUMP:
case MONO_PATCH_INFO_IMAGE:
- case MONO_PATCH_INFO_JIT_ICALL_ADDR:
case MONO_PATCH_INFO_ICALL_ADDR:
case MONO_PATCH_INFO_FIELD:
case MONO_PATCH_INFO_SFLDA:
return (ji->type << 8) | (gssize)info->klass | (gssize)info->method;
}
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ return (ji->type << 8) | g_str_hash (ji->data.target);
default:
printf ("info type: %d\n", ji->type);
mono_print_ji (ji); printf ("\n");
return ji1->data.index == ji2->data.index;
case MONO_PATCH_INFO_VIRT_METHOD:
return ji1->data.virt_method->klass == ji2->data.virt_method->klass && ji1->data.virt_method->method == ji2->data.virt_method->method;
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ if (ji1->data.target == ji2->data.target)
+ return 1;
+ return strcmp (ji1->data.target, ji2->data.target) == 0 ? 1 : 0;
default:
if (ji1->data.target != ji2->data.target)
return 0;
target = mono_class_vtable (domain, patch_info->data.klass);
g_assert (target);
break;
- case MONO_PATCH_INFO_CLASS_INIT: {
- MonoVTable *vtable = mono_class_vtable (domain, patch_info->data.klass);
-
- g_assert (vtable);
- target = mono_create_class_init_trampoline (vtable);
- break;
- }
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE: {
MonoDelegateClassMethodPair *del_tramp = patch_info->data.del_tramp;
case MONO_PATCH_INFO_NONE:
break;
case MONO_PATCH_INFO_RGCTX_FETCH: {
- MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry;
- guint32 slot = -1;
-
- switch (entry->data->type) {
- case MONO_PATCH_INFO_CLASS:
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, &entry->data->data.klass->byval_arg, entry->info_type, mono_method_get_context (entry->method));
- break;
- case MONO_PATCH_INFO_METHOD:
- case MONO_PATCH_INFO_METHODCONST:
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.method, entry->info_type, mono_method_get_context (entry->method));
- break;
- case MONO_PATCH_INFO_FIELD:
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.field, entry->info_type, mono_method_get_context (entry->method));
- break;
- case MONO_PATCH_INFO_SIGNATURE:
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.sig, entry->info_type, mono_method_get_context (entry->method));
- break;
- case MONO_PATCH_INFO_GSHAREDVT_CALL: {
- MonoJumpInfoGSharedVtCall *call_info = g_malloc0 (sizeof (MonoJumpInfoGSharedVtCall)); //mono_domain_alloc0 (domain, sizeof (MonoJumpInfoGSharedVtCall));
-
- memcpy (call_info, entry->data->data.gsharedvt, sizeof (MonoJumpInfoGSharedVtCall));
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, call_info, entry->info_type, mono_method_get_context (entry->method));
- break;
- }
- case MONO_PATCH_INFO_GSHAREDVT_METHOD: {
- MonoGSharedVtMethodInfo *info;
- MonoGSharedVtMethodInfo *oinfo = entry->data->data.gsharedvt_method;
- int i;
-
- /* Make a copy into the domain mempool */
- info = g_malloc0 (sizeof (MonoGSharedVtMethodInfo)); //mono_domain_alloc0 (domain, sizeof (MonoGSharedVtMethodInfo));
- info->method = oinfo->method;
- info->num_entries = oinfo->num_entries;
- info->entries = g_malloc0 (sizeof (MonoRuntimeGenericContextInfoTemplate) * info->num_entries);
- for (i = 0; i < oinfo->num_entries; ++i) {
- MonoRuntimeGenericContextInfoTemplate *otemplate = &oinfo->entries [i];
- MonoRuntimeGenericContextInfoTemplate *template = &info->entries [i];
-
- memcpy (template, otemplate, sizeof (MonoRuntimeGenericContextInfoTemplate));
- }
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, info, entry->info_type, mono_method_get_context (entry->method));
- break;
- }
- case MONO_PATCH_INFO_VIRT_METHOD: {
- MonoJumpInfoVirtMethod *info;
- MonoJumpInfoVirtMethod *oinfo = entry->data->data.virt_method;
-
- info = g_malloc0 (sizeof (MonoJumpInfoVirtMethod));
- memcpy (info, oinfo, sizeof (MonoJumpInfoVirtMethod));
- slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, info, entry->info_type, mono_method_get_context (entry->method));
- break;
- }
- default:
- g_assert_not_reached ();
- break;
- }
+ int slot = mini_get_rgctx_entry_slot (patch_info->data.rgctx_entry);
target = mono_create_rgctx_lazy_fetch_trampoline (slot);
break;
}
- case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
- target = mono_create_generic_class_init_trampoline ();
- break;
case MONO_PATCH_INFO_MONITOR_ENTER:
target = mono_create_monitor_enter_trampoline ();
break;
if (context && context->class_inst) {
inst = context->class_inst;
- if (domain)
- gsctx->var_is_vt = mono_domain_alloc0 (domain, sizeof (gboolean) * inst->type_argc);
- else if (mp)
- gsctx->var_is_vt = mono_mempool_alloc0 (mp, sizeof (gboolean) * inst->type_argc);
- else
- gsctx->var_is_vt = g_new0 (gboolean, inst->type_argc);
-
for (i = 0; i < inst->type_argc; ++i) {
MonoType *type = inst->type_argv [i];
if (mini_is_gsharedvt_gparam (type))
- gsctx->var_is_vt [i] = TRUE;
+ gsctx->is_gsharedvt = TRUE;
}
}
if (context && context->method_inst) {
inst = context->method_inst;
- if (domain)
- gsctx->mvar_is_vt = mono_domain_alloc0 (domain, sizeof (gboolean) * inst->type_argc);
- else if (mp)
- gsctx->mvar_is_vt = mono_mempool_alloc0 (mp, sizeof (gboolean) * inst->type_argc);
- else
- gsctx->mvar_is_vt = g_new0 (gboolean, inst->type_argc);
for (i = 0; i < inst->type_argc; ++i) {
MonoType *type = inst->type_argv [i];
if (mini_is_gsharedvt_gparam (type))
- gsctx->mvar_is_vt [i] = TRUE;
+ gsctx->is_gsharedvt = TRUE;
}
}
}
return NULL;
} else {
mono_raise_exception (jit_ex);
+ /* coverity[unreachable] */
}
}
- info->compiled_method = mini_add_method_trampoline (NULL, callee, info->compiled_method, mono_method_needs_static_rgctx_invoke (callee, FALSE), FALSE);
+ info->compiled_method = mini_add_method_trampoline (callee, info->compiled_method, mono_method_needs_static_rgctx_invoke (callee, TRUE), FALSE);
} else {
info->compiled_method = NULL;
}
for (i = 0; i < sig->param_count; ++i) {
MonoType *t = sig->params [i];
- if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t)))
+ if (t->byref && t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t)))
supported = FALSE;
}
if (!method)
return NULL;
- /* FIXME Support more cases */
- if (mono_aot_only)
- return NULL;
-
if (MONO_TYPE_ISSTRUCT (sig->ret))
return NULL;
if (cache [idx])
return cache [idx];
- return cache [idx] = mono_arch_get_delegate_virtual_invoke_impl (sig, method, offset, load_imt_reg);
+ /* FIXME Support more cases */
+ if (mono_aot_only) {
+ char tramp_name [256];
+
+ sprintf (tramp_name, "delegate_virtual_invoke%s_%d", load_imt_reg ? "_imt" : "", offset / SIZEOF_VOID_P);
+ cache [idx] = mono_aot_get_trampoline (tramp_name);
+ g_assert (cache [idx]);
+ } else {
+ cache [idx] = mono_arch_get_delegate_virtual_invoke_impl (sig, method, offset, load_imt_reg);
+ }
+ return cache [idx];
}
static gpointer
debug_options.gen_sdb_seq_points = TRUE;
else if (!strcmp (arg, "gen-compact-seq-points"))
debug_options.gen_seq_points_compact_data = TRUE;
+ else if (!strcmp (arg, "single-imm-size"))
+ debug_options.single_imm_size = TRUE;
else if (!strcmp (arg, "init-stacks"))
debug_options.init_stacks = TRUE;
else if (!strcmp (arg, "casts"))
debug_options.soft_breakpoints = TRUE;
else if (!strcmp (arg, "check-pinvoke-callconv"))
debug_options.check_pinvoke_callconv = TRUE;
+ else if (!strcmp (arg, "arm-use-fallback-tls"))
+ debug_options.arm_use_fallback_tls = TRUE;
else if (!strcmp (arg, "debug-domain-unload"))
mono_enable_debug_domain_unload (TRUE);
else if (!strcmp (arg, "partial-sharing"))
mono_align_small_structs = TRUE;
else {
fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg);
- fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'dont-free-domains', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks', 'check-pinvoke-callconv', 'debug-domain-unload', 'partial-sharing', 'align-small-structs'\n");
+ fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'dont-free-domains', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs'\n");
exit (1);
}
}
{
MonoJitDomainInfo *info = g_new0 (MonoJitDomainInfo, 1);
- info->class_init_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
info->jump_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
info->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
info->delegate_trampoline_hash = g_hash_table_new (class_method_pair_hash, class_method_pair_equal);
}
if (info->method_code_hash)
g_hash_table_destroy (info->method_code_hash);
- g_hash_table_destroy (info->class_init_trampoline_hash);
g_hash_table_destroy (info->jump_trampoline_hash);
g_hash_table_destroy (info->jit_trampoline_hash);
g_hash_table_destroy (info->delegate_trampoline_hash);
#endif
mono_threads_install_cleanup (mini_thread_cleanup);
-#ifdef MONO_ARCH_HAVE_NOTIFY_PENDING_EXC
- check_for_pending_exc = FALSE;
- mono_threads_install_notify_pending_exc ((MonoThreadNotifyPendingExcFunc)mono_arch_notify_pending_exc);
-#endif
-
#define JIT_TRAMPOLINES_WORK
#ifdef JIT_TRAMPOLINES_WORK
mono_install_compile_method (mono_jit_compile_method);
#endif
register_opcode_emulation (OP_FCONV_TO_U8, "__emul_fconv_to_u8", "ulong double", mono_fconv_u8, "mono_fconv_u8", FALSE);
+ register_opcode_emulation (OP_RCONV_TO_U8, "__emul_rconv_to_u8", "ulong float", mono_rconv_u8, "mono_rconv_u8", FALSE);
register_opcode_emulation (OP_FCONV_TO_U4, "__emul_fconv_to_u4", "uint32 double", mono_fconv_u4, "mono_fconv_u4", FALSE);
register_opcode_emulation (OP_FCONV_TO_OVF_I8, "__emul_fconv_to_ovf_i8", "long double", mono_fconv_ovf_i8, "mono_fconv_ovf_i8", FALSE);
register_opcode_emulation (OP_FCONV_TO_OVF_U8, "__emul_fconv_to_ovf_u8", "ulong double", mono_fconv_ovf_u8, "mono_fconv_ovf_u8", FALSE);
register_opcode_emulation (OP_RCONV_TO_OVF_I8, "__emul_rconv_to_ovf_i8", "long float", mono_rconv_ovf_i8, "mono_rconv_ovf_i8", FALSE);
register_opcode_emulation (OP_RCONV_TO_OVF_U8, "__emul_rconv_to_ovf_u8", "ulong float", mono_rconv_ovf_u8, "mono_rconv_ovf_u8", FALSE);
+
#ifdef MONO_ARCH_EMULATE_FCONV_TO_I8
register_opcode_emulation (OP_FCONV_TO_I8, "__emul_fconv_to_i8", "long double", mono_fconv_i8, "mono_fconv_i8", FALSE);
register_opcode_emulation (OP_RCONV_TO_I8, "__emul_rconv_to_i8", "long float", mono_rconv_i8, "mono_rconv_i8", FALSE);
#endif
+
#ifdef MONO_ARCH_EMULATE_CONV_R8_UN
register_opcode_emulation (OP_ICONV_TO_R_UN, "__emul_iconv_to_r_un", "double int32", mono_conv_to_r8_un, "mono_conv_to_r8_un", FALSE);
#endif
#ifdef MONO_ARCH_EMULATE_FREM
#if defined(__default_codegen__)
register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", fmod, "fmod", FALSE);
+ register_opcode_emulation (OP_RREM, "__emul_rrem", "float float float", fmodf, "fmodf", FALSE);
#elif defined(__native_client_codegen__)
register_opcode_emulation (OP_FREM, "__emul_frem", "double double double", mono_fmod, "mono_fmod", FALSE);
#endif
register_icall (mono_object_castclass_with_cache, "mono_object_castclass_with_cache", "object object ptr ptr", FALSE);
register_icall (mono_object_isinst_with_cache, "mono_object_isinst_with_cache", "object object ptr ptr", FALSE);
+ register_icall (mono_generic_class_init, "mono_generic_class_init", "void ptr", FALSE);
+ register_icall (mono_fill_class_rgctx, "mono_class_fill_rgctx", "ptr ptr int", FALSE);
+ register_icall (mono_fill_method_rgctx, "mono_method_fill_rgctx", "ptr ptr int", FALSE);
register_icall (mono_debugger_agent_user_break, "mono_debugger_agent_user_break", "void", FALSE);
#ifndef MONO_CROSS_COMPILE
mono_domain_free (domain, TRUE);
+ mono_gc_mutex_cleanup ();
#endif
#ifdef ENABLE_LLVM