[exdoc] Handle punctuation better in code formatting.
[mono.git] / mono / mini / driver.c
index 6e06724a9f0ea42b1cdbde2ee17b88333099c2d2..310c9f070e24bb6dcfc51fcfa1d3c1ed81ffccde 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * driver.c: The new mono JIT compiler.
+/**
+ * \file
+ * The new mono JIT compiler.
  *
  * Author:
  *   Paolo Molaro (lupus@ximian.com)
@@ -21,7 +22,7 @@
 #include <unistd.h>
 #endif
 
-#include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/loader.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/class.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/threads.h>
 #include <mono/metadata/marshal.h>
-#include <mono/metadata/socket-io.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
-#include <mono/io-layer/io-layer.h>
 #include "mono/metadata/profiler.h"
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/coree.h>
 #include <mono/metadata/attach.h>
+#include <mono/metadata/w32process.h>
 #include "mono/utils/mono-counters.h"
 #include "mono/utils/mono-hwcap.h"
 #include "mono/utils/mono-logger-internals.h"
-#include "mono/utils/w32handle.h"
+#include "mono/metadata/w32handle.h"
 
 #include "mini.h"
 #include "jit.h"
 #include "aot-compiler.h"
+#include "interp/interp.h"
 
 #include <string.h>
 #include <ctype.h>
@@ -120,11 +121,6 @@ opt_names [] = {
 
 #endif
 
-static const OptFunc
-opt_funcs [sizeof (int) * 8] = {
-       NULL
-};
-
 #ifdef __native_client__
 extern char *nacl_mono_path;
 #endif
@@ -154,7 +150,8 @@ parse_optimizations (guint32 opt, const char* p, gboolean cpu_opts)
 {
        guint32 exclude = 0;
        const char *n;
-       int i, invert, len;
+       int i, invert;
+       char **parts, **ptr;
 
        /* Initialize the hwcap module if necessary. */
        mono_hwcap_init ();
@@ -167,7 +164,11 @@ parse_optimizations (guint32 opt, const char* p, gboolean cpu_opts)
        if (!p)
                return opt;
 
-       while (*p) {
+       parts = g_strsplit (p, ",", -1);
+       for (ptr = parts; ptr && *ptr; ptr ++) {
+               char *arg = *ptr;
+               char *p = arg;
+
                if (*p == '-') {
                        p++;
                        invert = TRUE;
@@ -176,24 +177,11 @@ parse_optimizations (guint32 opt, const char* p, gboolean cpu_opts)
                }
                for (i = 0; i < G_N_ELEMENTS (opt_names) && optflag_get_name (i); ++i) {
                        n = optflag_get_name (i);
-                       len = strlen (n);
-                       if (strncmp (p, n, len) == 0) {
+                       if (!strcmp (p, n)) {
                                if (invert)
                                        opt &= ~ (1 << i);
                                else
                                        opt |= 1 << i;
-                               p += len;
-                               if (*p == ',') {
-                                       p++;
-                                       break;
-                               } else if (*p == '=') {
-                                       p++;
-                                       if (opt_funcs [i])
-                                               opt_funcs [i] (p);
-                                       while (*p && *p++ != ',');
-                                       break;
-                               }
-                               /* error out */
                                break;
                        }
                }
@@ -203,15 +191,16 @@ parse_optimizations (guint32 opt, const char* p, gboolean cpu_opts)
                                        opt = 0;
                                else
                                        opt = ~(EXCLUDED_FROM_ALL | exclude);
-                               p += 3;
-                               if (*p == ',')
-                                       p++;
                        } else {
                                fprintf (stderr, "Invalid optimization name `%s'\n", p);
                                exit (1);
                        }
                }
+
+               g_free (arg);
        }
+       g_free (parts);
+
        return opt;
 }
 
