X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdriver.c;h=d6af531824f8a9d50f60633270855d346b57a14b;hb=311dcbd59f854031a0c719bbc12056431e7108e0;hp=d5da57d8e94429722f55f08df899a9be56370425;hpb=8bd5b55ee10b71444f53292417c45d2243ae54a6;p=mono.git diff --git a/mono/mini/driver.c b/mono/mini/driver.c index d5da57d8e94..d6af531824f 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -5,7 +5,8 @@ * Paolo Molaro (lupus@ximian.com) * Dietmar Maurer (dietmar@ximian.com) * - * (C) 2002 Ximian, Inc. + * (C) 2002-2003 Ximian, Inc. + * (C) 2003-2004 Novell, Inc. */ #include @@ -33,12 +34,16 @@ #include #include #include +#include +#include +#include #include "mini.h" +#include "jit.h" #include #include #include "inssel.h" -#include "debug.h" +#include static FILE *mini_stats_fd = NULL; @@ -66,22 +71,37 @@ opt_names [] = { {"cmov", "Conditional moves"}, {"shared", "Emit per-domain code"}, {"sched", "Instruction scheduling"}, - {"instrins", "Intrinsic method implementations"}, + {"intrins", "Intrinsic method implementations"}, {"tailc", "Tail recursion and tail calls"}, {"loop", "Loop related optimizations"}, - {"fcmov", "Fast x86 FP compares"} + {"fcmov", "Fast x86 FP compares"}, + {"leaf", "Leaf procedures optimizations"}, + {"aot", "Usage of Ahead Of Time compiled code"}, + {"precomp", "Precompile all methods before executing Main"}, + {"abcrem", "Array bound checks removal"} }; +#define DEFAULT_OPTIMIZATIONS ( \ + MONO_OPT_PEEPHOLE | \ + MONO_OPT_CFOLD | \ + MONO_OPT_BRANCH | \ + MONO_OPT_LINEARS | \ + MONO_OPT_INTRINS | \ + MONO_OPT_AOT) + + static guint32 parse_optimizations (const char* p) { /* the default value */ - guint32 opt = MONO_OPT_PEEPHOLE | MONO_OPT_CFOLD /* | MONO_OPT_CONSPROP | MONO_OPT_INLINE*/ | MONO_OPT_BRANCH | /* | MONO_OPT_SAHRED |*/ MONO_OPT_LINEARS; + guint32 opt = DEFAULT_OPTIMIZATIONS; + guint32 exclude = 0; const char *n; int i, invert, len; /* call out to cpu detection code here that sets the defaults ... */ - opt |= mono_arch_cpu_optimizazions (); + opt |= mono_arch_cpu_optimizazions (&exclude); + opt &= ~exclude; if (!p) return opt; @@ -120,7 +140,7 @@ parse_optimizations (const char* p) if (invert) opt = 0; else - opt = ~(MONO_OPT_SAHRED); + opt = ~(MONO_OPT_SHARED | MONO_OPT_PRECOMP | MONO_OPT_ABCREM | exclude); p += 3; if (*p == ',') p++; @@ -166,7 +186,7 @@ mono_parse_graph_options (const char* p) } int -mini_parse_default_optimizations (const char* p) +mono_parse_default_optimizations (const char* p) { guint32 opt; @@ -198,12 +218,13 @@ opt_sets [] = { MONO_OPT_BRANCH, MONO_OPT_CFOLD, MONO_OPT_FCMOV, - MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE, + 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, 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_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_ABCREM }; typedef int (*TestMethod) (void); @@ -217,7 +238,7 @@ domain_dump_native_code (MonoDomain *domain) { #endif static int -mini_regression (MonoImage *image, int verbose) { +mini_regression (MonoImage *image, int verbose, int *total_run) { guint32 i, opt, opt_flags; MonoMethod *method; MonoCompile *cfg; @@ -248,7 +269,7 @@ mini_regression (MonoImage *image, int verbose) { } /* load the metadata */ - for (i = 0; i < image->tables [MONO_TABLE_METHOD].rows; ++i) { + 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); mono_class_init (method->klass); @@ -261,18 +282,21 @@ mini_regression (MonoImage *image, int verbose) { total = 0; + *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]; - mini_set_defaults (verbose, opt_flags); + mono_set_defaults (verbose, opt_flags); n = opt_descr (opt_flags); - g_print ("Test run: image=%s, opts=%s\n", image->name, n); + g_print ("Test run: image=%s, opts=%s\n", mono_image_get_filename (image), n); g_free (n); cfailed = failed = run = code_size = 0; comp_time = elapsed = 0.0; /* fixme: ugly hack - delete all previously compiled methods */ - for (i = 0; i < image->tables [MONO_TABLE_METHOD].rows; ++i) { + 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->info = NULL; } @@ -280,20 +304,22 @@ mini_regression (MonoImage *image, int verbose) { g_timer_start (timer); if (mini_stats_fd) fprintf (mini_stats_fd, "["); - for (i = 0; i < image->tables [MONO_TABLE_METHOD].rows; ++i) { + 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); if (strncmp (method->name, "test_", 5) == 0) { expected = atoi (method->name + 5); run++; start_time = g_timer_elapsed (timer, NULL); comp_time -= start_time; - cfg = mini_method_compile (method, opt_flags, mono_root_domain, 0); + cfg = mini_method_compile (method, opt_flags, mono_get_root_domain (), TRUE, 0); comp_time += g_timer_elapsed (timer, NULL); if (cfg) { if (verbose >= 2) g_print ("Running '%s' ...\n", method->name); #ifdef MONO_USE_AOT_COMPILER - if (!(func = mono_aot_get_method (method))) + if ((jinfo = mono_aot_get_method (mono_get_root_domain (), method))) + func = jinfo->code_start; + else #endif func = (TestMethod)cfg->native_code; result = func (); @@ -305,19 +331,6 @@ mini_regression (MonoImage *image, int verbose) { code_size += cfg->code_len; mono_destroy_compile (cfg); - if (mono_trace_coverage) { - MonoCoverageInfo *cov = mono_get_coverage_info (method); - - if (cov) { - int k; - printf ("COVERAGE INFO %s\n", mono_method_full_name (method, TRUE)); - - for (k = 0; k < cov->entries; k++) { - printf (" BBLOCK %3d %d\n", cov->data [k].iloffset, cov->data [k].count); - } - } - } - } else { cfailed++; if (verbose) @@ -337,6 +350,7 @@ mini_regression (MonoImage *image, int verbose) { g_print ("Elapsed time: %f secs (%f, %f), Code size: %d\n\n", elapsed, elapsed - comp_time, comp_time, code_size); total += failed + cfailed; + *total_run += run; } if (mini_stats_fd) { @@ -351,19 +365,22 @@ mini_regression (MonoImage *image, int verbose) { static int mini_regression_list (int verbose, int count, char *images []) { - int i, total; + int i, total, total_run, run; MonoAssembly *ass; - total = 0; + total_run = total = 0; for (i = 0; i < count; ++i) { ass = mono_assembly_open (images [i], NULL); if (!ass) { g_warning ("failed to load assembly: %s", images [i]); continue; } - total += mini_regression (ass->image, verbose); + total += mini_regression (mono_assembly_get_image (ass), verbose, &run); + total_run += run; mono_assembly_close (ass); } + g_print ("Overall results: tests: %d, failed: %d, opt combinations: %d (pass: %.2f%%)\n", + total_run, total, G_N_ELEMENTS (opt_sets), 100.0*(total_run-total)/total_run); return total; } @@ -372,17 +389,24 @@ enum { DO_REGRESSION, DO_COMPILE, DO_EXEC, - DO_DRAW, + 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) { - MonoImage *image = ass->image; + MonoAssembly *ass = args->ass; + int verbose = args->verbose; + MonoImage *image = mono_assembly_get_image (ass); MonoMethod *method; int i, count = 0; - for (i = 0; i < image->tables [MONO_TABLE_METHOD].rows; ++i) { + 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); if (method->flags & METHOD_ATTRIBUTE_ABSTRACT) continue; @@ -392,7 +416,7 @@ compile_all_methods (MonoAssembly *ass, int verbose) 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); @@ -400,6 +424,23 @@ compile_all_methods (MonoAssembly *ass, int verbose) } +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 @@ -408,15 +449,15 @@ compile_all_methods (MonoAssembly *ass, int verbose) * * Start execution of a program. */ -static int +int mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]) { - MonoImage *image = assembly->image; + MonoImage *image = mono_assembly_get_image (assembly); MonoMethod *method; guint32 entry = mono_image_get_entry_point (image); if (!entry) { - g_print ("Assembly '%s' doesn't have an entry point.\n", image->name); + g_print ("Assembly '%s' doesn't have an entry point.\n", mono_image_get_filename (image)); /* FIXME: remove this silly requirement. */ mono_environment_exitcode_set (1); return 1; @@ -440,7 +481,7 @@ 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); @@ -451,6 +492,13 @@ static void main_thread_handler (gpointer user_data) 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); } } @@ -460,43 +508,96 @@ mini_usage (void) { int i; - fprintf (stderr, - "Usage is: mini [options] assembly\n\n" + fprintf (stdout, + "Usage is: mono [options] assembly\n\n" "Runtime and JIT debugging:\n" " --compile METHOD Just compile METHOD in assembly\n" " --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" "\n" "Development:\n" " --statfile FILE Sets the stat file to FILE\n" " --aot Compiles the assembly to native code\n" - " --coverage Performs coverage analysis\n" - " --profile Runs in profiling mode\n" + " --profile[=profiler] Runs in profiling mode with the specified profiler module\n" " --graph[=TYPE] METHOD Draws a graph of the specified method:\n"); for (i = 0; i < G_N_ELEMENTS (graph_names); ++i) { - fprintf (stderr, " %-10s %s\n", graph_names [i].name, graph_names [i].desc); + fprintf (stdout, " %-10s %s\n", graph_names [i].name, graph_names [i].desc); } - fprintf (stderr, + fprintf (stdout, "\n" "Runtime:\n" " --config FILE Loads FILE as the Mono config\n" " --verbose, -v Increases the verbosity level\n" " --help, -h Show usage information\n" + " --version, -V Show version information\n" " --optimize=OPT Turns on a specific optimization:\n"); for (i = 0; i < G_N_ELEMENTS (opt_names); ++i) - fprintf (stderr, " %-10s %s\n", opt_names [i].name, opt_names [i].desc); + fprintf (stdout, " %-10s %s\n", opt_names [i].name, opt_names [i].desc); +} + +static void +mini_trace_usage (void) +{ + fprintf (stdout, + "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"); } +static const char *info = "" +#ifdef HAVE_KW_THREAD + "\tTLS: __thread\n" +#else + "\tTLS: normal\n" +#endif /* HAVE_KW_THREAD */ +#ifdef HAVE_BOEHM_GC +#ifdef USE_INCLUDED_LIBGC + "\tGC: Included Boehm (with typed GC)\n" +#else +#if HAVE_GC_GCJ_MALLOC + "\tGC: System Boehm (with typed GC)\n" +#else + "\tGC: System Boehm (no typed GC available)\n" +#endif +#endif +#else + "\tGC: none\n" +#endif /* HAVE_BOEHM_GC */ +#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK + "\tSIGSEGV : altstack\n" +#else + "\tSIGSEGV : normal\n" +#endif +#ifdef HAVE_ICU + "\tGlobalization: ICU\n" +#else + "\tGlobalization: none\n" +#endif /* HAVE_ICU */ + ""; + int -mini_main (int argc, char* argv[]) { +mono_main (int argc, char* argv[]) +{ MainThreadArgs main_args; MonoAssembly *assembly; MonoMethodDesc *desc; @@ -506,10 +607,16 @@ mini_main (int argc, char* argv[]) { const char* aname, *mname = NULL; char *config_file = NULL; int i, count = 1; + int enable_debugging = FALSE; 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); + g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR); + opt = parse_optimizations (NULL); for (i = 1; i < argc; ++i) { @@ -519,9 +626,29 @@ mini_main (int argc, char* argv[]) { action = DO_REGRESSION; } 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, (C) 2002-2004 Novell, Inc and Contributors. www.go-mono.com\n", VERSION); + g_print (info); + if (mini_verbose) { + const guchar *cerror; + const guchar *clibpath; + mono_init ("mono"); + cerror = mono_check_corlib_version (); + clibpath = mono_defaults.corlib? mono_image_get_filename (mono_defaults.corlib): "unknown"; + if (cerror) { + g_print ("The currently installed mscorlib doesn't match this runtime version.\n"); + g_print ("The error is: %s\n", cerror); + g_print ("mscorlib.dll loaded at: %s\n", clibpath); + return 1; + } + } + return 0; } 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) { @@ -534,11 +661,13 @@ mini_main (int argc, char* argv[]) { 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) { - if (!mono_insert_breakpoint (argv [++i], FALSE)) + if (!mono_debugger_insert_breakpoint (argv [++i], FALSE)) g_error ("Invalid method name '%s'", argv [i]); } else if (strcmp (argv [i], "--print-vtable") == 0) { mono_print_vtable = TRUE; @@ -546,13 +675,12 @@ mini_main (int argc, char* argv[]) { mono_jit_stats.enabled = TRUE; } else if (strcmp (argv [i], "--aot") == 0) { mono_compile_aot = TRUE; - } else if (strcmp (argv [i], "--coverage") == 0) { - mono_trace_coverage = TRUE; } else if (strcmp (argv [i], "--compile-all") == 0) { action = DO_COMPILE; } else if (strcmp (argv [i], "--profile") == 0) { - mono_jit_profile = TRUE; - mono_profiler_install_simple (); + mono_profiler_load (NULL); + } else if (strncmp (argv [i], "--profile=", 10) == 0) { + mono_profiler_load (argv [i] + 10); } else if (strcmp (argv [i], "--compile") == 0) { mname = argv [++i]; action = DO_BENCH; @@ -564,15 +692,26 @@ mini_main (int argc, char* argv[]) { mname = argv [++i]; mono_graph_options = MONO_GRAPH_CFG; action = DO_DRAW; + } else if (strcmp (argv [i], "--debug") == 0) { + enable_debugging = TRUE; } else { - fprintf (stderr, "Unknown command line option: %s\n", argv [i]); + fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]); return 1; } } - mini_set_defaults (mini_verbose, opt); - domain = mini_init (argv [0]); + if (!argv [i]) { + mini_usage (); + return 1; + } + + if (mono_compile_aot || action == DO_EXEC) { + g_set_prgname (argv[i]); + } + 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)) { @@ -592,7 +731,7 @@ mini_main (int argc, char* argv[]) { break; case DO_COMPILE: if (argc - i != 1) { - fprintf (stderr, "Missing assembly name in --compile-all"); + mini_usage (); mini_cleanup (domain); return 1; } @@ -600,7 +739,7 @@ mini_main (int argc, char* argv[]) { break; case DO_DRAW: if (argc - i != 1 || mname == NULL) { - fprintf (stderr, "Usage: mini --graph[=TYPE] method assembly\n"); + mini_usage (); mini_cleanup (domain); return 1; } @@ -616,6 +755,14 @@ mini_main (int argc, char* argv[]) { break; } + if (enable_debugging) + mono_debug_init (domain, MONO_DEBUG_FORMAT_MONO); + + /* Parse gac loading options before loading assemblies. */ + if (mono_compile_aot || action == DO_EXEC) { + mono_config_parse (config_file); + } + assembly = mono_assembly_open (aname, NULL); if (!assembly) { fprintf (stderr, "cannot open assembly %s\n", aname); @@ -623,11 +770,27 @@ mini_main (int argc, char* argv[]) { 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); + if (mono_compile_aot || action == DO_EXEC) { - g_set_prgname (aname); - mono_config_parse (config_file); + const guchar *error; + //mono_set_rootdir (); + error = mono_check_corlib_version (); + if (error) { + fprintf (stderr, "Corlib not in sync with this runtime: %s\n", error); + fprintf (stderr, "Download a newer corlib or a newer runtime at http://www.go-mono.com/daily.\n"); + exit (1); + } + main_args.domain = domain; main_args.file = aname; main_args.argc = argc - i; @@ -636,6 +799,7 @@ mini_main (int argc, char* argv[]) { mono_runtime_exec_managed_code (domain, main_thread_handler, &main_args); mini_cleanup (domain); + /* Look up return value from System.Environment.ExitCode */ i = mono_environment_exitcode_get (); return i; @@ -650,7 +814,7 @@ mini_main (int argc, char* argv[]) { mini_cleanup (domain); return 3; } - method = mono_method_desc_search_in_image (desc, assembly->image); + method = mono_method_desc_search_in_image (desc, mono_assembly_get_image (assembly)); if (!method) { g_print ("Cannot find method %s\n", mname); mini_cleanup (domain); @@ -678,7 +842,7 @@ mini_main (int argc, char* argv[]) { break; } - cfg = mini_method_compile (method, opt, mono_root_domain, part); + cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, part); if ((mono_graph_options & MONO_GRAPH_CFG_SSA) && !(cfg->comp_done & MONO_COMP_SSA)) { g_warning ("no SSA info available (use -O=deadce)"); return 1; @@ -710,7 +874,7 @@ mini_main (int argc, char* argv[]) { opt = opt_sets [i]; g_timer_start (timer); for (j = 0; j < count; ++j) { - cfg = mini_method_compile (method, opt, mono_root_domain, 0); + cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, 0); mono_destroy_compile (cfg); } g_timer_stop (timer); @@ -729,12 +893,16 @@ mini_main (int argc, char* argv[]) { fprintf (mini_stats_fd, ");\n"); } else { for (i = 0; i < count; ++i) { - cfg = mini_method_compile (method, opt, mono_root_domain, 0); + 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_get_root_domain (), FALSE, 0); mono_destroy_compile (cfg); } } } else { - cfg = mini_method_compile (method, opt, mono_root_domain, 0); + cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, 0); mono_destroy_compile (cfg); } @@ -742,3 +910,16 @@ mini_main (int argc, char* argv[]) { return 0; } +MonoDomain * +mono_jit_init (const char *file) +{ + return mini_init (file); +} + +void +mono_jit_cleanup (MonoDomain *domain) +{ + mini_cleanup (domain); +} + +