X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdriver.c;h=7f2a70415d90235ad481ad21ba4fd28d97af1c29;hb=7c2f0956be09bddfd5e7540495250103459085ad;hp=29bb6bd924b6fb33131f377ad10fbcd55139bc25;hpb=8efe5cab3eab18bef5ac682dc66904c4da1f7b9b;p=mono.git diff --git a/mono/mini/driver.c b/mono/mini/driver.c index 29bb6bd924b..7f2a70415d9 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -45,16 +45,17 @@ #include #include #include +#include #include "mono/utils/mono-counters.h" -#include +#include #include "mini.h" #include "jit.h" #include #include -#include "inssel.h" #include #include "version.h" +#include "debugger-agent.h" static FILE *mini_stats_fd = NULL; @@ -114,13 +115,13 @@ opt_funcs [sizeof (int) * 8] = { NULL }; + #define DEFAULT_OPTIMIZATIONS ( \ MONO_OPT_PEEPHOLE | \ MONO_OPT_CFOLD | \ MONO_OPT_INLINE | \ MONO_OPT_CONSPROP | \ MONO_OPT_COPYPROP | \ - MONO_OPT_TREEPROP | \ MONO_OPT_DEADCE | \ MONO_OPT_BRANCH | \ MONO_OPT_LINEARS | \ @@ -129,6 +130,7 @@ opt_funcs [sizeof (int) * 8] = { MONO_OPT_EXCEPTION | \ MONO_OPT_CMOV | \ MONO_OPT_GSHARED | \ + MONO_OPT_SIMD | \ MONO_OPT_AOT) #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP) @@ -213,6 +215,9 @@ parse_debug_options (const char* p) } else if (!strncmp (p, "mdb-optimizations", 17)) { opt->mdb_optimizations = TRUE; p += 17; + } else if (!strncmp (p, "gdb", 3)) { + opt->gdb = TRUE; + p += 3; } else { fprintf (stderr, "Invalid debug option `%s', use --help-debug for details\n", p); return FALSE; @@ -295,6 +300,11 @@ opt_sets [] = { MONO_OPT_BRANCH, MONO_OPT_CFOLD, MONO_OPT_FCMOV, +#ifdef MONO_ARCH_SIMD_INTRINSICS + MONO_OPT_SIMD, + MONO_OPT_SSE2, + MONO_OPT_SIMD | MONO_OPT_SSE2, +#endif MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_INTRINS, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP, @@ -307,9 +317,9 @@ opt_sets [] = { MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM | MONO_OPT_SSAPRE, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM, - MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_TREEPROP, MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSAPRE, - MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM | MONO_OPT_SHARED + MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM | MONO_OPT_SHARED, + DEFAULT_OPTIMIZATIONS, }; typedef int (*TestMethod) (void); @@ -323,7 +333,8 @@ domain_dump_native_code (MonoDomain *domain) { #endif static int -mini_regression (MonoImage *image, int verbose, int *total_run) { +mini_regression (MonoImage *image, int verbose, int *total_run) +{ guint32 i, opt, opt_flags; MonoMethod *method; MonoCompile *cfg; @@ -331,6 +342,10 @@ mini_regression (MonoImage *image, int verbose, int *total_run) { int result, expected, failed, cfailed, run, code_size, total; TestMethod func; GTimer *timer = g_timer_new (); + MonoDomain *domain = mono_domain_get (); + guint32 exclude = 0; + + mono_arch_cpu_optimizazions (&exclude); if (mini_stats_fd) { fprintf (mini_stats_fd, "$stattitle = \'Mono Benchmark Results (various optimizations)\';\n"); @@ -355,7 +370,9 @@ mini_regression (MonoImage *image, int verbose, int *total_run) { /* load the metadata */ for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) { - method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); + method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); + if (!method) + continue; mono_class_init (method->klass); if (!strncmp (method->name, "test_", 5) && mini_stats_fd) { @@ -371,7 +388,7 @@ mini_regression (MonoImage *image, int verbose, int *total_run) { for (opt = 0; opt < G_N_ELEMENTS (opt_sets); ++opt) { double elapsed, comp_time, start_time; - opt_flags = opt_sets [opt]; + opt_flags = opt_sets [opt] & ~exclude; mono_set_defaults (verbose, opt_flags); n = opt_descr (opt_flags); g_print ("Test run: image=%s, opts=%s\n", mono_image_get_filename (image), n); @@ -380,16 +397,18 @@ mini_regression (MonoImage *image, int verbose, int *total_run) { comp_time = elapsed = 0.0; /* fixme: ugly hack - delete all previously compiled methods */ - g_hash_table_destroy (mono_domain_get ()->jit_trampoline_hash); - mono_domain_get ()->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); - mono_internal_hash_table_destroy (&(mono_domain_get ()->jit_code_hash)); - mono_jit_code_hash_init (&(mono_domain_get ()->jit_code_hash)); + g_hash_table_destroy (domain_jit_info (domain)->jit_trampoline_hash); + domain_jit_info (domain)->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); + mono_internal_hash_table_destroy (&(domain->jit_code_hash)); + mono_jit_code_hash_init (&(domain->jit_code_hash)); g_timer_start (timer); if (mini_stats_fd) fprintf (mini_stats_fd, "["); for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) { - method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); + method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); + if (!method) + continue; if (strncmp (method->name, "test_", 5) == 0) { expected = atoi (method->name + 5); run++; @@ -829,6 +848,8 @@ compile_all_methods_thread_main (CompileAllThreadArgs *args) continue; method = mono_get_method (image, token, NULL); + if (!method) + continue; if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || @@ -924,16 +945,40 @@ static void main_thread_handler (gpointer user_data) MainThreadArgs *main_args = user_data; MonoAssembly *assembly; - assembly = mono_domain_assembly_open (main_args->domain, main_args->file); - if (!assembly){ - fprintf (stderr, "Can not open image %s\n", main_args->file); - exit (1); - } - if (mono_compile_aot) { - int res = mono_compile_assembly (assembly, main_args->opts, main_args->aot_options); - printf ("AOT RESULT %d\n", res); + int i, res; + + /* Treat the other arguments as assemblies to compile too */ + for (i = 0; i < main_args->argc; ++i) { + assembly = mono_domain_assembly_open (main_args->domain, main_args->argv [i]); + if (!assembly) { + fprintf (stderr, "Can not open image %s\n", main_args->argv [i]); + exit (1); + } + /* Check that the assembly loaded matches the filename */ + { + MonoImageOpenStatus status; + MonoImage *img; + + img = mono_image_open (main_args->argv [i], &status); + if (img && strcmp (img->name, assembly->image->name)) { + fprintf (stderr, "Error: Loaded assembly '%s' doesn't match original file name '%s'. Set MONO_PATH to the assembly's location.\n", assembly->image->name, img->name); + exit (1); + } + } + res = mono_compile_assembly (assembly, main_args->opts, main_args->aot_options); + if (res != 0) { + fprintf (stderr, "AOT of image %s failed.\n", main_args->argv [i]); + exit (1); + } + } } else { + assembly = mono_domain_assembly_open (main_args->domain, main_args->file); + if (!assembly){ + fprintf (stderr, "Can not open image %s\n", main_args->file); + exit (1); + } + /* * This must be done in a thread managed by mono since it can invoke * managed code. @@ -945,6 +990,72 @@ static void main_thread_handler (gpointer user_data) } } +static int +load_agent (MonoDomain *domain, char *desc) +{ + char* col = strchr (desc, ':'); + char *agent, *args; + MonoAssembly *agent_assembly; + MonoImage *image; + MonoMethod *method; + guint32 entry; + MonoArray *main_args; + gpointer pa [1]; + MonoImageOpenStatus open_status; + + if (col) { + agent = g_memdup (desc, col - desc + 1); + agent [col - desc] = '\0'; + args = col + 1; + } else { + agent = g_strdup (desc); + args = NULL; + } + + agent_assembly = mono_assembly_open (agent, &open_status); + if (!agent_assembly) { + fprintf (stderr, "Cannot open agent assembly '%s': %s.\n", agent, mono_image_strerror (open_status)); + g_free (agent); + return 2; + } + + /* + * Can't use mono_jit_exec (), as it sets things which might confuse the + * real Main method. + */ + image = mono_assembly_get_image (agent_assembly); + entry = mono_image_get_entry_point (image); + if (!entry) { + g_print ("Assembly '%s' doesn't have an entry point.\n", mono_image_get_filename (image)); + g_free (agent); + return 1; + } + + method = mono_get_method (image, entry, NULL); + if (method == NULL){ + g_print ("The entry point method of assembly '%s' could not be loaded\n", agent); + g_free (agent); + return 1; + } + + mono_thread_set_main (mono_thread_current ()); + + if (args) { + main_args = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, 1); + mono_array_set (main_args, MonoString*, 0, mono_string_new (domain, args)); + } else { + main_args = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, 0); + } + + g_free (agent); + + pa [0] = main_args; + /* Pass NULL as 'exc' so unhandled exceptions abort the runtime */ + mono_runtime_invoke (method, NULL, pa, NULL); + + return 0; +} + static void mini_usage_jitdeveloper (void) { @@ -962,10 +1073,12 @@ mini_usage_jitdeveloper (void) " --regression Runs the regression test contained in the assembly\n" " --statfile FILE Sets the stat file to FILE\n" " --stats Print statistics about the JIT operations\n" - " --wapi=hps|semdel IO-layer maintenance\n" + " --wapi=hps|semdel|seminfo IO-layer maintenance\n" " --inject-async-exc METHOD OFFSET Inject an asynchronous exception at METHOD\n" " --verify-all Run the verifier on all methods\n" " --full-aot Avoid JITting any code\n" + " --agent=ASSEMBLY[:ARG] Loads the specific agent assembly and executes its Main method with the given argument before loading the main assembly.\n" + " --no-x86-stack-align Don't align stack on x86\n" "\n" "Other options:\n" " --graph[=TYPE] METHOD Draws a graph of the specified method:\n"); @@ -993,6 +1106,7 @@ mini_usage (void) "Development:\n" " --aot Compiles the assembly to native code\n" " --debug[=] Enable debugging support, use --help-debug for details\n" + " --debugger-agent=options Enable the debugger agent\n" " --profile[=profiler] Runs in profiling mode with the specified profiler module\n" " --trace[=EXPR] Enable tracing, use --help-trace for details\n" " --help-devel Shows more options available to developers\n" @@ -1006,7 +1120,10 @@ mini_usage (void) " --optimize=OPT Turns on or off a specific optimization\n" " Use --list-opt to get a list of optimizations\n" " --security[=mode] Turns on the unsupported security manager (off by default)\n" - " mode is one of cas, core-clr, verifiable or validil\n"); + " mode is one of cas, core-clr, verifiable or validil\n" + " --attach=OPTIONS Pass OPTIONS to the attach agent in the runtime.\n" + " Currently the only supported option is 'disable'.\n" + ); } static void @@ -1024,8 +1141,9 @@ mini_trace_usage (void) " M:Type:Method Specifies a method\n" " N:Namespace Specifies a namespace\n" " T:Type Specifies a type\n" - " +EXPR Includes expression\n" + " EXPR Includes expression\n" " -EXPR Excludes expression\n" + " EXPR,EXPR Multiple expressions\n" " disabled Don't print any output until toggled via SIGUSR2\n"); } @@ -1045,14 +1163,10 @@ mini_debug_usage (void) " process with the debugger.\n"); } -#if defined(__arm__) && defined(__ARM_EABI__) +#if defined(MONO_ARCH_ARCHITECTURE) /* Redefine ARCHITECTURE to include more information */ #undef ARCHITECTURE -#if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define ARCHITECTURE "armel" -#else -#define ARCHITECTURE "armeb" -#endif +#define ARCHITECTURE MONO_ARCH_ARCHITECTURE #endif static const char info[] = @@ -1124,6 +1238,8 @@ mono_main (int argc, char* argv[]) char *profile_options = NULL; char *aot_options = NULL; char *forced_version = NULL; + GPtrArray *agents = NULL; + char *attach_options = NULL; #ifdef MONO_JIT_INFO_TABLE_TEST int test_jit_info_table = FALSE; #endif @@ -1168,7 +1284,9 @@ mono_main (int argc, char* argv[]) } else if (strcmp (argv [i], "--verbose") == 0 || strcmp (argv [i], "-v") == 0) { mini_verbose++; } else if (strcmp (argv [i], "--version") == 0 || strcmp (argv [i], "-V") == 0) { - g_print ("Mono JIT compiler version %s (%s)\nCopyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, FULL_VERSION); + char *build = mono_get_runtime_build_info (); + g_print ("Mono JIT compiler version %s (%s)\nCopyright (C) 2002-2009 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, build); + g_free (build); g_print (info); if (mini_verbose) { const char *cerror; @@ -1287,6 +1405,12 @@ mono_main (int argc, char* argv[]) } else if (strncmp (argv [i], "--profile=", 10) == 0) { enable_profile = TRUE; profile_options = argv [i] + 10; + } else if (strncmp (argv [i], "--agent=", 8) == 0) { + if (agents == NULL) + agents = g_ptr_array_new (); + g_ptr_array_add (agents, argv [i] + 8); + } else if (strncmp (argv [i], "--attach=", 9) == 0) { + attach_options = argv [i] + 9; } else if (strcmp (argv [i], "--compile") == 0) { if (i + 1 >= argc){ fprintf (stderr, "error: --compile option requires a method name argument\n"); @@ -1319,28 +1443,28 @@ mono_main (int argc, char* argv[]) enable_debugging = TRUE; if (!parse_debug_options (argv [i] + 8)) return 1; + } else if (strncmp (argv [i], "--debugger-agent=", 17) == 0) { + MonoDebugOptions *opt = mini_get_debug_options (); + + mono_debugger_agent_parse_options (argv [i] + 17); + opt->mdb_optimizations = TRUE; + enable_debugging = TRUE; } else if (strcmp (argv [i], "--security") == 0) { - /* fixme enable verifiable code when the verifier works with 2.0 - * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE); - */ + mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE); mono_security_set_mode (MONO_SECURITY_MODE_CAS); mono_activate_security_manager (); } else if (strncmp (argv [i], "--security=", 11) == 0) { if (strcmp (argv [i] + 11, "temporary-smcs-hack") == 0) { mono_security_set_mode (MONO_SECURITY_MODE_SMCS_HACK); } else if (strcmp (argv [i] + 11, "core-clr") == 0) { - /* fixme enable verifiable code when the verifier works with 2.0 - * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE); - */ + mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE); mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR); } else if (strcmp (argv [i] + 11, "core-clr-test") == 0) { /* fixme should we enable verifiable code here?*/ mono_security_set_mode (MONO_SECURITY_MODE_CORE_CLR); mono_security_core_clr_test = TRUE; } else if (strcmp (argv [i] + 11, "cas") == 0){ - /* fixme enable verifiable code when the verifier works with 2.0 - * mini_verifier_set_mode (MINI_VERIFIER_MODE_VERIFIABLE); - */ + mono_verifier_set_mode (MONO_VERIFIER_MODE_VERIFIABLE); mono_security_set_mode (MONO_SECURITY_MODE_CAS); mono_activate_security_manager (); } else if (strcmp (argv [i] + 11, "validil") == 0) { @@ -1352,7 +1476,9 @@ mono_main (int argc, char* argv[]) return 1; } } else if (strcmp (argv [i], "--desktop") == 0) { +#if defined (HAVE_BOEHM_GC) GC_dont_expand = 1; +#endif /* Put desktop-specific optimizations here */ } else if (strcmp (argv [i], "--server") == 0){ /* Put server-specific optimizations here */ @@ -1369,6 +1495,8 @@ mono_main (int argc, char* argv[]) fprintf (stderr, "Invalid --wapi suboption: '%s'\n", argv [i]); return 1; } + } else if (strcmp (argv [i], "--no-x86-stack-align") == 0) { + mono_do_x86_stack_align = FALSE; #ifdef MONO_JIT_INFO_TABLE_TEST } else if (strcmp (argv [i], "--test-jit-info-table") == 0) { test_jit_info_table = TRUE; @@ -1384,6 +1512,20 @@ mono_main (int argc, char* argv[]) return 1; } + if (getenv ("MONO_XDEBUG")) + enable_debugging = TRUE; + +#ifdef MONO_CROSS_COMPILE + if (!mono_compile_aot) { + fprintf (stderr, "This mono runtime is compiled for cross-compiling. Only the --aot option is supported."); + exit (1); + } +#if SIZEOF_VOID_P == 8 && defined(TARGET_ARM) + fprintf (stderr, "Can't cross-compile on 64 bit platforms to arm.\n"); + exit (1); +#endif +#endif + if ((action == DO_EXEC) && mono_debug_using_mono_debugger ()) action = DO_DEBUGGER; @@ -1391,11 +1533,10 @@ mono_main (int argc, char* argv[]) g_set_prgname (argv[i]); } - if (enable_profile) { - /* Needed because of TLS accesses in mono_profiler_load () */ - mono_gc_base_init (); + if (enable_profile) mono_profiler_load (profile_options); - } + + mono_attach_parse_options (attach_options); if (trace_options != NULL){ /* @@ -1407,12 +1548,18 @@ mono_main (int argc, char* argv[]) exit (1); } +#ifdef DISABLE_JIT + if (!mono_aot_only) { + fprintf (stderr, "This runtime has been configured with --enable-minimal=jit, so the --full-aot command line option is required.\n"); + exit (1); + } +#endif + if (action == DO_DEBUGGER) { enable_debugging = TRUE; #ifdef MONO_DEBUGGER_SUPPORTED mono_debug_init (MONO_DEBUG_FORMAT_DEBUGGER); - mono_debugger_init (); #else g_print ("The Mono Debugger is not supported on this platform.\n"); return 1; @@ -1420,9 +1567,31 @@ mono_main (int argc, char* argv[]) } else if (enable_debugging) mono_debug_init (MONO_DEBUG_FORMAT_MONO); +#ifdef MONO_DEBUGGER_SUPPORTED + if (enable_debugging) { + if ((opt & MONO_OPT_GSHARED) == 0) + mini_debugger_set_attach_ok (); + } +#endif + mono_set_defaults (mini_verbose, opt); mono_setup_vtable_in_class_init = FALSE; domain = mini_init (argv [i], forced_version); + + if (agents) { + int i; + + for (i = 0; i < agents->len; ++i) { + int res = load_agent (domain, (char*)g_ptr_array_index (agents, i)); + if (res) { + g_ptr_array_free (agents, TRUE); + mini_cleanup (domain); + return 1; + } + } + + g_ptr_array_free (agents, TRUE); + } switch (action) { case DO_REGRESSION: @@ -1519,6 +1688,28 @@ mono_main (int argc, char* argv[]) main_thread_handler (&main_args); mono_thread_manage (); #endif + + /* + * On unix, WaitForMultipleObjects for threads is implemented by waiting on + * a cond variable, which is set by the thread when it exits _mono code_, + * but it could still be running libc code. On amd64, the libc thread exit + * code does a stack unwind, and if it encounters a frame pointing to native + * code which is in memory which is no longer mapped (because the runtime has + * shut down), it will crash: + * http://mail-archives.apache.org/mod_mbox/harmony-dev/200801.mbox/%3C200801130327.41572.gshimansky@apache.org%3E + * Testcase: tests/main-exit-background-change.exe. + * To make this race less frequent, we avoid freeing the global code manager. + * Since mono_main () is hopefully only used by the runtime executable, this + * will only cause a shutdown leak. This workaround also has the advantage + * that it can be back-ported to 2.0 safely. + * FIXME: Fix this properly by waiting for threads to really exit using + * pthread_join (). This cannot be done currently as the io-layer calls + * pthread_detach (). + */ +#ifdef __x86_64__ + mono_dont_free_global_codeman = TRUE; +#endif + mini_cleanup (domain); /* Look up return value from System.Environment.ExitCode */ @@ -1539,7 +1730,7 @@ mono_main (int argc, char* argv[]) exit (1); } - mono_debugger_main (domain, assembly, argc - i, argv + i); + mini_debugger_main (domain, assembly, argc - i, argv + i); mini_cleanup (domain); return 0; #else @@ -1583,7 +1774,7 @@ mono_main (int argc, char* argv[]) if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) { MonoMethod *nm; - nm = mono_marshal_get_native_wrapper (method, TRUE); + nm = mono_marshal_get_native_wrapper (method, TRUE, FALSE); cfg = mini_method_compile (nm, opt, mono_get_root_domain (), FALSE, FALSE, part); } else @@ -1640,7 +1831,7 @@ mono_main (int argc, char* argv[]) for (i = 0; i < count; ++i) { if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) - method = mono_marshal_get_native_wrapper (method, TRUE); + method = mono_marshal_get_native_wrapper (method, TRUE, FALSE); cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, FALSE, 0); mono_destroy_compile (cfg); @@ -1692,6 +1883,12 @@ mono_jit_cleanup (MonoDomain *domain) mini_cleanup (domain); } +void +mono_jit_set_aot_only (gboolean val) +{ + mono_aot_only = val; +} + /** * mono_jit_set_trace_options: * @options: string representing the trace options @@ -1711,3 +1908,21 @@ mono_jit_set_trace_options (const char* options) return TRUE; } +/** + * mono_set_signal_chaining: + * + * Enable/disable signal chaining. This should be called before mono_jit_init (). + * If signal chaining is enabled, the runtime saves the original signal handlers before + * installing its own handlers, and calls the original ones in the following cases: + * - a SIGSEGV/SIGABRT signal received while executing native (i.e. not JITted) code. + * - SIGPROF + * - SIGFPE + * - SIGQUIT + * - SIGUSR2 + * Signal chaining only works on POSIX platforms. + */ +void +mono_set_signal_chaining (gboolean chain_signals) +{ + mono_do_signal_chaining = chain_signals; +}