X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=841ee66b2a7594df2a549754375afba4a0f475a1;hb=d2e184bbf7f82d83d767aae6af08359729769270;hp=cb572175830cf8fe263582301af4ad22dcac0563;hpb=2d8af166633a3f57bde7333d0b91fd71edf63e1b;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index cb572175830..841ee66b2a7 100755 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -10,7 +10,6 @@ * Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com) */ -#define MONO_LLVM_IN_MINI 1 #include #ifdef HAVE_ALLOCA_H #include @@ -64,7 +63,6 @@ #include "mini.h" #include "seq-points.h" -#include "mini-llvm.h" #include "tasklets.h" #include #include @@ -88,8 +86,7 @@ MONO_FAST_TLS_DECLARE(mono_jit_tls); 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; -/* Whenever to use IMT */ -gboolean mono_use_imt = TRUE; + const char *mono_build_date; gboolean mono_do_signal_chaining; gboolean mono_do_crash_chaining; @@ -229,29 +226,28 @@ mono_print_method_from_ip (void *ip) FindTrampUserData user_data; MonoGenericSharingContext*gsctx; const char *shared_type; - GSList *l; - ji = mini_jit_info_table_find (domain, ip, &target_domain); + ji = mini_jit_info_table_find_ext (domain, ip, TRUE, &target_domain); + if (ji && ji->is_trampoline) { + MonoTrampInfo *tinfo = ji->d.tramp_info; + + printf ("IP %p is at offset 0x%x of trampoline '%s'.\n", ip, (int)((guint8*)ip - tinfo->code), tinfo->name); + return; + } + if (!ji) { user_data.ip = ip; user_data.method = NULL; mono_domain_lock (domain); g_hash_table_foreach (domain_jit_info (domain)->jit_trampoline_hash, find_tramp, &user_data); mono_domain_unlock (domain); + if (user_data.method) { char *mname = mono_method_full_name (user_data.method, TRUE); printf ("IP %p is a JIT trampoline for %s\n", ip, mname); g_free (mname); return; } - for (l = tramp_infos; l; l = l->next) { - MonoTrampInfo *tinfo = l->data; - - if ((guint8*)ip >= tinfo->code && (guint8*)ip <= tinfo->code + tinfo->code_size) { - printf ("IP %p is at offset 0x%x of trampoline '%s'.\n", ip, (int)((guint8*)ip - tinfo->code), tinfo->name); - return; - } - } g_print ("No method at %p\n", ip); fflush (stdout); @@ -474,6 +470,20 @@ mono_tramp_info_free (MonoTrampInfo *info) g_free (info); } +static void +register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info) +{ + MonoJitInfo *ji; + + ji = mono_domain_alloc0 (domain, mono_jit_info_size (0, 0, 0)); + mono_jit_info_init (ji, NULL, info->code, info->code_size, 0, 0, 0); + ji->d.tramp_info = info; + ji->is_trampoline = TRUE; + // FIXME: Unwind info + + mono_jit_info_table_add (domain, ji); +} + /* * mono_tramp_info_register: * @@ -500,6 +510,9 @@ mono_tramp_info_register (MonoTrampInfo *info) mono_save_trampoline_xdebug_info (info); + if (mono_get_root_domain ()) + register_trampoline_jit_info (mono_get_root_domain (), copy); + if (mono_jit_map_is_enabled ()) mono_emit_jit_tramp (info->code, info->code_size, info->name); @@ -519,6 +532,19 @@ mono_tramp_info_cleanup (void) g_slist_free (tramp_infos); } +/* Register trampolines created before the root domain was created in the jit info tables */ +static void +register_trampolines (MonoDomain *domain) +{ + GSList *l; + + for (l = tramp_infos; l; l = l->next) { + MonoTrampInfo *info = l->data; + + register_trampoline_jit_info (domain, info); + } +} + G_GNUC_UNUSED static void break_count (void) { @@ -611,14 +637,6 @@ mono_icall_get_wrapper (MonoJitICallInfo* callinfo) return mono_icall_get_wrapper_full (callinfo, FALSE); } -static void -mono_dynamic_code_hash_insert (MonoDomain *domain, MonoMethod *method, MonoJitDynamicMethodInfo *ji) -{ - if (!domain_jit_info (domain)->dynamic_code_hash) - domain_jit_info (domain)->dynamic_code_hash = g_hash_table_new (NULL, NULL); - g_hash_table_insert (domain_jit_info (domain)->dynamic_code_hash, method, ji); -} - static MonoJitDynamicMethodInfo* mono_dynamic_code_hash_lookup (MonoDomain *domain, MonoMethod *method) { @@ -656,20 +674,6 @@ register_icall (gpointer func, const char *name, const char *sigstr, gboolean sa mono_register_jit_icall_full (func, name, sig, save, FALSE, save ? name : NULL); } -/* Register a jit icall which doesn't throw exceptions through mono_raise_exception () */ -static void -register_icall_noraise (gpointer func, const char *name, const char *sigstr) -{ - MonoMethodSignature *sig; - - if (sigstr) - sig = mono_create_icall_signature (sigstr); - else - sig = NULL; - - mono_register_jit_icall_full (func, name, sig, TRUE, TRUE, name); -} - static void register_dyn_icall (gpointer func, const char *name, const char *sigstr, gboolean save) { @@ -949,9 +953,9 @@ free_jit_tls_data (MonoJitTlsData *jit_tls) static void mono_thread_start_cb (intptr_t tid, gpointer stack_start, gpointer func) { - MonoInternalThread *thread; + MonoThreadInfo *thread; void *jit_tls = setup_jit_tls_data (stack_start, mono_thread_abort); - thread = mono_thread_internal_current (); + thread = mono_thread_info_current_unchecked (); if (thread) thread->jit_data = jit_tls; @@ -972,9 +976,9 @@ mono_thread_abort_dummy (MonoObject *obj) static void mono_thread_attach_cb (intptr_t tid, gpointer stack_start) { - MonoInternalThread *thread; + MonoThreadInfo *thread; void *jit_tls = setup_jit_tls_data (stack_start, mono_thread_abort_dummy); - thread = mono_thread_internal_current (); + thread = mono_thread_info_current_unchecked (); if (thread) thread->jit_data = jit_tls; if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL) @@ -984,30 +988,41 @@ mono_thread_attach_cb (intptr_t tid, gpointer stack_start) } static void -mini_thread_cleanup (MonoInternalThread *thread) +mini_thread_cleanup (MonoNativeThreadId tid) { - MonoJitTlsData *jit_tls = thread->jit_data; + MonoJitTlsData *jit_tls = NULL; + MonoThreadInfo *info; - if (jit_tls) { - /* We can't clean up tls information if we are on another thread, it will clean up the wrong stuff - * It would be nice to issue a warning when this happens outside of the shutdown sequence. but it's - * not a trivial thing. - * - * The current offender is mono_thread_manage which cleanup threads from the outside. - */ - if (thread == mono_thread_internal_current ()) - mono_set_jit_tls (NULL); + info = mono_thread_info_current_unchecked (); + + /* We can't clean up tls information if we are on another thread, it will clean up the wrong stuff + * It would be nice to issue a warning when this happens outside of the shutdown sequence. but it's + * not a trivial thing. + * + * The current offender is mono_thread_manage which cleanup threads from the outside. + */ + if (info && mono_thread_info_get_tid (info) == tid) { + jit_tls = info->jit_data; + info->jit_data = NULL; + + mono_set_jit_tls (NULL); /* If we attach a thread but never call into managed land, we might never get an lmf.*/ if (mono_get_lmf ()) { mono_set_lmf (NULL); mono_set_lmf_addr (NULL); } + } else { + info = mono_thread_info_lookup (tid); + if (info) { + jit_tls = info->jit_data; + info->jit_data = NULL; + } + mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1); + } + if (jit_tls) free_jit_tls_data (jit_tls); - - thread->jit_data = NULL; - } } int @@ -1121,6 +1136,16 @@ mono_patch_info_dup_mp (MonoMemPool *mp, MonoJumpInfo *patch_info) //memcpy (info->locals_types, oinfo->locals_types, info->nlocals * sizeof (MonoType*)); break; } + case MONO_PATCH_INFO_VIRT_METHOD: { + MonoJumpInfoVirtMethod *info; + MonoJumpInfoVirtMethod *oinfo; + + oinfo = patch_info->data.virt_method; + info = mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoVirtMethod)); + res->data.virt_method = info; + memcpy (info, oinfo, sizeof (MonoJumpInfoVirtMethod)); + break; + } default: break; } @@ -1173,11 +1198,13 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG: case MONO_PATCH_INFO_MSCORLIB_GOT_ADDR: case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR: + case MONO_PATCH_INFO_GC_NURSERY_START: case MONO_PATCH_INFO_JIT_TLS_ID: case MONO_PATCH_INFO_MONITOR_ENTER: case MONO_PATCH_INFO_MONITOR_ENTER_V4: case MONO_PATCH_INFO_MONITOR_EXIT: case MONO_PATCH_INFO_GOT_OFFSET: + case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: return (ji->type << 8); case MONO_PATCH_INFO_CASTCLASS_CACHE: return (ji->type << 8) | (ji->data.index); @@ -1192,6 +1219,11 @@ mono_patch_info_hash (gconstpointer data) return (ji->type << 8) | (gsize)ji->data.del_tramp->klass | (gsize)ji->data.del_tramp->method | (gsize)ji->data.del_tramp->virtual; case MONO_PATCH_INFO_LDSTR_LIT: return g_str_hash (ji->data.target); + case MONO_PATCH_INFO_VIRT_METHOD: { + MonoJumpInfoVirtMethod *info = ji->data.virt_method; + + return (ji->type << 8) | (gssize)info->klass | (gssize)info->method; + } default: printf ("info type: %d\n", ji->type); mono_print_ji (ji); printf ("\n"); @@ -1249,6 +1281,8 @@ mono_patch_info_equal (gconstpointer ka, gconstpointer kb) return ji1->data.del_tramp->klass == ji2->data.del_tramp->klass && ji1->data.del_tramp->method == ji2->data.del_tramp->method && ji1->data.del_tramp->virtual == ji2->data.del_tramp->virtual; case MONO_PATCH_INFO_CASTCLASS_CACHE: 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; default: if (ji1->data.target != ji2->data.target) return 0; @@ -1351,6 +1385,15 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = code_slot; break; } + case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: +#if defined(__native_client_codegen__) + target = (gpointer)&__nacl_thread_suspension_needed; +#elif defined (USE_COOP_GC) + target = (gpointer)&mono_polling_required; +#else + g_error ("Unsuported patch target"); +#endif + break; case MONO_PATCH_INFO_SWITCH: { gpointer *jump_table; int i; @@ -1586,6 +1629,15 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, 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; @@ -1630,6 +1682,13 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mono_gc_get_card_table (&card_table_shift_bits, &card_table_mask); break; } + case MONO_PATCH_INFO_GC_NURSERY_START: { + int shift_bits; + size_t size; + + target = mono_gc_get_nursery (&shift_bits, &size); + break; + } case MONO_PATCH_INFO_CASTCLASS_CACHE: { target = mono_domain_alloc0 (domain, sizeof (gpointer)); break; @@ -1653,7 +1712,14 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, break; } case MONO_PATCH_INFO_LDSTR_LIT: { - target = mono_string_new (domain, patch_info->data.target); + int len; + char *s; + + len = strlen (patch_info->data.target); + s = mono_domain_alloc0 (domain, len + 1); + memcpy (s, patch_info->data.target, len); + target = s; + break; } default: @@ -1663,202 +1729,6 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, return (gpointer)target; } -static MonoType* -get_gsharedvt_type (MonoType *t) -{ - MonoGenericParam *par = t->data.generic_param; - MonoGenericParam *copy; - MonoType *res; - MonoImage *image = NULL; - - /* - * Create an anonymous gparam with a different serial so normal gshared and gsharedvt methods have - * a different instantiation. - */ - g_assert (mono_generic_param_info (par)); - if (par->owner) { - image = par->owner->image; - - mono_image_lock (image); - if (!image->gsharedvt_types) - image->gsharedvt_types = g_hash_table_new (NULL, NULL); - res = g_hash_table_lookup (image->gsharedvt_types, par); - mono_image_unlock (image); - if (res) - return res; - copy = mono_image_alloc0 (image, sizeof (MonoGenericParamFull)); - memcpy (copy, par, sizeof (MonoGenericParamFull)); - } else { - copy = g_memdup (par, sizeof (MonoGenericParam)); - } - copy->owner = NULL; - // FIXME: - copy->image = mono_defaults.corlib; - copy->serial = 1; - res = mono_metadata_type_dup (NULL, t); - res->data.generic_param = copy; - - if (par->owner) { - mono_image_lock (image); - /* Duplicates are ok */ - g_hash_table_insert (image->gsharedvt_types, par, res); - mono_image_unlock (image); - } - - return res; -} - -static gboolean -is_gsharedvt_type (MonoType *t) -{ - return (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->serial == 1; -} - -/* Return whenever METHOD is a gsharedvt method */ -static gboolean -is_gsharedvt_method (MonoMethod *method) -{ - MonoGenericContext *context; - MonoGenericInst *inst; - int i; - - if (!method->is_inflated) - return FALSE; - context = mono_method_get_context (method); - inst = context->class_inst; - if (inst) { - for (i = 0; i < inst->type_argc; ++i) - if (is_gsharedvt_type (inst->type_argv [i])) - return TRUE; - } - inst = context->method_inst; - if (inst) { - for (i = 0; i < inst->type_argc; ++i) - if (is_gsharedvt_type (inst->type_argv [i])) - return TRUE; - } - return FALSE; -} - -static gboolean -is_open_method (MonoMethod *method) -{ - MonoGenericContext *context; - - if (!method->is_inflated) - return FALSE; - context = mono_method_get_context (method); - if (context->class_inst && context->class_inst->is_open) - return TRUE; - if (context->method_inst && context->method_inst->is_open) - return TRUE; - return FALSE; -} - -static MonoGenericInst* -get_shared_inst (MonoGenericInst *inst, MonoGenericInst *shared_inst, MonoGenericContainer *container, gboolean all_vt, gboolean gsharedvt) -{ - MonoGenericInst *res; - MonoType **type_argv; - int i; - - type_argv = g_new0 (MonoType*, inst->type_argc); - for (i = 0; i < inst->type_argc; ++i) { - if (!all_vt && (MONO_TYPE_IS_REFERENCE (inst->type_argv [i]) || inst->type_argv [i]->type == MONO_TYPE_VAR || inst->type_argv [i]->type == MONO_TYPE_MVAR)) { - type_argv [i] = shared_inst->type_argv [i]; - } else if (all_vt) { - type_argv [i] = get_gsharedvt_type (shared_inst->type_argv [i]); - } else if (gsharedvt) { - type_argv [i] = get_gsharedvt_type (shared_inst->type_argv [i]); - } else { - type_argv [i] = inst->type_argv [i]; - } - } - - res = mono_metadata_get_generic_inst (inst->type_argc, type_argv); - g_free (type_argv); - return res; -} - -/* - * mini_get_shared_method_full: - * - * Return the method which is actually compiled/registered when doing generic sharing. - * If ALL_VT is true, return the shared method belonging to an all-vtype instantiation. - * If IS_GSHAREDVT is true, treat METHOD as a gsharedvt method even if it fails some constraints. - * METHOD can be a non-inflated generic method. - */ -MonoMethod* -mini_get_shared_method_full (MonoMethod *method, gboolean all_vt, gboolean is_gsharedvt) -{ - MonoError error; - MonoGenericContext shared_context; - MonoMethod *declaring_method, *res; - gboolean partial = FALSE; - gboolean gsharedvt = FALSE; - MonoGenericContainer *class_container, *method_container = NULL; - - if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) { - declaring_method = method; - } else { - declaring_method = mono_method_get_declaring_generic_method (method); - } - - if (declaring_method->is_generic) - shared_context = mono_method_get_generic_container (declaring_method)->context; - else - shared_context = declaring_method->klass->generic_container->context; - - /* Handle gsharedvt/partial sharing */ - if ((method != declaring_method && method->is_inflated && !mono_method_is_generic_sharable_full (method, FALSE, FALSE, TRUE)) || - is_gsharedvt || mini_is_gsharedvt_sharable_method (method)) { - MonoGenericContext *context = mono_method_get_context (method); - MonoGenericInst *inst; - - partial = mono_method_is_generic_sharable_full (method, FALSE, TRUE, FALSE); - - gsharedvt = is_gsharedvt || (!partial && mini_is_gsharedvt_sharable_method (method)); - - class_container = declaring_method->klass->generic_container; - method_container = mono_method_get_generic_container (declaring_method); - - /* - * Create the shared context by replacing the ref type arguments with - * type parameters, and keeping the rest. - */ - if (context) - inst = context->class_inst; - else - inst = shared_context.class_inst; - if (inst) - shared_context.class_inst = get_shared_inst (inst, shared_context.class_inst, class_container, all_vt, gsharedvt); - - if (context) - inst = context->method_inst; - else - inst = shared_context.method_inst; - if (inst) - shared_context.method_inst = get_shared_inst (inst, shared_context.method_inst, method_container, all_vt, gsharedvt); - - partial = TRUE; - } - - res = mono_class_inflate_generic_method_checked (declaring_method, &shared_context, &error); - g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ - - if (!partial) { - /* The result should be an inflated method whose parent is not inflated */ - g_assert (!res->klass->is_inflated); - } - return res; -} - -MonoMethod* -mini_get_shared_method (MonoMethod *method) -{ - return mini_get_shared_method_full (method, FALSE, FALSE); -} - void mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *context, MonoGenericSharingContext *gsctx) { @@ -1879,7 +1749,7 @@ mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *contex for (i = 0; i < inst->type_argc; ++i) { MonoType *type = inst->type_argv [i]; - if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1) + if (mini_is_gsharedvt_gparam (type)) gsctx->var_is_vt [i] = TRUE; } } @@ -1895,7 +1765,7 @@ mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *contex for (i = 0; i < inst->type_argc; ++i) { MonoType *type = inst->type_argv [i]; - if ((type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && type->data.generic_param->serial == 1) + if (mini_is_gsharedvt_gparam (type)) gsctx->mvar_is_vt [i] = TRUE; } } @@ -1952,6 +1822,12 @@ lookup_method (MonoDomain *domain, MonoMethod *method) return ji; } +MonoJitInfo * +mono_get_jit_info_from_method (MonoDomain *domain, MonoMethod *method) +{ + return lookup_method (domain, method); +} + #if ENABLE_JIT_MAP static FILE* perf_map_file; @@ -2846,7 +2722,7 @@ mini_parse_debug_options (void) else if (!strcmp (arg, "explicit-null-checks")) debug_options.explicit_null_checks = TRUE; else if (!strcmp (arg, "gen-seq-points")) - debug_options.gen_seq_points_debug_data = TRUE; + 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, "init-stacks")) @@ -2859,9 +2735,11 @@ mini_parse_debug_options (void) debug_options.check_pinvoke_callconv = TRUE; else if (!strcmp (arg, "debug-domain-unload")) mono_enable_debug_domain_unload (TRUE); + else if (!strcmp (arg, "partial-sharing")) + mono_set_partial_sharing_supported (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'\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', 'debug-domain-unload', 'partial-sharing'\n"); exit (1); } } @@ -3140,10 +3018,8 @@ mini_init (const char *filename, const char *runtime_version) callbacks.debug_log_is_enabled = mono_debugger_agent_debug_log_is_enabled; callbacks.tls_key_supported = mini_tls_key_supported; - if (mono_use_imt) { - callbacks.get_vtable_trampoline = mini_get_vtable_trampoline; - callbacks.get_imt_trampoline = mini_get_imt_trampoline; - } + callbacks.get_vtable_trampoline = mini_get_vtable_trampoline; + callbacks.get_imt_trampoline = mini_get_imt_trampoline; mono_install_callbacks (&callbacks); @@ -3169,6 +3045,7 @@ mini_init (const char *filename, const char *runtime_version) mono_unwind_init (); +#ifdef XDEBUG_ENABLED if (g_getenv ("MONO_XDEBUG")) { const char *xdebug_opts = g_getenv ("MONO_XDEBUG"); mono_xdebug_init (xdebug_opts); @@ -3180,6 +3057,7 @@ mini_init (const char *filename, const char *runtime_version) mono_dont_free_domains = TRUE; mono_using_xdebug = TRUE; } +#endif #ifdef ENABLE_LLVM if (mono_use_llvm) { @@ -3250,12 +3128,10 @@ mini_init (const char *filename, const char *runtime_version) mono_marshal_use_aot_wrappers (TRUE); } - if (mono_use_imt) { - if (mono_aot_only) - mono_install_imt_thunk_builder (mono_aot_get_imt_thunk); - else - mono_install_imt_thunk_builder (mono_arch_build_imt_thunk); - } + if (mono_aot_only) + mono_install_imt_thunk_builder (mono_aot_get_imt_thunk); + else + mono_install_imt_thunk_builder (mono_arch_build_imt_thunk); /*Init arch tls information only after the metadata side is inited to make sure we see dynamic appdomain tls keys*/ mono_arch_finish_init (); @@ -3294,6 +3170,8 @@ mini_init (const char *filename, const char *runtime_version) mono_tasklets_init (); #endif + register_trampolines (domain); + if (mono_compile_aot) /* * Avoid running managed code when AOT compiling, since the platform @@ -3368,6 +3246,10 @@ register_icalls (void) #if defined(__native_client__) || defined(__native_client_codegen__) register_icall (mono_nacl_gc, "mono_nacl_gc", "void", TRUE); #endif +#if defined(USE_COOP_GC) + register_icall (mono_threads_state_poll, "mono_threads_state_poll", "void", TRUE); +#endif + #ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS register_opcode_emulation (OP_LMUL, "__emul_lmul", "long long long", mono_llmult, "mono_llmult", TRUE); register_opcode_emulation (OP_LDIV, "__emul_ldiv", "long long long", mono_lldiv, "mono_lldiv", FALSE);