@@ -548,7 +537,7 @@ mini_regression_list (int verbose, int count, char *images [])
        
        total_run =  total = 0;
        for (i = 0; i < count; ++i) {
-               ass = mono_assembly_open (images [i], NULL);
+               ass = mono_assembly_open_predicate (images [i], FALSE, FALSE, NULL, NULL, NULL);
                if (!ass) {
                        g_warning ("failed to load assembly: %s", images [i]);
                        continue;
@@ -934,7 +923,7 @@ compile_all_methods_thread_main_inner (CompileAllThreadArgs *args)
                    (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
                        continue;
 
-               if (method->klass->generic_container)
+               if (mono_class_is_gtd (method->klass))
                        continue;
                sig = mono_method_signature (method);
                if (!sig) {
@@ -954,7 +943,7 @@ compile_all_methods_thread_main_inner (CompileAllThreadArgs *args)
                        g_print ("Compiling %d %s\n", count, desc);
                        g_free (desc);
                }
-               cfg = mini_method_compile (method, mono_get_optimizations_for_method (method, args->opts), mono_get_root_domain (), (JitFlags)0, 0, -1);
+               cfg = mini_method_compile (method, mono_get_optimizations_for_method (method, args->opts), mono_get_root_domain (), (JitFlags)JIT_FLAG_DISCARD_RESULTS, 0, -1);
                if (cfg->exception_type != MONO_EXCEPTION_NONE) {
                        printf ("Compilation of %s failed with exception '%s':\n", mono_method_full_name (cfg->method, TRUE), cfg->exception_message);
                        fail_count ++;
@@ -997,10 +986,9 @@ compile_all_methods (MonoAssembly *ass, int verbose, guint32 opts, guint32 recom
 
 /**
  * mono_jit_exec:
- * @assembly: reference to an assembly
- * @argc: argument count
- * @argv: argument vector
- *
+ * \param assembly reference to an assembly
+ * \param argc argument count
+ * \param argv argument vector
  * Start execution of a program.
  */
 int 
@@ -1134,7 +1122,7 @@ load_agent (MonoDomain *domain, char *desc)
                args = NULL;
        }
 
-       agent_assembly = mono_assembly_open (agent, &open_status);
+       agent_assembly = mono_assembly_open_predicate (agent, FALSE, FALSE, NULL, NULL, &open_status);
        if (!agent_assembly) {
                fprintf (stderr, "Cannot open agent assembly '%s': %s.\n", agent, mono_image_strerror (open_status));
                g_free (agent);
@@ -1210,7 +1198,6 @@ mini_usage_jitdeveloper (void)
                 "    --single-method=OPTS   Runs regressions with only one method optimized with OPTS at any time\n"
                 "    --statfile FILE        Sets the stat file to FILE\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 assemblies and methods\n"
                 "    --full-aot             Avoid JITting any code\n"
@@ -1274,6 +1261,8 @@ mini_usage (void)
 #ifdef HOST_WIN32
                "    --mixed-mode           Enable mixed-mode image support.\n"
 #endif
+               "    --handlers             Install custom handlers, use --help-handlers for details.\n"
+               "    --aot-path=PATH        List of additional directories to search for AOT images.\n"
          );
 }
 
@@ -1434,6 +1423,10 @@ mono_jit_parse_options (int argc, char * argv[])
                        
                        if (!mono_debugger_insert_breakpoint (argv [++i], FALSE))
                                fprintf (stderr, "Error: invalid method name '%s'\n", argv [i]);
+               } else if (strncmp (argv[i], "--gc-params=", 12) == 0) {
+                       mono_gc_params_set (argv[i] + 12);
+               } else if (strncmp (argv[i], "--gc-debug=", 11) == 0) {
+                       mono_gc_debug_set (argv[i] + 11);
                } else if (strcmp (argv [i], "--llvm") == 0) {
 #ifndef MONO_ARCH_LLVM_SUPPORTED
                        fprintf (stderr, "Mono Warning: --llvm not supported on this platform.\n");
@@ -1552,11 +1545,14 @@ switch_arch (char* argv[], const char* target_arch)
 }
 
 #endif
+
+#define MONO_HANDLERS_ARGUMENT "--handlers="
+#define MONO_HANDLERS_ARGUMENT_LEN G_N_ELEMENTS(MONO_HANDLERS_ARGUMENT)-1
+
 /**
  * mono_main:
- * @argc: number of arguments in the argv array
- * @argv: array of strings containing the startup arguments
- *
+ * \param argc number of arguments in the argv array
+ * \param argv array of strings containing the startup arguments
  * Launches the Mono JIT engine and parses all the command line options
  * in the same way that the mono command line VM would.
  */
@@ -1679,6 +1675,10 @@ mono_main (int argc, char* argv[])
                        switch_gc (argv, "sgen");
                } else if (strcmp (argv [i], "--gc=boehm") == 0) {
                        switch_gc (argv, "boehm");
+               } else if (strncmp (argv[i], "--gc-params=", 12) == 0) {
+                       mono_gc_params_set (argv[i] + 12);
+               } else if (strncmp (argv[i], "--gc-debug=", 11) == 0) {
+                       mono_gc_debug_set (argv[i] + 11);
                }
 #ifdef TARGET_OSX
                else if (strcmp (argv [i], "--arch=32") == 0) {
@@ -1745,11 +1745,11 @@ mono_main (int argc, char* argv[])
                } 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;
+                       mono_jit_set_aot_mode (MONO_AOT_MODE_FULL);
                } else if (strcmp (argv [i], "--llvmonly") == 0) {
-                       mono_aot_only = TRUE;
-                       mono_llvm_only = TRUE;
+                       mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);
                } else if (strcmp (argv [i], "--hybrid-aot") == 0) {
+                       mono_jit_set_aot_mode (MONO_AOT_MODE_HYBRID);
                } else if (strcmp (argv [i], "--print-vtable") == 0) {
                        mono_print_vtable = TRUE;
                } else if (strcmp (argv [i], "--stats") == 0) {
@@ -1765,6 +1765,16 @@ mono_main (int argc, char* argv[])
                        mono_compile_aot = TRUE;
                        aot_options = &argv [i][6];
 #endif
+               } else if (strncmp (argv [i], "--aot-path=", 11) == 0) {
+                       char **splitted;
+
+                       splitted = g_strsplit (argv [i] + 11, G_SEARCHPATH_SEPARATOR_S, 1000);
+                       while (*splitted) {
+                               char *tmp = *splitted;
+                               mono_aot_paths = g_list_append (mono_aot_paths, g_strdup (tmp));
+                               g_free (tmp);
+                               splitted++;
+                       }
                } else if (strncmp (argv [i], "--compile-all=", 14) == 0) {
                        action = DO_COMPILE;
                        recompilation_times = atoi (argv [i] + 14);
@@ -1894,12 +1904,26 @@ mono_main (int argc, char* argv[])
 #endif
                } else if (strcmp (argv [i], "--nollvm") == 0){
                        mono_use_llvm = FALSE;
+#ifdef ENABLE_INTERPRETER
+               } else if (strcmp (argv [i], "--interpreter") == 0) {
+                       mono_use_interpreter = TRUE;
+#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 if (strncmp (argv [i], MONO_HANDLERS_ARGUMENT, MONO_HANDLERS_ARGUMENT_LEN) == 0) {
+                       //Install specific custom handlers.
+                       if (!mono_runtime_install_custom_handlers (argv[i] + MONO_HANDLERS_ARGUMENT_LEN)) {
+                               fprintf (stderr, "error: " MONO_HANDLERS_ARGUMENT ", one or more unknown handlers: '%s'\n", argv [i]);
+                               return 1;
+                       }
+               } else if (strcmp (argv [i], "--help-handlers") == 0) {
+                       mono_runtime_install_custom_handlers_usage ();
+                       return 0;
                } else if (argv [i][0] == '-' && argv [i][1] == '-' && mini_parse_debug_option (argv [i] + 2)) {
                } else {
                        fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
@@ -1934,9 +1958,9 @@ mono_main (int argc, char* argv[])
        {
                char *runtime_path;
 
-               runtime_path = wapi_process_get_path (getpid ());
+               runtime_path = mono_w32process_get_path (getpid ());
                if (runtime_path) {
-                       wapi_process_set_cli_launcher (runtime_path);
+                       mono_w32process_set_cli_launcher (runtime_path);
                        g_free (runtime_path);
                }
        }
@@ -1972,15 +1996,8 @@ mono_main (int argc, char* argv[])
        /* Set rootdir before loading config */
        mono_set_rootdir ();
 
-       /*
-        * We only set the native name of the thread since MS.NET leaves the
-        * managed thread name for the main thread as null.
-        */
-       mono_native_thread_set_name (mono_native_thread_id_get (), "Main");
-
        if (enable_profile) {
-               mono_profiler_load (profile_options);
-               mono_profiler_thread_name (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()), "Main");
+               mini_profiler_enable_with_options (profile_options);
        }
 
        mono_attach_parse_options (attach_options);
