#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"
int nrgctx_fetch_trampolines;
gboolean print_skipped_methods;
gboolean stats;
+ gboolean verbose;
char *tool_prefix;
char *ld_flags;
char *mtriple;
char *instances_logfile_path;
char *logfile;
gboolean dump_json;
+ gboolean profile_only;
} MonoAotOptions;
typedef enum {
GPtrArray *objc_selectors;
GHashTable *objc_selector_to_index;
GList *profile_data;
+ GHashTable *profile_methods;
FILE *logfile;
FILE *instances_logfile;
FILE *data_outfile;
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");
printf (" stats\n");
printf (" dump\n");
printf (" info\n");
+ printf (" verbose\n");
printf (" help/?\n");
exit (0);
} else {
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
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);
/*
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;
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));
+ }
}
}
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.
*/
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);