Revert "Merge branch 'master' of https://github.com/mono/mono"
[mono.git] / mono / mini / aot-compiler.c
index dc1d868f343d4df6c89f70c1da158f79e6872121..c28ec1d5b08ca990a33b39dd135531f4dbfe0492 100644 (file)
@@ -128,6 +128,7 @@ typedef struct MonoAotOptions {
        gboolean dwarf_debug;
        gboolean soft_debug;
        gboolean log_generics;
+       gboolean log_instances;
        gboolean direct_pinvoke;
        gboolean direct_icalls;
        gboolean no_direct_calls;
@@ -146,6 +147,7 @@ typedef struct MonoAotOptions {
        gboolean autoreg;
        char *mtriple;
        char *llvm_path;
+       char *instances_logfile_path;
 } MonoAotOptions;
 
 typedef struct MonoAotStats {
@@ -240,6 +242,7 @@ typedef struct MonoAotCompile {
        int objc_selector_index, objc_selector_index_2;
        GPtrArray *objc_selectors;
        GHashTable *objc_selector_to_index;
+       FILE *instances_logfile;
 } MonoAotCompile;
 
 typedef struct {
@@ -3880,7 +3883,8 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth,
         * Use gsharedvt for generic collections with vtype arguments to avoid code blowup.
         * Enable this only for some classes since gsharedvt might not support all methods.
         */
-       if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && klass->generic_class && klass->generic_class->context.class_inst && is_vt_inst (klass->generic_class->context.class_inst) && (!strcmp (klass->name, "Dictionary`2") || !strcmp (klass->name, "List`1")))
+       if ((acfg->opts & MONO_OPT_GSHAREDVT) && klass->image == mono_defaults.corlib && klass->generic_class && klass->generic_class->context.class_inst && is_vt_inst (klass->generic_class->context.class_inst) &&
+               (!strcmp (klass->name, "Dictionary`2") || !strcmp (klass->name, "List`1") || !strcmp (klass->name, "ReadOnlyCollection`1")))
                use_gsharedvt = TRUE;
 
        iter = NULL;
@@ -6284,6 +6288,11 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        opts->no_instances = TRUE;
                } else if (str_begins_with (arg, "log-generics")) {
                        opts->log_generics = TRUE;
+               } else if (str_begins_with (arg, "log-instances=")) {
+                       opts->log_instances = TRUE;
+                       opts->instances_logfile_path = g_strdup (arg + strlen ("log-instances="));
+               } else if (str_begins_with (arg, "log-instances")) {
+                       opts->log_instances = TRUE;
                } else if (str_begins_with (arg, "mtriple=")) {
                        opts->mtriple = g_strdup (arg + strlen ("mtriple="));
                } else if (str_begins_with (arg, "llvm-path=")) {
@@ -6605,6 +6614,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
                return;
        }
 
+       if (method->is_inflated && acfg->aot_opts.log_instances) {
+               if (acfg->instances_logfile)
+                       fprintf (acfg->instances_logfile, "%s ### %d\n", mono_method_full_name (method, TRUE), cfg->code_size);
+               else
+                       printf ("%s ### %d\n", mono_method_full_name (method, TRUE), cfg->code_size);
+       }
+
        /* Adds generic instances referenced by this method */
        /* 
         * The depth is used to avoid infinite loops when generic virtual recursion is 
@@ -7247,16 +7263,16 @@ emit_code (MonoAotCompile *acfg)
                method = cfg->orig_method;
 
                if (acfg->aot_opts.full_aot && cfg->orig_method->klass->valuetype) {
+                       int call_size;
+
                        index = get_method_index (acfg, method);
                        sprintf (symbol, "ut_%d", index);
 
                        emit_int32 (acfg, index);
                        if (acfg->direct_method_addresses) {
-                               emit_unset_mode (acfg);
-                               if (acfg->thumb_mixed && cfg->compile_llvm)
-                                       fprintf (acfg->fp, "\n\tblx %s\n", symbol);
-                               else
-                                       fprintf (acfg->fp, "\n\tbl %s\n", symbol);
+#ifdef MONO_ARCH_AOT_SUPPORTED
+                               arch_emit_direct_call (acfg, symbol, FALSE, acfg->thumb_mixed && cfg->compile_llvm, NULL, &call_size);
+#endif
                        } else {
                                emit_symbol_diff (acfg, symbol, acfg->methods_symbol, 0);
                        }
@@ -8757,6 +8773,14 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        if (acfg->aot_opts.full_aot)
                acfg->flags |= MONO_AOT_FILE_FLAG_FULL_AOT;
 
+       if (acfg->aot_opts.instances_logfile_path) {
+               acfg->instances_logfile = fopen (acfg->aot_opts.instances_logfile_path, "w");
+               if (!acfg->instances_logfile) {
+                       fprintf (stderr, "Unable to create logfile: '%s'.\n", acfg->aot_opts.instances_logfile_path);
+                       exit (1);
+               }
+       }
+
        load_profile_files (acfg);
 
        acfg->num_trampolines [MONO_AOT_TRAMP_SPECIFIC] = acfg->aot_opts.full_aot ? acfg->aot_opts.ntrampolines : 0;