@@ -2020,6 +2037,9 @@ mono_main (int argc, char* argv[])
        }
 
        mono_set_defaults (mini_verbose, opt);
+#ifdef ENABLE_INTERPRETER
+       mono_interp_init ();
+#endif
        domain = mini_init (argv [i], forced_version);
 
        mono_gc_set_stack_end (&domain);
@@ -2043,6 +2063,17 @@ mono_main (int argc, char* argv[])
        case DO_SINGLE_METHOD_REGRESSION:
                mono_do_single_method_regression = TRUE;
        case DO_REGRESSION:
+#ifdef ENABLE_INTERPRETER
+               if (mono_use_interpreter) {
+                       if (mono_interp_regression_list (2, argc -i, argv + i)) {
+                               g_print ("Regression ERRORS!\n");
+                               // mini_cleanup (domain);
+                               return 1;
+                       }
+                       // mini_cleanup (domain);
+                       return 0;
+               }
+#endif
                if (mini_regression_list (mini_verbose, argc -i, argv + i)) {
                        g_print ("Regression ERRORS!\n");
                        mini_cleanup (domain);
@@ -2089,7 +2120,7 @@ mono_main (int argc, char* argv[])
                jit_info_table_test (domain);
 #endif
 
-       assembly = mono_assembly_open (aname, &open_status);
+       assembly = mono_assembly_open_predicate (aname, FALSE, FALSE, NULL, NULL, &open_status);
        if (!assembly) {
                fprintf (stderr, "Cannot open assembly '%s': %s.\n", aname, mono_image_strerror (open_status));
                mini_cleanup (domain);
@@ -2113,7 +2144,7 @@ mono_main (int argc, char* argv[])
                        exit (1);
                }
 
-#ifdef HOST_WIN32
+#if defined(HOST_WIN32) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
                /* Detach console when executing IMAGE_SUBSYSTEM_WINDOWS_GUI on win32 */
                if (!enable_debugging && !mono_compile_aot && ((MonoCLIImageInfo*)(mono_assembly_get_image (assembly)->image_info))->cli_header.nt.pe_subsys_required == IMAGE_SUBSYSTEM_WINDOWS_GUI)
                        FreeConsole ();
@@ -2263,22 +2294,22 @@ mono_jit_init (const char *file)
 
 /**
  * mono_jit_init_version:
- * @domain_name: the name of the root domain
- * @runtime_version: the version of the runtime to load
+ * \param domain_name the name of the root domain
+ * \param runtime_version the version of the runtime to load
  *
  * Use this version when you want to force a particular runtime
  * version to be used.  By default Mono will pick the runtime that is
- * referenced by the initial assembly (specified in @file), this
+ * referenced by the initial assembly (specified in \p file), this
  * routine allows programmers to specify the actual runtime to be used
  * as the initial runtime is inherited by all future assemblies loaded
  * (since Mono does not support having more than one mscorlib runtime
  * loaded at once).
  *
- * The @runtime_version can be one of these strings: "v4.0.30319" for
+ * The \p runtime_version can be one of these strings: "v4.0.30319" for
  * desktop, "mobile" for mobile or "moonlight" for Silverlight compat.
  * If an unrecognized string is input, the vm will default to desktop.
  *
- * Returns: the MonoDomain representing the domain where the assembly
+ * \returns the \c MonoDomain representing the domain where the assembly
  * was loaded.
  */
 MonoDomain * 
@@ -2304,21 +2335,30 @@ mono_jit_set_aot_only (gboolean val)
 void
 mono_jit_set_aot_mode (MonoAotMode mode)
 {
+       /* we don't want to set mono_aot_mode twice */
+       g_assert (mono_aot_mode == MONO_AOT_MODE_NONE);
        mono_aot_mode = mode;
+
        if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY) {
                mono_aot_only = TRUE;
                mono_llvm_only = TRUE;
        }
+       if (mono_aot_mode == MONO_AOT_MODE_FULL) {
+               mono_aot_only = TRUE;
+       }
+       if (mono_aot_mode == MONO_AOT_MODE_HYBRID) {
+               mono_set_generic_sharing_vt_supported (TRUE);
+               mono_set_partial_sharing_supported (TRUE);
+       }
 }
 
 /**
  * mono_jit_set_trace_options:
- * @options: string representing the trace options
- *
+ * \param 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.
+ * \returns TRUE if the options were parsed and set correctly, FALSE otherwise.
  */
 gboolean
 mono_jit_set_trace_options (const char* options)
