{"tailc", "Tail recursion and tail calls"},
{"loop", "Loop related optimizations"},
{"fcmov", "Fast x86 FP compares"},
- {"leaf", "Leaf procedures optimizations"}
+ {"leaf", "Leaf procedures optimizations"},
+ {"aot", "Usage of Ahead Of Time compiled code"},
+ {"precomp", "Precompile all methods before executing Main"}
};
#define DEFAULT_OPTIMIZATIONS ( \
MONO_OPT_CFOLD | \
MONO_OPT_BRANCH | \
MONO_OPT_LINEARS | \
- MONO_OPT_INTRINS)
+ MONO_OPT_INTRINS | \
+ MONO_OPT_AOT)
static guint32
parse_optimizations (const char* p)
if (invert)
opt = 0;
else
- opt = ~(MONO_OPT_SHARED | exclude);
+ opt = ~(MONO_OPT_SHARED | MONO_OPT_PRECOMP | exclude);
p += 3;
if (*p == ',')
p++;
*total_run = 0;
for (opt = 0; opt < G_N_ELEMENTS (opt_sets); ++opt) {
double elapsed, comp_time, start_time;
+ MonoJitInfo *jinfo;
+
opt_flags = opt_sets [opt];
mono_set_defaults (verbose, opt_flags);
n = opt_descr (opt_flags);
if (verbose >= 2)
g_print ("Running '%s' ...\n", method->name);
#ifdef MONO_USE_AOT_COMPILER
- if (!(func = mono_aot_get_method (mono_root_domain, method)))
+ if ((jinfo = mono_aot_get_method (mono_root_domain, method)))
+ func = jinfo->code_start;
+ else
#endif
func = (TestMethod)cfg->native_code;
result = func ();
DO_DRAW,
};
+typedef struct CompileAllThreadArgs {
+ MonoAssembly *ass;
+ int verbose;
+} CompileAllThreadArgs;
+
static void
-compile_all_methods (MonoAssembly *ass, int verbose)
+compile_all_methods_thread_main (CompileAllThreadArgs *args)
{
+ MonoAssembly *ass = args->ass;
+ int verbose = args->verbose;
MonoImage *image = ass->image;
MonoMethod *method;
int i, count = 0;
count++;
if (verbose) {
char * desc = mono_method_full_name (method, TRUE);
- g_print ("Compiling %d %s\n", count, desc + 3);
+ g_print ("Compiling %d %s\n", count, desc);
g_free (desc);
}
mono_compile_method (method);
}
+static void
+compile_all_methods (MonoAssembly *ass, int verbose)
+{
+ CompileAllThreadArgs args;
+
+ args.ass = ass;
+ args.verbose = verbose;
+
+ /*
+ * Need to create a mono thread since compilation might trigger
+ * running of managed code.
+ */
+ mono_thread_create (mono_domain_get (), compile_all_methods_thread_main, &args);
+
+ mono_thread_manage ();
+}
+
/**
* mono_jit_exec:
* @assembly: reference to an assembly
{
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);
int res = mono_compile_assembly (assembly, main_args->opts);
printf ("AOT RESULT %d\n", res);
} else {
+ /*
+ * This must be done in a thread managed by mono since it can invoke
+ * managed code.
+ */
+ if (main_args->opts & MONO_OPT_PRECOMP)
+ mono_precompile_assemblies ();
+
mono_jit_exec (main_args->domain, assembly, main_args->argc, main_args->argv);
}
}
" --ncompile N Number of times to compile METHOD (default: 1)\n"
" --regression Runs the regression test contained in the assembly\n"
" --print-vtable Print the vtable of all used classes\n"
- " --trace Enable tracing\n"
+ " --trace[=EXPR] Enable tracing, use --help-trace for details\n"
" --compile-all Compiles all the methods in the assembly\n"
" --breakonex Inserts a breakpoint on exceptions\n"
" --break METHOD Inserts a breakpoint at METHOD entry\n"
" --debug Enable debugging support\n"
" --stats Print statistics about the JIT operations\n"
- " --no-aot Disable loading of AOT code\n"
"\n"
"Development:\n"
" --statfile FILE Sets the stat file to FILE\n"
fprintf (stderr, " %-10s %s\n", opt_names [i].name, opt_names [i].desc);
}
+static void
+mini_trace_usage (void)
+{
+ fprintf (stderr,
+ "Tracing options:\n"
+ " --trace[=EXPR] Trace every call, optional EXPR controls the scope\n"
+ "\n"
+ "EXPR is composed of:\n"
+ " all All assemblies\n"
+ " none No assemblies\n"
+ " program Entry point assembly\n"
+ " assembly Specifies an assembly\n"
+ " M:Type:Method Specifies a method\n"
+ " N:Namespace Specifies a namespace\n"
+ " T:Type Specifies a type\n"
+ " +EXPR Includes expression\n"
+ " -EXPR Excludes expression\n");
+}
+
int
-mono_main (int argc, char* argv[]) {
+mono_main (int argc, char* argv[])
+{
MainThreadArgs main_args;
MonoAssembly *assembly;
MonoMethodDesc *desc;
guint32 opt, action = DO_EXEC;
MonoGraphOptions mono_graph_options = 0;
int mini_verbose = 0;
+ char *trace_options = NULL;
setlocale (LC_ALL, "");
g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
} else if (strcmp (argv [i], "--help") == 0 || strcmp (argv [i], "-h") == 0) {
mini_usage ();
return 0;
+ } else if (strcmp (argv [i], "--help-trace") == 0){
+ mini_trace_usage ();
+ return 0;
} else if (strncmp (argv [i], "--statfile", 10) == 0) {
mini_stats_fd = fopen (argv [++i], "w+");
} else if (strncmp (argv [i], "--optimize=", 11) == 0) {
count = atoi (argv [++i]);
action = DO_BENCH;
} else if (strcmp (argv [i], "--trace") == 0) {
- mono_jit_trace_calls = TRUE;
+ trace_options = "";
+ } 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;
} else if (strcmp (argv [i], "--break") == 0) {
mono_print_vtable = TRUE;
} else if (strcmp (argv [i], "--stats") == 0) {
mono_jit_stats.enabled = TRUE;
- } else if (strcmp (argv [i], "--no-aot") == 0) {
- mono_no_aot = TRUE;
} else if (strcmp (argv [i], "--aot") == 0) {
mono_compile_aot = TRUE;
} else if (strcmp (argv [i], "--compile-all") == 0) {
mono_set_defaults (mini_verbose, opt);
domain = mini_init (argv [i]);
-
+
switch (action) {
case DO_REGRESSION:
if (mini_regression_list (mini_verbose, argc -i, argv + i)) {
return 2;
}
+ if (trace_options != NULL){
+ mono_jit_trace_calls = mono_trace_parse_options (assembly, trace_options);
+ if (mono_jit_trace_calls == NULL)
+ exit (1);
+ }
+
if (enable_debugging)
mono_debug_init_2 (assembly);
fprintf (mini_stats_fd, ");\n");
} else {
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);
+
cfg = mini_method_compile (method, opt, mono_root_domain, 0);
mono_destroy_compile (cfg);
}