#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/checked-build.h>
#include <mono/metadata/w32handle.h>
-#include <mono/io-layer/io-layer.h>
#include "mini.h"
#include "seq-points.h"
#include "mini-gc.h"
#include "mini-llvm.h"
#include "debugger-agent.h"
+#include "lldb.h"
#ifdef MONO_ARCH_LLVM_SUPPORTED
#ifdef ENABLE_LLVM
*/
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;
#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)
{
*/
#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)
}
}
+/* 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()
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)
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;
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*
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));
mono_error_init (error);
+#ifdef ENABLE_INTERPRETER
+ if (mono_use_interpreter)
+ return interp_create_method_pointer (method, error);
+#endif
+
if (mono_llvm_only)
/* Should be handled by the caller */
g_assert (!(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED));
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);
MonoJitInfo *ji = NULL;
gboolean callee_gsharedvt = FALSE;
+#ifdef ENABLE_INTERPRETER
+ if (mono_use_interpreter)
+ return interp_mono_runtime_invoke (method, obj, params, exc, error);
+#endif
+
mono_error_init (error);
if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) {
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))
/*
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)
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
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"))
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"))
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);
}
}
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)
#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)
{
MonoDomain *domain;
MonoRuntimeCallbacks callbacks;
MonoThreadInfoRuntimeCallbacks ticallbacks;
+ MonoCodeManagerCallbacks code_manager_callbacks;
MONO_VES_INIT_BEGIN ();
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 ();
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");
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);