@@ -2364,14 +2404,14 @@ mono_set_crash_chaining (gboolean chain_crashes)
 
 /**
  * mono_parse_options_from:
- * @options: string containing strings 
- * @ref_argc: pointer to the argc variable that might be updated 
- * @ref_argv: pointer to the argv string vector variable that might be updated
+ * \param options string containing strings 
+ * \param ref_argc pointer to the \c argc variable that might be updated 
+ * \param ref_argv pointer to the \c argv string vector variable that might be updated
  *
- * This function parses the contents of the `MONO_ENV_OPTIONS`
+ * This function parses the contents of the \c MONO_ENV_OPTIONS
  * environment variable as if they were parsed by a command shell
  * splitting the contents by spaces into different elements of the
- * @argv vector.  This method supports quoting with both the " and '
+ * \p argv vector.  This method supports quoting with both the " and '
  * characters.  Inside quoting, spaces and tabs are significant,
  * otherwise, they are considered argument separators.
  *
@@ -2380,14 +2420,14 @@ mono_set_crash_chaining (gboolean chain_crashes)
  * inside quotes.   If the quotes are not balanced, this method 
  *
  * If the environment variable is empty, no changes are made
- * to the values pointed by @ref_argc and @ref_argv.
+ * to the values pointed by \p ref_argc and \p ref_argv.
  *
- * Otherwise the @ref_argv is modified to point to a new array that contains
+ * Otherwise the \p ref_argv is modified to point to a new array that contains
  * all the previous elements contained in the vector, plus the values parsed.
- * The @argc is updated to match the new number of parameters.
+ * The \p argc is updated to match the new number of parameters.
  *
- * Returns: The value NULL is returned on success, otherwise a g_strdup allocated
- * string is returned (this is an alias to malloc under normal circumstances) that
+ * \returns The value NULL is returned on success, otherwise a \c g_strdup allocated
+ * string is returned (this is an alias to \c malloc under normal circumstances) that
  * contains the error message that happened during parsing.
  */
 char *
