[io-layer] Extract error (#4279)
[mono.git] / mono / mini / aot-compiler.c
index aad2d7a06938b79e9df18c1c9b0d002e4c2d54f4..0d24eeb924d4bf9588ed4cd1e1515bf4d31b960b 100644 (file)
@@ -56,7 +56,7 @@
 #include <mono/utils/json.h>
 #include <mono/utils/mono-threads-coop.h>
 #include <mono/profiler/mono-profiler-aot.h>
-#include <mono/io-layer/io-layer.h>
+#include <mono/utils/w32api.h>
 
 #include "aot-compiler.h"
 #include "seq-points.h"
@@ -182,6 +182,7 @@ typedef struct MonoAotOptions {
        int nrgctx_fetch_trampolines;
        gboolean print_skipped_methods;
        gboolean stats;
+       gboolean verbose;
        char *tool_prefix;
        char *ld_flags;
        char *mtriple;
@@ -190,6 +191,7 @@ typedef struct MonoAotOptions {
        char *instances_logfile_path;
        char *logfile;
        gboolean dump_json;
+       gboolean profile_only;
 } MonoAotOptions;
 
 typedef enum {
@@ -311,6 +313,7 @@ typedef struct MonoAotCompile {
        GPtrArray *objc_selectors;
        GHashTable *objc_selector_to_index;
        GList *profile_data;
+       GHashTable *profile_methods;
        FILE *logfile;
        FILE *instances_logfile;
        FILE *data_outfile;
@@ -7223,6 +7226,10 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        opts->data_outfile = g_strdup (arg + strlen ("data-outfile="));
                } else if (str_begins_with (arg, "profile=")) {
                        opts->profile_files = g_list_append (opts->profile_files, g_strdup (arg + strlen ("profile=")));
+               } else if (!strcmp (arg, "profile-only")) {
+                       opts->profile_only = TRUE;
+               } else if (!strcmp (arg, "verbose")) {
+                       opts->verbose = TRUE;
                } else if (str_begins_with (arg, "help") || str_begins_with (arg, "?")) {
                        printf ("Supported options for --aot:\n");
                        printf ("    outfile=\n");
@@ -7255,6 +7262,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        printf ("    stats\n");
                        printf ("    dump\n");
                        printf ("    info\n");
+                       printf ("    verbose\n");
                        printf ("    help/?\n");
                        exit (0);
                } else {
@@ -7544,6 +7552,9 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
        if (method->wrapper_type == MONO_WRAPPER_COMINTEROP)
                return;
 
+       if (acfg->aot_opts.profile_only && !method->is_inflated && !g_hash_table_lookup (acfg->profile_methods, method))
+               return;
+
        InterlockedIncrement (&acfg->stats.mcount);
 
 #if 0
@@ -10403,8 +10414,11 @@ resolve_profile_data (MonoAotCompile *acfg, ProfileData *data)
        while (g_hash_table_iter_next (&iter, &key, &value)) {
                ClassProfileData *cdata = (ClassProfileData*)value;
 
-               if (!cdata->image->image)
+               if (!cdata->image->image) {
+                       if (acfg->aot_opts.verbose)
+                               printf ("Unable to load class '%s.%s' because its image '%s' is not loaded.\n", cdata->ns, cdata->name, cdata->image->name);
                        continue;
+               }
 
                resolve_class (cdata);
                /*
@@ -10423,8 +10437,11 @@ resolve_profile_data (MonoAotCompile *acfg, ProfileData *data)
 
                resolve_class (mdata->klass);
                klass = mdata->klass->klass;
-               if (!klass)
+               if (!klass) {
+                       if (acfg->aot_opts.verbose)
+                               printf ("Unable to load method '%s' because its class '%s.%s' is not loaded.\n", mdata->name, mdata->klass->ns, mdata->klass->name);
                        continue;
+               }
                miter = NULL;
                while ((m = mono_class_get_methods (klass, &miter))) {
                        MonoError error;
@@ -10458,11 +10475,16 @@ resolve_profile_data (MonoAotCompile *acfg, ProfileData *data)
                        gboolean match = !strcmp (sig_str, mdata->signature);
                        g_free (sig_str);
                        if (!match)
+
                                continue;
                        //printf ("%s\n", mono_method_full_name (m, 1));
                        mdata->method = m;
                        break;
                }
+               if (!mdata->method) {
+                       if (acfg->aot_opts.verbose)
+                               printf ("Unable to load method '%s' from class '%s', not found.\n", mdata->name, mono_class_full_name (klass));
+               }
        }
 }
 
@@ -10507,6 +10529,23 @@ add_profile_instances (MonoAotCompile *acfg, ProfileData *data)
        if (!data)
                return;
 
+       if (acfg->aot_opts.profile_only) {
+               /* Add methods referenced by the profile */
+               g_hash_table_iter_init (&iter, data->methods);
+               while (g_hash_table_iter_next (&iter, &key, &value)) {
+                       MethodProfileData *mdata = (MethodProfileData*)value;
+                       MonoMethod *m = mdata->method;
+
+                       if (!m)
+                               continue;
+                       if (m->is_inflated)
+                               continue;
+                       add_extra_method (acfg, m);
+                       g_hash_table_insert (acfg->profile_methods, m, m);
+                       count ++;
+               }
+       }
+
        /*
         * Add method instances 'related' to this assembly to the AOT image.
         */
@@ -10594,6 +10633,7 @@ acfg_create (MonoAssembly *ass, guint32 opts)
        acfg->plt_entry_debug_sym_cache = g_hash_table_new (g_str_hash, g_str_equal);
        acfg->gsharedvt_in_signatures = g_hash_table_new ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal);
        acfg->gsharedvt_out_signatures = g_hash_table_new ((GHashFunc)mono_signature_hash, (GEqualFunc)mono_metadata_signature_equal);
+       acfg->profile_methods = g_hash_table_new (NULL, NULL);
        mono_os_mutex_init_recursive (&acfg->mutex);
 
        init_got_info (&acfg->got_info);