more c*****y windows issues.
[mono.git] / mono / mini / driver.c
index e07095aac46627805d94ee5ba3bba85c2a555833..34b7d4ea398d51a6b535ec443e77377f15db82f3 100644 (file)
@@ -37,6 +37,7 @@
 #include <mono/metadata/verify.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-debug-debugger.h>
+#include <mono/metadata/security-manager.h>
 #include <mono/os/gc_wrapper.h>
 
 #include "mini.h"
@@ -79,7 +80,8 @@ opt_names [] = {
        {"leaf",     "Leaf procedures optimizations"},
        {"aot",      "Usage of Ahead Of Time compiled code"},
        {"precomp",  "Precompile all methods before executing Main"},
-       {"abcrem",   "Array bound checks removal"}
+       {"abcrem",   "Array bound checks removal"},     
+       {"ssapre",   "SSA based Partial Redundancy Elimination"}
 };
 
 #define DEFAULT_OPTIMIZATIONS (        \
@@ -89,7 +91,7 @@ opt_names [] = {
        MONO_OPT_LINEARS |      \
        MONO_OPT_INTRINS |  \
        MONO_OPT_LOOP |  \
-    MONO_OPT_AOT)
+       MONO_OPT_AOT)
 
 #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP)
 
@@ -228,6 +230,7 @@ opt_sets [] = {
        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_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_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
 };
 
@@ -300,10 +303,8 @@ mini_regression (MonoImage *image, int verbose, int *total_run) {
                comp_time = elapsed = 0.0;
 
                /* fixme: ugly hack - delete all previously compiled methods */
-               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;
-               }
+               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);
 
                g_timer_start (timer);
                if (mini_stats_fd)
@@ -315,7 +316,7 @@ mini_regression (MonoImage *image, int verbose, int *total_run) {
                                run++;
                                start_time = g_timer_elapsed (timer, NULL);
                                comp_time -= start_time; 
-                               cfg = mini_method_compile (method, opt_flags, mono_get_root_domain (), TRUE, 0);
+                               cfg = mini_method_compile (method, opt_flags, mono_get_root_domain (), TRUE, FALSE, 0);
                                comp_time += g_timer_elapsed (timer, NULL);
                                if (cfg) {
                                        if (verbose >= 2)
@@ -407,13 +408,27 @@ compile_all_methods_thread_main (CompileAllThreadArgs *args)
        int verbose = args->verbose;
        MonoImage *image = mono_assembly_get_image (ass);
        MonoMethod *method;
+       MonoCompile *cfg;
        int i, count = 0;
 
        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)
+               guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
+               MonoMethodSignature *sig;
+
+               if (mono_metadata_has_generic_params (image, token))
+                       continue;
+
+               method = mono_get_method (image, token, NULL);
+               if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
+                   (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
+                   (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
+                   (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
                        continue;
-               if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
+
+               if (method->klass->generic_container)
+                       continue;
+               sig = mono_method_signature (method);
+               if (sig->has_type_parameters)
                        continue;
 
                count++;
@@ -422,7 +437,8 @@ compile_all_methods_thread_main (CompileAllThreadArgs *args)
                        g_print ("Compiling %d %s\n", count, desc);
                        g_free (desc);
                }
-               mono_compile_method (method);
+               cfg = mini_method_compile (method, DEFAULT_OPTIMIZATIONS, mono_get_root_domain (), FALSE, FALSE, 0);
+               mono_destroy_compile (cfg);
        }
 
 }
@@ -508,45 +524,60 @@ static void main_thread_handler (gpointer user_data)
 }
 
 static void
-mini_usage (void)
+mini_usage_jitdeveloper (void)
 {
        int i;
-
+       
        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[=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"
-               "    --profile[=profiler]   Runs in profiling mode with the specified profiler module\n"
-               "    --graph[=TYPE] METHOD  Draws a graph of the specified method:\n");
+                "Runtime and JIT debugging options:\n"
+                "    --breakonex            Inserts a breakpoint on exceptions\n"
+                "    --break METHOD         Inserts a breakpoint at METHOD entry\n"
+                "    --compile METHOD       Just compile METHOD in assembly\n"
+                "    --compile-all          Compiles all the methods in the assembly\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"
+                "    --statfile FILE        Sets the stat file to FILE\n"
+                "    --stats                Print statistics about the JIT operations\n"
+                "\n"
+                "Other options:\n" 
+                "    --graph[=TYPE] METHOD  Draws a graph of the specified method:\n");
        
        for (i = 0; i < G_N_ELEMENTS (graph_names); ++i) {
                fprintf (stdout, "                           %-10s %s\n", graph_names [i].name, graph_names [i].desc);
        }
