2008-08-22 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / driver.c
index 38cd1cf071296585d7d6adc7c73b434406ae43d5..a3445c7f33a19e98b4f88a9b5933113c398aa6c5 100644 (file)
@@ -44,7 +44,9 @@
 #include <mono/metadata/security-manager.h>
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/coree.h>
 #include "mono/utils/mono-counters.h"
+#include <mono/os/gc_wrapper.h>
 
 #include "mini.h"
 #include "jit.h"
@@ -125,6 +127,8 @@ opt_funcs [sizeof (int) * 8] = {
        MONO_OPT_INTRINS |  \
        MONO_OPT_LOOP |  \
        MONO_OPT_EXCEPTION |  \
+    MONO_OPT_CMOV |  \
+       MONO_OPT_GSHARED |      \
        MONO_OPT_AOT)
 
 #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP)
@@ -299,6 +303,7 @@ 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_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,
        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,
@@ -619,7 +624,7 @@ free_jit_info_data (ThreadData *td, JitInfoData *free)
                while (free->next != NULL) {
                        JitInfoData *next = free->next->next;
 
-                       g_free (free->next->ji);
+                       //g_free (free->next->ji);
                        g_free (free->next);
                        free->next = next;
 
@@ -670,16 +675,26 @@ test_thread_func (ThreadData *td)
                                if (region->num_datas > 0) {
                                        JitInfoData **data = choose_random_data (region);
                                        guint pos = (*data)->start + random () % (*data)->length;
-                                       MonoJitInfo *ji = mono_jit_info_table_find (domain, (char*)(gulong) pos);
+                                       MonoJitInfo *ji;
+
+                                       ji = mono_jit_info_table_find (domain, (char*)(gulong) pos);
 
-                                       g_assert ((*data)->ji == ji);
                                        g_assert (ji->cas_inited);
+                                       g_assert ((*data)->ji == ji);
                                }
                        } else {
                                int pos = random () % MAX_ADDR;
                                char *addr = (char*)(gulong) pos;
-                               MonoJitInfo *ji = mono_jit_info_table_find (domain, addr);
+                               MonoJitInfo *ji;
 
+                               ji = mono_jit_info_table_find (domain, addr);
+
+                               /*
+                                * FIXME: We are actually not allowed
+                                * to do this.  By the time we examine
+                                * the ji another thread might already
+                                * have removed it.
+                                */
                                if (ji != NULL) {
                                        g_assert (addr >= (char*)ji->code_start && addr < (char*)ji->code_start + ji->code_size);
                                        ++lookup_successes;
@@ -703,7 +718,7 @@ test_thread_func (ThreadData *td)
 
                                mono_jit_info_table_remove (domain, (*data)->ji);
 
-                               (*data)->ji->cas_inited = 0; /* marks a free jit info */
+                               //(*data)->ji->cas_inited = 0; /* marks a free jit info */
 
                                free = *data;
                                *data = (*data)->next;
@@ -909,16 +924,29 @@ 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);
+                       }
+                       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.
@@ -947,9 +975,10 @@ 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"
                 "\n"
                 "Other options:\n" 
                 "    --graph[=TYPE] METHOD  Draws a graph of the specified method:\n");
@@ -1029,6 +1058,15 @@ mini_debug_usage (void)
                 "                         process with the debugger.\n");
 }
 
+#if defined(__arm__) && defined(__ARM_EABI__)
+/* Redefine ARCHITECTURE to include more information */
+#undef ARCHITECTURE
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define ARCHITECTURE "armel"
+#else
+#define ARCHITECTURE "armeb"
+#endif
+#endif
 
 static const char info[] =
 #ifdef HAVE_KW_THREAD
@@ -1057,6 +1095,26 @@ static const char info[] =
 #define error_if_aot_unsupported()
 #endif
 
+#ifdef PLATFORM_WIN32
+BOOL APIENTRY DllMain (HMODULE module_handle, DWORD reason, LPVOID reserved)
+{
+       if (!GC_DllMain (module_handle, reason, reserved))
+               return FALSE;
+
+       switch (reason)
+       {
+       case DLL_PROCESS_ATTACH:
+               mono_install_runtime_load (mini_init);
+               break;
+       case DLL_PROCESS_DETACH:
+               if (coree_module_handle)
+                       FreeLibrary (coree_module_handle);
+               break;
+       }
+       return TRUE;
+}
+#endif
+
 int
 mono_main (int argc, char* argv[])
 {
@@ -1123,7 +1181,7 @@ 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-2007 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, FULL_VERSION);
+                       g_print ("Mono JIT compiler version %s (%s)\nCopyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com\n", VERSION, FULL_VERSION);
                        g_print (info);
                        if (mini_verbose) {
                                const char *cerror;
@@ -1215,6 +1273,8 @@ mono_main (int argc, char* argv[])
                        mono_inject_async_exc_pos = atoi (argv [++i]);
                } else if (strcmp (argv [i], "--verify-all") == 0) {
                        mono_verifier_enable_verify_all ();
+               } else if (strcmp (argv [i], "--full-aot") == 0) {
+                       mono_aot_only = TRUE;
                } else if (strcmp (argv [i], "--print-vtable") == 0) {
                        mono_print_vtable = TRUE;
                } else if (strcmp (argv [i], "--stats") == 0) {
@@ -1339,7 +1399,7 @@ mono_main (int argc, char* argv[])
                return 1;
        }
 
-       if ((action == DO_EXEC) && g_getenv ("MONO_INSIDE_MDB"))
+       if ((action == DO_EXEC) && mono_debug_using_mono_debugger ())
                action = DO_DEBUGGER;
 
        if (mono_compile_aot || action == DO_EXEC || action == DO_DEBUGGER) {
@@ -1376,6 +1436,7 @@ mono_main (int argc, char* argv[])
                mono_debug_init (MONO_DEBUG_FORMAT_MONO);
 
        mono_set_defaults (mini_verbose, opt);
+       mono_setup_vtable_in_class_init = FALSE;
        domain = mini_init (argv [i], forced_version);
        
        switch (action) {
@@ -1537,7 +1598,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
@@ -1594,7 +1655,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);
@@ -1617,7 +1678,7 @@ mono_jit_init (const char *file)
 
 /**
  * mono_jit_init_version:
- * @file: the initial assembly to load
+ * @domain_name: the name of the root domain
  * @runtime_version: the version of the runtime to load
  *
  * Use this version when you want to force a particular runtime
@@ -1635,9 +1696,9 @@ mono_jit_init (const char *file)
  * was loaded.
  */
 MonoDomain * 
-mono_jit_init_version (const char *file, const char *runtime_version)
+mono_jit_init_version (const char *domain_name, const char *runtime_version)
 {
-       return mini_init (file, runtime_version);
+       return mini_init (domain_name, runtime_version);
 }
 
 void        
@@ -1645,3 +1706,23 @@ mono_jit_cleanup (MonoDomain *domain)
 {
        mini_cleanup (domain);
 }
+
+/**
+ * mono_jit_set_trace_options:
+ * @options: string representing the trace options
+ *
+ * Set the options of the tracing engine. This function can be called before initializing
+ * the mono runtime. See the --trace mono(1) manpage for the options format.
+ *
+ * Returns: #TRUE if the options where parsed and set correctly, #FALSE otherwise.
+ */
+gboolean
+mono_jit_set_trace_options (const char* options)
+{
+       MonoTraceSpec *trace_opt = mono_trace_parse_options (options);
+       if (trace_opt == NULL)
+               return FALSE;
+       mono_jit_trace_calls = trace_opt;
+       return TRUE;
+}
+