X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=9336b94f2d2bcc0f5935fa09163f6f5bfb9e0098;hb=b0b4fb685a8637231874c8d30b63365eb721283e;hp=0c67814f126135e9e89b8a59f6204a26b1539e8e;hpb=a650d4d72cf11da18ab71687f10298fad01fa33f;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 0c67814f126..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,6 +90,10 @@ #endif #endif +#ifdef ENABLE_INTERPRETER +#include "interp/interp.h" +#endif + static guint32 default_opt = 0; static gboolean default_opt_set = FALSE; @@ -110,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; @@ -121,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) { @@ -233,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) @@ -352,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() @@ -480,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) @@ -691,7 +715,7 @@ register_dyn_icall (gpointer func, const char *name, const char *sigstr, gboolea MonoLMF * mono_get_lmf (void) { -#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) +#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR) return (MonoLMF *)mono_tls_get_lmf (); #else MonoJitTlsData *jit_tls; @@ -716,11 +740,11 @@ mono_get_lmf_addr (void) void mono_set_lmf (MonoLMF *lmf) { -#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) +#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR) mono_tls_set_lmf (lmf); -#endif - +#else (*mono_get_lmf_addr ()) = lmf; +#endif } MonoJitTlsData* @@ -852,7 +876,15 @@ setup_jit_tls_data (gpointer stack_start, gpointer abort_func) jit_tls->first_lmf = lmf; -#if 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_tls_set_lmf (lmf); mono_set_lmf_addr (mono_tls_get_tls_addr (TLS_KEY_LMF)); @@ -1257,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: @@ -1738,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 */ @@ -1931,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); @@ -2240,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); @@ -2324,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"); @@ -2688,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)) /* @@ -2703,16 +2748,19 @@ 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_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) @@ -2836,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 @@ -2856,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, @@ -2996,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* @@ -3091,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")) @@ -3103,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")) @@ -3155,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', '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); } } @@ -3391,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) @@ -3428,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) { @@ -3435,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 (); @@ -3518,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 (); @@ -3526,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"); @@ -3577,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); @@ -4016,6 +4115,8 @@ mini_cleanup (MonoDomain *domain) mono_runtime_cleanup (domain); #endif + mono_threadpool_cleanup (); + mono_profiler_shutdown (); free_jit_tls_data ((MonoJitTlsData *)mono_tls_get_jit_tls ());