gboolean dwarf_debug;
gboolean soft_debug;
gboolean log_generics;
+ gboolean log_instances;
gboolean direct_pinvoke;
gboolean direct_icalls;
gboolean no_direct_calls;
gboolean autoreg;
char *mtriple;
char *llvm_path;
+ char *instances_logfile_path;
} MonoAotOptions;
typedef struct MonoAotStats {
int objc_selector_index, objc_selector_index_2;
GPtrArray *objc_selectors;
GHashTable *objc_selector_to_index;
+ FILE *instances_logfile;
} MonoAotCompile;
typedef struct {
* 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;
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=")) {
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
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;