@@ -2471,13 +2511,13 @@ mono_parse_options_from (const char *options, int *ref_argc, char **ref_argv [])
 
 /**
  * mono_parse_env_options:
- * @ref_argc: pointer to the argc variable that might be updated 
- * @ref_argv: pointer to the argv string vector variable that might be updated
+ * \param ref_argc pointer to the \c argc variable that might be updated 
+ * \param ref_argv pointer to the \c argv string vector variable that might be updated
  *
- * This function parses the contents of the `MONO_ENV_OPTIONS`
+ * This function parses the contents of the \c MONO_ENV_OPTIONS
  * environment variable as if they were parsed by a command shell
  * splitting the contents by spaces into different elements of the
- * @argv vector.  This method supports quoting with both the " and '
+ * \p argv vector.  This method supports quoting with both the " and '
  * characters.  Inside quoting, spaces and tabs are significant,
  * otherwise, they are considered argument separators.
  *
@@ -2486,11 +2526,11 @@ mono_parse_options_from (const char *options, int *ref_argc, char **ref_argv [])
  * inside quotes.   If the quotes are not balanced, this method 
  *
  * If the environment variable is empty, no changes are made
- * to the values pointed by @ref_argc and @ref_argv.
+ * to the values pointed by \p ref_argc and \p ref_argv.
  *
- * Otherwise the @ref_argv is modified to point to a new array that contains
+ * Otherwise the \p ref_argv is modified to point to a new array that contains
  * all the previous elements contained in the vector, plus the values parsed.
- * The @argc is updated to match the new number of parameters.
+ * The \p argc is updated to match the new number of parameters.
  *
  * If there is an error parsing, this method will terminate the process by
  * calling exit(1).