+}
+
+static void
+mini_usage_list_opt (void)
+{
+       int i;
+       
+       for (i = 0; i < G_N_ELEMENTS (opt_names); ++i)
+               fprintf (stdout, "                           %-10s %s\n", opt_names [i].name, opt_names [i].desc);
+}
 
+static void
+mini_usage (void)
+{
        fprintf (stdout,
+               "Usage is: mono [options] program [program-options]\n"
+               "\n"
+               "Development:\n"
+               "    --aot                  Compiles the assembly to native code\n"
+               "    --debug                Enable debugging support\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"
                "\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 (stdout, "                           %-10s %s\n", opt_names [i].name, opt_names [i].desc);
+               "    --optimize=OPT         Turns on or off a specific optimization\n"
+               "                           Use --list-opt to get a list of optimizations\n"
+               "    --security             Turns on the security manager (unsupported, default is off)\n");
 }
 
 static void
@@ -622,6 +653,22 @@ mono_main (int argc, char* argv[])
 
        setlocale (LC_ALL, "");
 
+       if (mono_running_on_valgrind () && getenv ("MONO_VALGRIND_LEAK_CHECK")) {
+               GMemVTable mem_vtable;
+
+               /* 
+                * 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;
+
+               g_mem_set_vtable (&mem_vtable);
+       }
+
        g_log_set_always_fatal (G_LOG_LEVEL_ERROR);
        g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR);
 
@@ -657,6 +704,12 @@ mono_main (int argc, char* argv[])
                } else if (strcmp (argv [i], "--help-trace") == 0){
                        mini_trace_usage ();
                        return 0;
+               } else if (strcmp (argv [i], "--help-devel") == 0){
+                       mini_usage_jitdeveloper ();
+                       return 0;
+               } else if (strcmp (argv [i], "--list-opt") == 0){
+                       mini_usage_list_opt ();
+                       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) {
@@ -682,11 +735,13 @@ mono_main (int argc, char* argv[])
                } else if (strcmp (argv [i], "--stats") == 0) {
                        mono_stats.enabled = TRUE;
                        mono_jit_stats.enabled = TRUE;
+#ifndef DISABLE_AOT
                } else if (strcmp (argv [i], "--aot") == 0) {
                        mono_compile_aot = TRUE;
                } else if (strncmp (argv [i], "--aot=", 6) == 0) {
                        mono_compile_aot = TRUE;
                        aot_options = &argv [i][6];
+#endif
                } else if (strcmp (argv [i], "--compile-all") == 0) {
                        action = DO_COMPILE;
                } else if (strcmp (argv [i], "--profile") == 0) {
@@ -708,6 +763,9 @@ mono_main (int argc, char* argv[])
                        action = DO_DRAW;
                } else if (strcmp (argv [i], "--debug") == 0) {
                        enable_debugging = TRUE;
+               } else if (strcmp (argv [i], "--security") == 0) {
+                       mono_use_security_manager = TRUE;
+                       mono_activate_security_manager ();
                } else {
                        fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
                        return 1;
@@ -826,8 +884,12 @@ mono_main (int argc, char* argv[])
                main_args.argv = argv + i;
                main_args.opts = opt;
                main_args.aot_options = aot_options;
-            
+#if RUN_IN_SUBTHREAD
                mono_runtime_exec_managed_code (domain, main_thread_handler, &main_args);
+#else
+               main_thread_handler (&main_args);
+               mono_thread_manage ();
+#endif
                mini_cleanup (domain);
 
                /* Look up return value from System.Environment.ExitCode */
@@ -876,10 +938,10 @@ mono_main (int argc, char* argv[])
                        (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
                        MonoMethod *nm;
                        nm = mono_marshal_get_native_wrapper (method);
-                       cfg = mini_method_compile (nm, opt, mono_get_root_domain (), FALSE, part);
+                       cfg = mini_method_compile (nm, opt, mono_get_root_domain (), FALSE, FALSE, part);
                }
                else
-                       cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, part);
+                       cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, 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;
@@ -911,7 +973,7 @@ mono_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_get_root_domain (), FALSE, 0);
+                                       cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, FALSE, 0);
                                        mono_destroy_compile (cfg);
                                }
                                g_timer_stop (timer);
@@ -934,12 +996,12 @@ mono_main (int argc, char* argv[])
                                        (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);
+                               cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, FALSE, 0);
                                mono_destroy_compile (cfg);
                        }
                }
        } else {
-               cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, 0);
+               cfg = mini_method_compile (method, opt, mono_get_root_domain (), FALSE, FALSE, 0);
                mono_destroy_compile (cfg);
        }
 
@@ -958,5 +1020,3 @@ mono_jit_cleanup (MonoDomain *domain)
 {
        mini_cleanup (domain);
 }
-
-