X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=9336b94f2d2bcc0f5935fa09163f6f5bfb9e0098;hb=b0b4fb685a8637231874c8d30b63365eb721283e;hp=76647275f08a4462f2d7ff43dcef86ae344ea8cf;hpb=9e167696e7709b66bc42e7a822046665f7d29660;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 76647275f08..9336b94f2d2 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include "mini.h" #include "seq-points.h" @@ -81,6 +81,7 @@ #include "mini-gc.h" #include "mini-llvm.h" #include "debugger-agent.h" +#include "lldb.h" #ifdef MONO_ARCH_LLVM_SUPPORTED #ifdef ENABLE_LLVM @@ -89,15 +90,13 @@ #endif #endif +#ifdef ENABLE_INTERPRETER +#include "interp/interp.h" +#endif + static guint32 default_opt = 0; static gboolean default_opt_set = FALSE; -MonoNativeTlsKey mono_jit_tls_id; - -#ifdef MONO_HAVE_FAST_TLS -MONO_FAST_TLS_DECLARE(mono_jit_tls); -#endif - 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; @@ -116,6 +115,8 @@ int mini_verbose = 0; */ gboolean mono_use_llvm = FALSE; +gboolean mono_use_interpreter = FALSE; + #define mono_jit_lock() mono_os_mutex_lock (&jit_mutex) #define mono_jit_unlock() mono_os_mutex_unlock (&jit_mutex) static mono_mutex_t jit_mutex; @@ -127,11 +128,18 @@ MonoDebugOptions debug_options; #ifdef VALGRIND_JIT_REGISTER_MAP int valgrind_register; #endif +GList* mono_aot_paths; + +static gboolean mini_enable_profiler = FALSE; +static char* mini_profiler_options = NULL; static GSList *tramp_infos; static void register_icalls (void); +static gboolean mini_profiler_enabled (void) { return mini_enable_profiler; } +static const char* mini_profiler_get_options (void) { return mini_profiler_options; } + gboolean mono_running_on_valgrind (void) { @@ -239,7 +247,7 @@ mono_pmip (void *ip) */ #ifdef __GNUC__ /* Prevent the linker from optimizing this away in embedding setups to help debugging */ - __attribute__((used)) + __attribute__ ((__used__)) #endif void mono_print_method_from_ip (void *ip) @@ -253,6 +261,8 @@ mono_print_method_from_ip (void *ip) MonoGenericSharingContext*gsctx; const char *shared_type; + if (!domain) + domain = mono_get_root_domain (); ji = mini_jit_info_table_find_ext (domain, (char *)ip, TRUE, &target_domain); if (ji && ji->is_trampoline) { MonoTrampInfo *tinfo = (MonoTrampInfo *)ji->d.tramp_info; @@ -356,6 +366,15 @@ void *mono_global_codeman_reserve (int size) } } +/* The callback shouldn't take any locks */ +void +mono_global_codeman_foreach (MonoCodeManagerFunc func, void *user_data) +{ + mono_jit_lock (); + mono_code_manager_foreach (global_codeman, func, user_data); + mono_jit_unlock (); +} + #if defined(__native_client_codegen__) && defined(__native_client__) void mono_nacl_gc() @@ -484,6 +503,7 @@ mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain) mono_jit_unlock (); mono_save_trampoline_xdebug_info (info); + mono_lldb_save_trampoline_info (info); /* Only register trampolines that have unwind infos */ if (mono_get_root_domain () && copy->uw_info) @@ -692,63 +712,15 @@ register_dyn_icall (gpointer func, const char *name, const char *sigstr, gboolea mono_register_jit_icall (func, name, sig, save); } -#ifdef MONO_HAVE_FAST_TLS -MONO_FAST_TLS_DECLARE(mono_lmf_addr); -#ifdef MONO_ARCH_ENABLE_MONO_LMF_VAR -/* - * When this is defined, the current lmf is stored in this tls variable instead of in - * jit_tls->lmf. - */ -MONO_FAST_TLS_DECLARE(mono_lmf); -#endif -#endif - -gint32 -mono_get_jit_tls_offset (void) -{ - int offset; - -#ifdef HOST_WIN32 - if (mono_jit_tls_id) - offset = mono_jit_tls_id; - else - /* FIXME: Happens during startup */ - offset = -1; -#else - MONO_THREAD_VAR_OFFSET (mono_jit_tls, offset); -#endif - return offset; -} - -gint32 -mono_get_lmf_tls_offset (void) -{ -#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) - int offset; - MONO_THREAD_VAR_OFFSET(mono_lmf,offset); - return offset; -#else - return -1; -#endif -} - -gint32 -mono_get_lmf_addr_tls_offset (void) -{ - int offset; - MONO_THREAD_VAR_OFFSET(mono_lmf_addr,offset); - return offset; -} - MonoLMF * mono_get_lmf (void) { -#if defined(MONO_HAVE_FAST_TLS) && defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) - return (MonoLMF *)MONO_FAST_TLS_GET (mono_lmf); +#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR) + return (MonoLMF *)mono_tls_get_lmf (); #else MonoJitTlsData *jit_tls; - if ((jit_tls = mono_native_tls_get_value (mono_jit_tls_id))) + if ((jit_tls = mono_tls_get_jit_tls ())) return jit_tls->lmf; /* * We do not assert here because this function can be called from @@ -762,48 +734,23 @@ mono_get_lmf (void) MonoLMF ** mono_get_lmf_addr (void) { -#ifdef MONO_HAVE_FAST_TLS - return (MonoLMF **)MONO_FAST_TLS_GET (mono_lmf_addr); -#else - MonoJitTlsData *jit_tls; - - jit_tls = mono_native_tls_get_value (mono_jit_tls_id); - if (G_LIKELY (jit_tls)) - return &jit_tls->lmf; - - /* - * When resolving the call to mono_jit_thread_attach full-aot will look - * in the plt, which causes a call into the generic trampoline, which in turn - * tries to resolve the lmf_addr creating a cyclic dependency. We cannot - * call mono_jit_thread_attach from the native-to-managed wrapper, without - * mono_get_lmf_addr, and mono_get_lmf_addr requires the thread to be attached. - */ - - mono_thread_attach (mono_get_root_domain ()); - mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background); - - if ((jit_tls = mono_native_tls_get_value (mono_jit_tls_id))) - return &jit_tls->lmf; - - g_assert_not_reached (); - return NULL; -#endif + return (MonoLMF **)mono_tls_get_lmf_addr (); } void mono_set_lmf (MonoLMF *lmf) { -#if defined(MONO_HAVE_FAST_TLS) && defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) - MONO_FAST_TLS_SET (mono_lmf, lmf); -#endif - +#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR) + mono_tls_set_lmf (lmf); +#else (*mono_get_lmf_addr ()) = lmf; +#endif } MonoJitTlsData* mono_get_jit_tls (void) { - return (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); + return (MonoJitTlsData *)mono_tls_get_jit_tls (); } static void @@ -811,11 +758,7 @@ mono_set_jit_tls (MonoJitTlsData *jit_tls) { MonoThreadInfo *info; - mono_native_tls_set_value (mono_jit_tls_id, jit_tls); - -#ifdef MONO_HAVE_FAST_TLS - MONO_FAST_TLS_SET (mono_jit_tls, jit_tls); -#endif + mono_tls_set_jit_tls (jit_tls); /* Save it into MonoThreadInfo so it can be accessed by mono_thread_state_init_from_handle () */ info = mono_thread_info_current (); @@ -828,9 +771,7 @@ mono_set_lmf_addr (gpointer lmf_addr) { MonoThreadInfo *info; -#ifdef MONO_HAVE_FAST_TLS - MONO_FAST_TLS_SET (mono_lmf_addr, lmf_addr); -#endif + mono_tls_set_lmf_addr (lmf_addr); /* Save it into MonoThreadInfo so it can be accessed by mono_thread_state_init_from_handle () */ info = mono_thread_info_current (); @@ -861,11 +802,7 @@ mono_jit_thread_attach (MonoDomain *domain) g_assert (domain); -#ifdef MONO_HAVE_FAST_TLS - attached = MONO_FAST_TLS_GET (mono_lmf_addr) != NULL; -#else - attached = mono_native_tls_get_value (mono_jit_tls_id) != NULL; -#endif + attached = mono_tls_get_jit_tls () != NULL; if (!attached) { mono_thread_attach (domain); @@ -923,7 +860,7 @@ setup_jit_tls_data (gpointer stack_start, gpointer abort_func) MonoJitTlsData *jit_tls; MonoLMF *lmf; - jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); + jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls (); if (jit_tls) return jit_tls; @@ -939,10 +876,18 @@ setup_jit_tls_data (gpointer stack_start, gpointer abort_func) jit_tls->first_lmf = lmf; -#if defined(MONO_HAVE_FAST_TLS) && defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) + /* + * We can have 2 configurations for accessing lmf. + * We can use only the tls_lmf_addr variable, which will store the address of + * jit_tls->lmf, or, if we have MONO_ARCH_ENABLE_MONO_LMF_VAR enabled, we can + * use both tls_lmf_addr and tls_lmf variables (in this case we need to have + * means of getting the address of a tls variable; this can be done always + * when using __thread or, on osx, even when using pthread) + */ +#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR) /* jit_tls->lmf is unused */ - MONO_FAST_TLS_SET (mono_lmf, lmf); - mono_set_lmf_addr (MONO_FAST_TLS_ADDR (mono_lmf)); + mono_tls_set_lmf (lmf); + mono_set_lmf_addr (mono_tls_get_tls_addr (TLS_KEY_LMF)); #else mono_set_lmf_addr (&jit_tls->lmf); @@ -1041,46 +986,6 @@ mini_thread_cleanup (MonoNativeThreadId tid) free_jit_tls_data (jit_tls); } -int -mini_get_tls_offset (MonoTlsKey key) -{ - int offset; - g_assert (MONO_ARCH_HAVE_TLS_GET); - - switch (key) { - case TLS_KEY_THREAD: - offset = mono_thread_get_tls_offset (); - break; - case TLS_KEY_JIT_TLS: - offset = mono_get_jit_tls_offset (); - break; - case TLS_KEY_DOMAIN: - offset = mono_domain_get_tls_offset (); - break; - case TLS_KEY_LMF: - offset = mono_get_lmf_tls_offset (); - break; - case TLS_KEY_LMF_ADDR: - offset = mono_get_lmf_addr_tls_offset (); - break; - default: - offset = mono_tls_key_get_offset (key); - g_assert (offset != -1); - break; - } - - return offset; -} - -static gboolean -mini_tls_key_supported (MonoTlsKey key) -{ - if (!MONO_ARCH_HAVE_TLS_GET) - return FALSE; - - return mini_get_tls_offset (key) != -1; -} - MonoJumpInfo * mono_patch_info_list_prepend (MonoJumpInfo *list, int ip, MonoJumpInfoType type, gconstpointer target) { @@ -1258,9 +1163,10 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_SEQ_POINT_INFO: case MONO_PATCH_INFO_METHOD_RGCTX: case MONO_PATCH_INFO_SIGNATURE: - case MONO_PATCH_INFO_TLS_OFFSET: case MONO_PATCH_INFO_METHOD_CODE_SLOT: case MONO_PATCH_INFO_AOT_JIT_INFO: + case MONO_PATCH_INFO_GET_TLS_TRAMP: + case MONO_PATCH_INFO_SET_TLS_TRAMP: return (ji->type << 8) | (gssize)ji->data.target; case MONO_PATCH_INFO_GSHAREDVT_CALL: return (ji->type << 8) | (gssize)ji->data.gsharedvt->method; @@ -1275,11 +1181,10 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR: case MONO_PATCH_INFO_GC_NURSERY_START: case MONO_PATCH_INFO_GC_NURSERY_BITS: - case MONO_PATCH_INFO_JIT_TLS_ID: case MONO_PATCH_INFO_GOT_OFFSET: case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: case MONO_PATCH_INFO_AOT_MODULE: - case MONO_PATCH_INFO_GET_TLS_TRAMP: + case MONO_PATCH_INFO_JIT_THREAD_ATTACH: return (ji->type << 8); case MONO_PATCH_INFO_CASTCLASS_CACHE: return (ji->type << 8) | (ji->data.index); @@ -1384,7 +1289,7 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, unsigned char *ip = patch_info->ip.i + code; gconstpointer target = NULL; - mono_error_init (error); + error_init (error); switch (patch_info->type) { case MONO_PATCH_INFO_BB: @@ -1499,11 +1404,11 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, break; case MONO_PATCH_INFO_IID: mono_class_init (patch_info->data.klass); - target = GINT_TO_POINTER ((int)patch_info->data.klass->interface_id); + target = GUINT_TO_POINTER (patch_info->data.klass->interface_id); break; case MONO_PATCH_INFO_ADJUSTED_IID: mono_class_init (patch_info->data.klass); - target = GINT_TO_POINTER ((int)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P))); + target = GUINT_TO_POINTER ((guint32)(-((patch_info->data.klass->interface_id + 1) * SIZEOF_VOID_P))); break; case MONO_PATCH_INFO_VTABLE: target = mono_class_vtable (domain, patch_info->data.klass); @@ -1687,20 +1592,6 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mono_domain_alloc0 (domain, sizeof (gpointer)); break; } - case MONO_PATCH_INFO_JIT_TLS_ID: { - target = (gpointer) (size_t) mono_jit_tls_id; - break; - } - case MONO_PATCH_INFO_TLS_OFFSET: { - int offset; - - offset = mini_get_tls_offset ((MonoTlsKey)GPOINTER_TO_INT (patch_info->data.target)); -#ifdef MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET - offset = mono_arch_translate_tls_offset (offset); -#endif - target = GINT_TO_POINTER (offset); - break; - } case MONO_PATCH_INFO_OBJC_SELECTOR_REF: { target = NULL; break; @@ -1720,12 +1611,17 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mini_get_gsharedvt_wrapper (TRUE, NULL, patch_info->data.sig, NULL, -1, FALSE); break; case MONO_PATCH_INFO_GET_TLS_TRAMP: -#ifdef MONO_ARCH_HAVE_GET_TLS_TRAMP - target = mono_arch_get_get_tls_tramp (); -#else - target = NULL; -#endif + target = mono_tls_get_tls_getter (patch_info->data.index, FALSE); + break; + case MONO_PATCH_INFO_SET_TLS_TRAMP: + target = mono_tls_get_tls_setter (patch_info->data.index, FALSE); + break; + case MONO_PATCH_INFO_JIT_THREAD_ATTACH: { + MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("mono_jit_thread_attach"); + g_assert (mi); + target = mi->func; break; + } default: g_assert_not_reached (); } @@ -1874,7 +1770,12 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er MonoJitICallInfo *callinfo = NULL; WrapperInfo *winfo = NULL; - mono_error_init (error); + error_init (error); + +#ifdef ENABLE_INTERPRETER + if (mono_use_interpreter) + return mono_interp_create_method_pointer (method, error); +#endif if (mono_llvm_only) /* Should be handled by the caller */ @@ -2067,6 +1968,7 @@ mono_jit_free_method (MonoDomain *domain, MonoMethod *method) return; mono_debug_remove_method (method, domain); + mono_lldb_remove_method (domain, method, ji); mono_domain_lock (domain); g_hash_table_remove (domain_jit_info (domain)->dynamic_code_hash, method); @@ -2376,7 +2278,7 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void gpointer *param_refs; int i, pindex; - mono_error_init (error); + error_init (error); g_assert (info->gsharedvt_invoke); @@ -2460,7 +2362,12 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoJitInfo *ji = NULL; gboolean callee_gsharedvt = FALSE; - mono_error_init (error); +#ifdef ENABLE_INTERPRETER + if (mono_use_interpreter) + return mono_interp_runtime_invoke (method, obj, params, exc, error); +#endif + + error_init (error); if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) { g_warning ("Ignoring invocation of an instance method on a NULL instance.\n"); @@ -2824,6 +2731,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) ji = mono_jit_info_table_find_internal (mono_domain_get (), (char *)mono_arch_ip_from_context (ctx), TRUE, TRUE); + MONO_ENTER_GC_UNSAFE_UNBALANCED; + #if defined(MONO_ARCH_HAVE_IS_INT_OVERFLOW) if (mono_arch_is_int_overflow (ctx, info)) /* @@ -2839,33 +2748,37 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) if (!ji) { if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) - return; + goto exit; - mono_handle_native_sigsegv (SIGSEGV, ctx, info); + mono_handle_native_crash ("SIGFPE", ctx, info); if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); - return; + goto exit; } } mono_arch_handle_exception (ctx, exc); + +exit: + MONO_EXIT_GC_UNSAFE_UNBALANCED; } MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) { - MonoException *exc; + MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); MONO_SIG_HANDLER_GET_CONTEXT; if (mono_runtime_get_no_exec ()) exit (1); - MONO_ENTER_GC_UNSAFE_UNBALANCED; - exc = mono_get_exception_execution_engine ("SIGILL"); - - mono_arch_handle_exception (ctx, exc); + mono_handle_native_crash ("SIGILL", ctx, info); + if (mono_do_crash_chaining) { + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); + return; + } - MONO_EXIT_GC_UNSAFE_UNBALANCED; + g_assert_not_reached (); } #if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32) @@ -2875,7 +2788,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) { MonoJitInfo *ji; - MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id); + MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls (); gpointer fault_addr = NULL; #ifdef HAVE_SIG_INFO MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); @@ -2907,7 +2820,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) if (!mono_domain_get () || !jit_tls) { if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; - mono_handle_native_sigsegv (SIGSEGV, ctx, info); + mono_handle_native_crash ("SIGSEGV", ctx, info); if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; @@ -2954,7 +2867,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; - mono_handle_native_sigsegv (SIGSEGV, ctx, info); + mono_handle_native_crash ("SIGSEGV", ctx, info); if (mono_do_crash_chaining) { mono_chain_signal (MONO_SIG_HANDLER_PARAMS); @@ -2971,9 +2884,13 @@ MONO_SIG_HANDLER_FUNC (, mono_sigint_signal_handler) MonoException *exc; MONO_SIG_HANDLER_GET_CONTEXT; + MONO_ENTER_GC_UNSAFE_UNBALANCED; + exc = mono_get_exception_execution_engine ("Interrupted (SIGINT)."); mono_arch_handle_exception (ctx, exc); + + MONO_EXIT_GC_UNSAFE_UNBALANCED; } #ifndef DISABLE_REMOTING @@ -2991,7 +2908,7 @@ mono_jit_create_remoting_trampoline (MonoDomain *domain, MonoMethod *method, Mon MonoMethod *nm; guint8 *addr = NULL; - mono_error_init (error); + error_init (error); if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && mono_method_signature (method)->generic_param_count) { return mono_create_specific_trampoline (method, MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING, @@ -3131,6 +3048,10 @@ mini_init_delegate (MonoDelegate *del) { if (mono_llvm_only) del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr); +#ifdef ENABLE_INTERPRETER + if (mono_use_interpreter) + mono_interp_init_delegate (del); +#endif } char* @@ -3226,8 +3147,8 @@ mini_parse_debug_option (const char *option) debug_options.break_on_unverified = TRUE; else if (!strcmp (option, "no-gdb-backtrace")) debug_options.no_gdb_backtrace = TRUE; - else if (!strcmp (option, "suspend-on-sigsegv")) - debug_options.suspend_on_sigsegv = TRUE; + else if (!strcmp (option, "suspend-on-native-crash") || !strcmp (option, "suspend-on-sigsegv")) + debug_options.suspend_on_native_crash = TRUE; else if (!strcmp (option, "suspend-on-exception")) debug_options.suspend_on_exception = TRUE; else if (!strcmp (option, "suspend-on-unhandled")) @@ -3238,6 +3159,8 @@ mini_parse_debug_option (const char *option) debug_options.dyn_runtime_invoke = TRUE; else if (!strcmp (option, "gdb")) debug_options.gdb = TRUE; + else if (!strcmp (option, "lldb")) + debug_options.lldb = TRUE; else if (!strcmp (option, "explicit-null-checks")) debug_options.explicit_null_checks = TRUE; else if (!strcmp (option, "gen-seq-points")) @@ -3256,8 +3179,8 @@ mini_parse_debug_option (const char *option) debug_options.soft_breakpoints = TRUE; else if (!strcmp (option, "check-pinvoke-callconv")) debug_options.check_pinvoke_callconv = TRUE; - else if (!strcmp (option, "arm-use-fallback-tls")) - debug_options.arm_use_fallback_tls = TRUE; + else if (!strcmp (option, "use-fallback-tls")) + debug_options.use_fallback_tls = TRUE; else if (!strcmp (option, "debug-domain-unload")) mono_enable_debug_domain_unload (TRUE); else if (!strcmp (option, "partial-sharing")) @@ -3290,7 +3213,7 @@ mini_parse_debug_options (void) if (!mini_parse_debug_option (arg)) { 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', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'no-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n"); + fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-native-crash', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'no-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n"); exit (1); } } @@ -3526,6 +3449,22 @@ mini_free_jit_domain_info (MonoDomain *domain) domain->runtime_info = NULL; } +#ifdef MONO_ARCH_HAVE_CODE_CHUNK_TRACKING + +static void +code_manager_chunk_new (void *chunk, int size) +{ + mono_arch_code_chunk_new (chunk, size); +} + +static void +code_manager_chunk_destroy (void *chunk) +{ + mono_arch_code_chunk_destroy (chunk); +} + +#endif + #ifdef ENABLE_LLVM static gboolean llvm_init_inner (void) @@ -3563,6 +3502,13 @@ mini_llvm_init (void) #endif } +void +mini_profiler_enable_with_options (const char* profile_options) +{ + mini_enable_profiler = TRUE; + mini_profiler_options = g_strdup (profile_options); +} + MonoDomain * mini_init (const char *filename, const char *runtime_version) { @@ -3570,6 +3516,7 @@ mini_init (const char *filename, const char *runtime_version) MonoDomain *domain; MonoRuntimeCallbacks callbacks; MonoThreadInfoRuntimeCallbacks ticallbacks; + MonoCodeManagerCallbacks code_manager_callbacks; MONO_VES_INIT_BEGIN (); @@ -3586,6 +3533,8 @@ mini_init (const char *filename, const char *runtime_version) mono_cross_helpers_run (); + mono_counters_init (); + mini_jit_init (); /* Happens when using the embedding interface */ @@ -3600,15 +3549,7 @@ mini_init (const char *filename, const char *runtime_version) mono_set_generic_sharing_vt_supported (TRUE); #endif -#ifdef MONO_HAVE_FAST_TLS - MONO_FAST_TLS_INIT (mono_jit_tls); - MONO_FAST_TLS_INIT (mono_lmf_addr); -#ifdef MONO_ARCH_ENABLE_MONO_LMF_VAR - MONO_FAST_TLS_INIT (mono_lmf); -#endif -#endif - - mono_runtime_set_has_tls_get (MONO_ARCH_HAVE_TLS_GET); + mono_tls_init_runtime_keys (); if (!global_codeman) global_codeman = mono_code_manager_new (); @@ -3620,7 +3561,6 @@ mini_init (const char *filename, const char *runtime_version) callbacks.set_cast_details = mono_set_cast_details; callbacks.debug_log = mono_debugger_agent_debug_log; callbacks.debug_log_is_enabled = mono_debugger_agent_debug_log_is_enabled; - callbacks.tls_key_supported = mini_tls_key_supported; callbacks.get_vtable_trampoline = mini_get_vtable_trampoline; callbacks.get_imt_trampoline = mini_get_imt_trampoline; callbacks.imt_entry_inited = mini_imt_entry_inited; @@ -3634,6 +3574,11 @@ mini_init (const char *filename, const char *runtime_version) callbacks.compile_method = mono_jit_compile_method; callbacks.create_jump_trampoline = mono_create_jump_trampoline; callbacks.create_jit_trampoline = mono_create_jit_trampoline; + callbacks.create_delegate_trampoline = mono_create_delegate_trampoline; + callbacks.free_method = mono_jit_free_method; +#ifndef DISABLE_REMOTING + callbacks.create_remoting_trampoline = mono_jit_create_remoting_trampoline; +#endif #endif mono_install_callbacks (&callbacks); @@ -3644,8 +3589,6 @@ mini_init (const char *filename, const char *runtime_version) ticallbacks.thread_state_init_from_handle = mono_thread_state_init_from_handle; ticallbacks.thread_state_init = mono_thread_state_init; - mono_counters_init (); - #ifndef HOST_WIN32 mono_w32handle_init (); #endif @@ -3657,6 +3600,13 @@ mini_init (const char *filename, const char *runtime_version) mono_code_manager_init (); + memset (&code_manager_callbacks, 0, sizeof (code_manager_callbacks)); +#ifdef MONO_ARCH_HAVE_CODE_CHUNK_TRACKING + code_manager_callbacks.chunk_new = code_manager_chunk_new; + code_manager_callbacks.chunk_destroy = code_manager_chunk_destroy; +#endif + mono_code_manager_install_callbacks (&code_manager_callbacks); + mono_hwcap_init (); mono_arch_cpu_init (); @@ -3665,6 +3615,11 @@ mini_init (const char *filename, const char *runtime_version) mono_unwind_init (); + if (mini_get_debug_options ()->lldb || g_getenv ("MONO_LLDB")) { + mono_lldb_init (""); + mono_dont_free_domains = TRUE; + } + #ifdef XDEBUG_ENABLED if (g_getenv ("MONO_XDEBUG")) { const char *xdebug_opts = g_getenv ("MONO_XDEBUG"); @@ -3692,8 +3647,6 @@ mini_init (const char *filename, const char *runtime_version) mono_trampolines_init (); - mono_native_tls_alloc (&mono_jit_tls_id, NULL); - if (default_opt & MONO_OPT_AOT) mono_aot_init (); @@ -3703,17 +3656,14 @@ mini_init (const char *filename, const char *runtime_version) mono_set_generic_sharing_supported (TRUE); #endif + mono_threads_signals_init (); + #ifndef MONO_CROSS_COMPILE mono_runtime_install_handlers (); #endif mono_threads_install_cleanup (mini_thread_cleanup); #ifdef JIT_TRAMPOLINES_WORK - mono_install_free_method (mono_jit_free_method); -#ifndef DISABLE_REMOTING - mono_install_remoting_trampoline (mono_jit_create_remoting_trampoline); -#endif - mono_install_delegate_trampoline (mono_create_delegate_trampoline); mono_install_create_domain_hook (mini_create_jit_domain_info); mono_install_free_domain_hook (mini_free_jit_domain_info); #endif @@ -3721,6 +3671,11 @@ mini_init (const char *filename, const char *runtime_version) mono_install_get_class_from_name (mono_aot_get_class_from_name); mono_install_jit_info_find_in_aot (mono_aot_find_jit_info); + if (mini_profiler_enabled ()) { + mono_profiler_load (mini_profiler_get_options ()); + mono_profiler_thread_name (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()), "Main"); + } + if (debug_options.collect_pagefault_stats) mono_aot_set_make_unreadable (TRUE); @@ -4062,14 +4017,27 @@ register_icalls (void) register_icall (mono_throw_method_access, "mono_throw_method_access", "void ptr ptr", FALSE); register_icall_no_wrapper (mono_dummy_jit_icall, "mono_dummy_jit_icall", "void"); - register_icall_with_wrapper (mono_monitor_enter, "mono_monitor_enter", "void obj"); - register_icall_with_wrapper (mono_monitor_enter_v4, "mono_monitor_enter_v4", "void obj ptr"); + register_icall_with_wrapper (mono_monitor_enter_internal, "mono_monitor_enter_internal", "void obj"); + register_icall_with_wrapper (mono_monitor_enter_v4_internal, "mono_monitor_enter_v4_internal", "void obj ptr"); register_icall_no_wrapper (mono_monitor_enter_fast, "mono_monitor_enter_fast", "int obj"); register_icall_no_wrapper (mono_monitor_enter_v4_fast, "mono_monitor_enter_v4_fast", "int obj ptr"); #ifdef TARGET_IOS register_icall (pthread_getspecific, "pthread_getspecific", "ptr ptr", TRUE); #endif + /* Register tls icalls */ + register_icall_no_wrapper (mono_tls_get_thread, "mono_tls_get_thread", "ptr"); + register_icall_no_wrapper (mono_tls_get_jit_tls, "mono_tls_get_jit_tls", "ptr"); + register_icall_no_wrapper (mono_tls_get_domain, "mono_tls_get_domain", "ptr"); + register_icall_no_wrapper (mono_tls_get_lmf, "mono_tls_get_lmf", "ptr"); + register_icall_no_wrapper (mono_tls_get_sgen_thread_info, "mono_tls_get_sgen_thread_info", "ptr"); + register_icall_no_wrapper (mono_tls_get_lmf_addr, "mono_tls_get_lmf_addr", "ptr"); + register_icall_no_wrapper (mono_tls_set_thread, "mono_tls_set_thread", "void ptr"); + register_icall_no_wrapper (mono_tls_set_jit_tls, "mono_tls_set_jit_tls", "void ptr"); + register_icall_no_wrapper (mono_tls_set_domain, "mono_tls_set_domain", "void ptr"); + register_icall_no_wrapper (mono_tls_set_lmf, "mono_tls_set_lmf", "void ptr"); + register_icall_no_wrapper (mono_tls_set_sgen_thread_info, "mono_tls_set_sgen_thread_info", "void ptr"); + register_icall_no_wrapper (mono_tls_set_lmf_addr, "mono_tls_set_lmf_addr", "void ptr"); } MonoJitStats mono_jit_stats = {0}; @@ -4147,9 +4115,11 @@ mini_cleanup (MonoDomain *domain) mono_runtime_cleanup (domain); #endif + mono_threadpool_cleanup (); + mono_profiler_shutdown (); - free_jit_tls_data ((MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id)); + free_jit_tls_data ((MonoJitTlsData *)mono_tls_get_jit_tls ()); mono_icall_cleanup (); @@ -4190,7 +4160,7 @@ mini_cleanup (MonoDomain *domain) if (mono_inject_async_exc_method) mono_method_desc_free (mono_inject_async_exc_method); - mono_native_tls_free (mono_jit_tls_id); + mono_tls_free_keys (); mono_os_mutex_destroy (&jit_mutex);