#include <mono/metadata/coree.h>
#include <mono/metadata/attach.h>
#include "mono/utils/mono-counters.h"
-#include <mono/utils/gc_wrapper.h>
#include "mini.h"
#include "jit.h"
NULL
};
+#ifdef __native_client_codegen__
+extern gint8 nacl_align_byte;
+#endif
+#ifdef __native_client__
+extern char *nacl_mono_path;
+#endif
#define DEFAULT_OPTIMIZATIONS ( \
MONO_OPT_PEEPHOLE | \
MONO_OPT_SIMD | \
MONO_OPT_AOT)
-#define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP | MONO_OPT_UNSAFE)
+#define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP | MONO_OPT_UNSAFE | MONO_OPT_GSHAREDVT)
static guint32
parse_optimizations (const char* p)
int i, invert, len;
/* call out to cpu detection code here that sets the defaults ... */
- opt |= mono_arch_cpu_optimizazions (&exclude);
+ opt |= mono_arch_cpu_optimizations (&exclude);
opt &= ~exclude;
if (!p)
return opt;
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_CFOLD,
MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE,
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_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_TAILC,
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_SSA,
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_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_CMOV,
MonoDomain *domain = mono_domain_get ();
guint32 exclude = 0;
- mono_arch_cpu_optimizazions (&exclude);
+ mono_arch_cpu_optimizations (&exclude);
if (mini_stats_fd) {
fprintf (mini_stats_fd, "$stattitle = \'Mono Benchmark Results (various optimizations)\';\n");
MonoAssembly *ass;
int verbose;
guint32 opts;
+ guint32 recompilation_times;
} CompileAllThreadArgs;
static void
-compile_all_methods_thread_main (CompileAllThreadArgs *args)
+compile_all_methods_thread_main_inner (CompileAllThreadArgs *args)
{
MonoAssembly *ass = args->ass;
int verbose = args->verbose;
}
static void
-compile_all_methods (MonoAssembly *ass, int verbose, guint32 opts)
+compile_all_methods_thread_main (CompileAllThreadArgs *args)
+{
+ guint32 i;
+ for (i = 0; i < args->recompilation_times; ++i)
+ compile_all_methods_thread_main_inner (args);
+}
+
+static void
+compile_all_methods (MonoAssembly *ass, int verbose, guint32 opts, guint32 recompilation_times)
{
CompileAllThreadArgs args;
args.ass = ass;
args.verbose = verbose;
args.opts = opts;
+ args.recompilation_times = recompilation_times;
/*
* Need to create a mono thread since compilation might trigger
" --break METHOD Inserts a breakpoint at METHOD entry\n"
" --break-at-bb METHOD N Inserts a breakpoint in METHOD at BB N\n"
" --compile METHOD Just compile METHOD in assembly\n"
- " --compile-all Compiles all the methods in the assembly\n"
+ " --compile-all=N Compiles all the methods in the assembly multiple times (default: 1)\n"
" --ncompile N Number of times to compile METHOD (default: 1)\n"
" --print-vtable Print the vtable of all used classes\n"
" --regression Runs the regression test contained in the assembly\n"
" --stats Print statistics about the JIT operations\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"
+ " --verify-all Run the verifier on all assemblies and 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"
" --trace[=EXPR] Enable tracing, use --help-trace for details\n"
" --jitmap Output a jit method map to /tmp/perf-PID.map\n"
" --help-devel Shows more options available to developers\n"
+#ifdef __native_client_codegen__
+ " --nacl-align-mask-off Turn off Native Client 32-byte alignment mask (for debug only)\n"
+#endif
"\n"
"Runtime:\n"
" --config FILE Loads FILE as the Mono config\n"
" --attach=OPTIONS Pass OPTIONS to the attach agent in the runtime.\n"
" Currently the only supported option is 'disable'.\n"
" --llvm, --nollvm Controls whenever the runtime uses LLVM to compile code.\n"
+ " --gc=[sgen,boehm] Select SGen or Boehm GC (runs mono or mono-sgen)\n"
+#ifdef HOST_WIN32
+ " --mixed-mode Enable mixed-mode image support.\n"
+#endif
);
}
" none No assemblies\n"
" program Entry point assembly\n"
" assembly Specifies an assembly\n"
+ " wrapper All wrappers bridging native and managed code\n"
" M:Type:Method Specifies a method\n"
" N:Namespace Specifies a namespace\n"
" T:Type Specifies a type\n"
+ " E:Type Specifies stack traces for an exception type\n"
" EXPR Includes expression\n"
" -EXPR Excludes expression\n"
" EXPR,EXPR Multiple expressions\n"
#endif
#ifdef HAVE_EPOLL
"\tNotifications: epoll\n"
+#elif defined(HAVE_KQUEUE)
+ "\tNotification: kqueue\n"
#else
"\tNotification: Thread + polling\n"
#endif
#endif
"\n"
#ifdef MONO_ARCH_LLVM_SUPPORTED
- "\tLLVM: supported\n"
+#ifdef ENABLE_LLVM
+ "\tLLVM: yes(" LLVM_VERSION ")\n"
+#else
+ "\tLLVM: supported, not enabled.\n"
+#endif
#endif
"";
#ifdef HOST_WIN32
BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
{
- if (!GC_DllMain (module_handle, reason, reserved))
+ int dummy;
+ if (!mono_gc_dllmain (module_handle, reason, reserved))
return FALSE;
switch (reason)
if (coree_module_handle)
FreeLibrary (coree_module_handle);
break;
+ case DLL_THREAD_ATTACH:
+ mono_thread_info_attach (&dummy);
+ break;
+ case DLL_THREAD_DETACH:
+ mono_thread_info_dettach ();
+ break;
+
}
return TRUE;
}
mono_jit_parse_options (int argc, char * argv[])
{
int i;
+ char *trace_options = NULL;
+ int mini_verbose = 0;
/*
* Some options have no effect here, since they influence the behavior of
mono_debugger_agent_parse_options (argv [i] + 17);
opt->mdb_optimizations = TRUE;
enable_debugging = TRUE;
+ } else if (!strcmp (argv [i], "--soft-breakpoints")) {
+ MonoDebugOptions *opt = mini_get_debug_options ();
+
+ opt->soft_breakpoints = TRUE;
+ opt->explicit_null_checks = TRUE;
+ } else if (strncmp (argv [i], "--optimize=", 11) == 0) {
+ guint32 opt = parse_optimizations (argv [i] + 11);
+ mono_set_optimizations (opt);
+ } else if (strncmp (argv [i], "-O=", 3) == 0) {
+ guint32 opt = parse_optimizations (argv [i] + 3);
+ mono_set_optimizations (opt);
+ } else if (strcmp (argv [i], "--trace") == 0) {
+ trace_options = (char*)"";
+ } else if (strncmp (argv [i], "--trace=", 8) == 0) {
+ trace_options = &argv [i][8];
+ } else if (strcmp (argv [i], "--verbose") == 0 || strcmp (argv [i], "-v") == 0) {
+ mini_verbose++;
+ } else if (strcmp (argv [i], "--breakonex") == 0) {
+ MonoDebugOptions *opt = mini_get_debug_options ();
+
+ opt->break_on_exc = TRUE;
+ } else if (strcmp (argv [i], "--stats") == 0) {
+ mono_counters_enable (-1);
+ mono_stats.enabled = TRUE;
+ mono_jit_stats.enabled = TRUE;
+ } else if (strcmp (argv [i], "--break") == 0) {
+ if (i+1 >= argc){
+ fprintf (stderr, "Missing method name in --break command line option\n");
+ exit (1);
+ }
+
+ if (!mono_debugger_insert_breakpoint (argv [++i], FALSE))
+ fprintf (stderr, "Error: invalid method name '%s'\n", argv [i]);
+ } else if (strcmp (argv [i], "--llvm") == 0) {
+#ifndef MONO_ARCH_LLVM_SUPPORTED
+ fprintf (stderr, "Mono Warning: --llvm not supported on this platform.\n");
+#else
+ mono_use_llvm = TRUE;
+#endif
} else {
fprintf (stderr, "Unsupported command line option: '%s'\n", argv [i]);
exit (1);
}
}
+
+ if (trace_options != NULL) {
+ /*
+ * Need to call this before mini_init () so we can trace methods
+ * compiled there too.
+ */
+ mono_jit_trace_calls = mono_trace_parse_options (trace_options);
+ if (mono_jit_trace_calls == NULL)
+ exit (1);
+ }
+
+ if (mini_verbose)
+ mono_set_verbose_level (mini_verbose);
+}
+
+static void
+mono_set_use_smp (int use_smp)
+{
+#if HAVE_SCHED_SETAFFINITY
+ if (!use_smp) {
+ unsigned long proc_mask = 1;
+#ifdef GLIBC_BEFORE_2_3_4_SCHED_SETAFFINITY
+ sched_setaffinity (getpid(), (gpointer)&proc_mask);
+#else
+ sched_setaffinity (getpid(), sizeof (unsigned long), (gpointer)&proc_mask);
+#endif
+ }
+#endif
}
+
/**
* mono_main:
const char* aname, *mname = NULL;
char *config_file = NULL;
int i, count = 1;
- guint32 opt, action = DO_EXEC;
+ guint32 opt, action = DO_EXEC, recompilation_times = 1;
MonoGraphOptions mono_graph_options = 0;
int mini_verbose = 0;
gboolean enable_profile = FALSE;
#ifdef MONO_JIT_INFO_TABLE_TEST
int test_jit_info_table = FALSE;
#endif
-
- setlocale (LC_ALL, "");
-
-#if HAVE_SCHED_SETAFFINITY
- if (getenv ("MONO_NO_SMP")) {
- unsigned long proc_mask = 1;
-#ifdef GLIBC_BEFORE_2_3_4_SCHED_SETAFFINITY
- sched_setaffinity (getpid(), (gpointer)&proc_mask);
-#else
- sched_setaffinity (getpid(), sizeof (unsigned long), (gpointer)&proc_mask);
+#ifdef HOST_WIN32
+ int mixed_mode = FALSE;
#endif
- }
+#ifdef __native_client__
+ gboolean nacl_null_checks_off = FALSE;
#endif
- if (!g_thread_supported ())
- g_thread_init (NULL);
- if (mono_running_on_valgrind () && getenv ("MONO_VALGRIND_LEAK_CHECK")) {
- GMemVTable mem_vtable;
+#ifdef MOONLIGHT
+#ifndef HOST_WIN32
+ /* stdout defaults to block buffering if it's not writing to a terminal, which
+ * happens with our test harness: we redirect stdout to capture it. Force line
+ * buffering in all cases. */
+ setlinebuf (stdout);
+#endif
+#endif
- /*
- * Instruct glib to use the system allocation functions so valgrind
- * can track the memory allocated by the g_... functions.
- */
- memset (&mem_vtable, 0, sizeof (mem_vtable));
- mem_vtable.malloc = malloc;
- mem_vtable.realloc = realloc;
- mem_vtable.free = free;
- mem_vtable.calloc = calloc;
+ setlocale (LC_ALL, "");
- g_mem_set_vtable (&mem_vtable);
- }
+ if (getenv ("MONO_NO_SMP"))
+ mono_set_use_smp (FALSE);
+
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
char *build = mono_get_runtime_build_info ();
char *gc_descr;
- g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com\n", build);
+ g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com\n", build);
g_free (build);
g_print (info);
gc_descr = mono_gc_get_description ();
opt = parse_optimizations (argv [i] + 11);
} else if (strncmp (argv [i], "-O=", 3) == 0) {
opt = parse_optimizations (argv [i] + 3);
+ } else if (strcmp (argv [i], "--gc=sgen") == 0) {
+ if (!strcmp (mono_gc_get_gc_name (), "boehm")) {
+ GString *path = g_string_new (argv [0]);
+ g_string_append (path, "-sgen");
+ argv [0] = path->str;
+#ifdef HAVE_EXECVP
+ execvp (path->str, argv);
+#else
+ fprintf (stderr, "Error: --gc=<NAME> option not supported on this platform.\n");
+#endif
+ }
+ } else if (strcmp (argv [i], "--gc=boehm") == 0) {
+ if (!strcmp (mono_gc_get_gc_name (), "sgen")) {
+ char *copy = g_strdup (argv [0]);
+ char *p = strstr (copy, "-sgen");
+ if (p == NULL){
+ fprintf (stderr, "Error, this process is not named mono-sgen and the command line option --boehm was passed");
+ exit (1);
+ }
+ *p = 0;
+ argv [0] = p;
+#ifdef HAVE_EXECVP
+ execvp (p, argv);
+#else
+ fprintf (stderr, "Error: --gc=<NAME> option not supported on this platform.\n");
+#endif
+ }
} else if (strcmp (argv [i], "--config") == 0) {
if (i +1 >= argc){
fprintf (stderr, "error: --config requires a filename argument\n");
return 1;
}
config_file = argv [++i];
+#ifdef HOST_WIN32
+ } else if (strcmp (argv [i], "--mixed-mode") == 0) {
+ mixed_mode = TRUE;
+#endif
} else if (strcmp (argv [i], "--ncompile") == 0) {
if (i + 1 >= argc){
fprintf (stderr, "error: --ncompile requires an argument\n");
} else if (strncmp (argv [i], "--trace=", 8) == 0) {
trace_options = &argv [i][8];
} else if (strcmp (argv [i], "--breakonex") == 0) {
- mono_break_on_exc = TRUE;
+ MonoDebugOptions *opt = mini_get_debug_options ();
+
+ opt->break_on_exc = TRUE;
} else if (strcmp (argv [i], "--break") == 0) {
if (i+1 >= argc){
fprintf (stderr, "Missing method name in --break command line option\n");
mono_compile_aot = TRUE;
aot_options = &argv [i][6];
#endif
+ } else if (strncmp (argv [i], "--compile-all=", 14) == 0) {
+ action = DO_COMPILE;
+ recompilation_times = atoi (argv [i] + 14);
} else if (strcmp (argv [i], "--compile-all") == 0) {
action = DO_COMPILE;
} else if (strncmp (argv [i], "--runtime=", 10) == 0) {
#endif
} else if (strcmp (argv [i], "--nollvm") == 0){
mono_use_llvm = FALSE;
+#ifdef __native_client_codegen__
+ } else if (strcmp (argv [i], "--nacl-align-mask-off") == 0){
+ nacl_align_byte = -1; /* 0xff */
+#endif
+#ifdef __native_client__
+ } else if (strcmp (argv [i], "--nacl-mono-path") == 0){
+ nacl_mono_path = g_strdup(argv[++i]);
+ } else if (strcmp (argv [i], "--nacl-null-checks-off") == 0){
+ nacl_null_checks_off = TRUE;
+#endif
} else {
fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
return 1;
}
}
+#ifdef __native_client_codegen__
+ if (getenv ("MONO_NACL_ALIGN_MASK_OFF"))
+ {
+ nacl_align_byte = -1; /* 0xff */
+ }
+ if (!nacl_null_checks_off) {
+ MonoDebugOptions *opt = mini_get_debug_options ();
+ opt->explicit_null_checks = TRUE;
+ }
+#endif
+
if (!argv [i]) {
mini_usage ();
return 1;
}
#endif
- /*
- * This must be called before mono_debug_init(), because the
- * latter registers GC roots.
- */
- mono_gc_base_init ();
-
if (action == DO_DEBUGGER) {
enable_debugging = TRUE;
}
#endif
+#ifdef HOST_WIN32
+ if (mixed_mode)
+ mono_load_coree (argv [i]);
+#endif
+
mono_set_defaults (mini_verbose, opt);
domain = mini_init (argv [i], forced_version);
+ mono_gc_set_stack_end (&domain);
+
if (agents) {
int i;
* This used to be an amd64 only crash, but it looks like now most glibc targets do unwinding
* that requires reading the target code.
*/
-#ifdef __linux__
+#if defined( __linux__ ) || defined( __native_client__ )
mono_dont_free_global_codeman = TRUE;
#endif
i = mono_environment_exitcode_get ();
return i;
} else if (action == DO_COMPILE) {
- compile_all_methods (assembly, mini_verbose, opt);
+ compile_all_methods (assembly, mini_verbose, opt, recompilation_times);
mini_cleanup (domain);
return 0;
} else if (action == DO_DEBUGGER) {