diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 5cb0a2ad1888c..82b9698765a32 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -217,7 +217,7 @@ typedef struct MonoAotOptions { gboolean use_trampolines_page; gboolean no_instances; // We are collecting inflated methods and emitting non-inflated - gboolean dedup_skip; + gboolean dedup; // The name of the assembly for which the AOT module is going to have all deduped methods moved to. // When set, we are emitting inflated methods only char *dedup_include; @@ -295,13 +295,6 @@ typedef struct _UnwindInfoSectionCacheItem { } UnwindInfoSectionCacheItem; #endif -typedef enum { - DEDUP_NONE, // dedup is turned off - DEDUP_SKIP, // dedup is on, dedup assembly is not provided - DEDUP_COLLECT, // dedup is on, this assembly is not the dedup image, so just collect the methods - DEDUP_EMIT // dedup is on, this assembly is the dedup image, emit collected methods -} DedupPhase; - typedef struct MonoAotCompile { MonoImage *image; GPtrArray *methods; @@ -388,6 +381,7 @@ typedef struct MonoAotCompile { gboolean llvm; gboolean has_jitted_code; gboolean is_full_aot; + gboolean dedup_collect_only; MonoAotFileFlags flags; MonoDynamicStream blob; gboolean blob_closed; @@ -422,8 +416,8 @@ typedef struct MonoAotCompile { FILE *compiled_methods_outfile; int datafile_offset; int gc_name_offset; - - DedupPhase dedup_phase; + // In this mode, we are emitting dedupable methods that we encounter + gboolean dedup_emit_mode; } MonoAotCompile; typedef struct { @@ -525,12 +519,6 @@ mono_aot_mode_is_hybrid (MonoAotOptions *opts) return opts->mode == MONO_AOT_MODE_HYBRID; } -static void -dedup_change_phase (MonoAotCompile *acfg, int next_phase) -{ - acfg->dedup_phase = next_phase; -} - static void aot_printf (MonoAotCompile *acfg, const gchar *format, ...) { @@ -4312,21 +4300,6 @@ get_method_index (MonoAotCompile *acfg, MonoMethod *method) return index - 1; } -static gboolean -collect_dedup_method (MonoAotCompile *acfg, MonoMethod *method) -{ - // Check if the dedup is enabled, and if the current method can be deduplicated - if ((acfg->dedup_phase == DEDUP_SKIP || acfg->dedup_phase == DEDUP_COLLECT) && mono_aot_can_dedup (method)) { - // Remember for later - if (acfg->dedup_phase == DEDUP_COLLECT && !g_hash_table_lookup (dedup_methods, method)) - g_hash_table_insert (dedup_methods, method, method); - return TRUE; - } - return FALSE; -} - - - static int add_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean extra, int depth) { @@ -4416,8 +4389,16 @@ add_extra_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean prefer mono_error_assert_ok (error); } - if (collect_dedup_method (acfg, method)) - return; + if ((acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (method)) { + if (acfg->aot_opts.dedup) { + /* Don't emit instances */ + return; + } else if (!acfg->dedup_emit_mode) { + /* Remember for later */ + if (!g_hash_table_lookup (dedup_methods, method)) + g_hash_table_insert (dedup_methods, method, method); + } + } if (acfg->aot_opts.log_generics) aot_printf (acfg, "%*sAdding method %s.\n", depth, "", mono_method_get_full_name (method)); @@ -6409,7 +6390,7 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc if (callee_cfg) { gboolean direct_callable = TRUE; - if (direct_callable && acfg->dedup_phase != DEDUP_NONE && mono_aot_can_dedup (patch_info->data.method)) + if (direct_callable && (acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (patch_info->data.method)) direct_callable = FALSE; if (direct_callable && !acfg->llvm && !(!callee_cfg->has_got_slots && mono_class_is_before_field_init (callee_cfg->method->klass))) @@ -8812,7 +8793,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) } else if (str_begins_with (arg, "internal-logfile=")) { opts->logfile = g_strdup (arg + strlen ("internal-logfile=")); } else if (str_begins_with (arg, "dedup-skip")) { - opts->dedup_skip = TRUE; + opts->dedup = TRUE; } else if (str_begins_with (arg, "dedup-include=")) { opts->dedup_include = g_strdup (arg + strlen ("dedup-include=")); } else if (str_begins_with (arg, "mtriple=")) { @@ -14079,7 +14060,6 @@ acfg_create (MonoAssembly *ass, guint32 jit_opts) acfg->gshared_instances = g_hash_table_new (NULL, NULL); acfg->prefer_instances = g_hash_table_new (NULL, NULL); acfg->exported_methods = g_ptr_array_new (); - acfg->dedup_phase = DEDUP_NONE; mono_os_mutex_init_recursive (&acfg->mutex); init_got_info (&acfg->got_info); @@ -14726,20 +14706,15 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) acfg = acfg_create (ass, jit_opts); memcpy (&acfg->aot_opts, aot_options, sizeof (MonoAotOptions)); - if (acfg->aot_opts.dedup_skip || acfg->aot_opts.dedup_include) { - if (acfg->aot_opts.dedup_skip) - dedup_change_phase (acfg, DEDUP_SKIP); - else if (acfg->aot_opts.dedup_include && ass != dedup_assembly) - dedup_change_phase (acfg, DEDUP_COLLECT); - else - dedup_change_phase (acfg, DEDUP_EMIT); - } + + if (acfg->aot_opts.dedup_include && ass != dedup_assembly) + acfg->dedup_collect_only = TRUE; if (acfg->aot_opts.logfile) { acfg->logfile = fopen (acfg->aot_opts.logfile, "a+"); } - if (acfg->aot_opts.compiled_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) { + if (acfg->aot_opts.compiled_methods_outfile && !acfg->dedup_collect_only) { acfg->compiled_methods_outfile = fopen (acfg->aot_opts.compiled_methods_outfile, "w+"); if (!acfg->compiled_methods_outfile) aot_printerrf (acfg, "Unable to open compiled-methods-outfile specified file %s\n", acfg->aot_opts.compiled_methods_outfile); @@ -14790,14 +14765,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) if (acfg->jit_opts & MONO_OPT_GSHAREDVT) mono_set_generic_sharing_vt_supported (TRUE); - if (acfg->dedup_phase != DEDUP_COLLECT) + if (!acfg->dedup_collect_only) aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name); if (!acfg->aot_opts.deterministic) generate_aotid ((guint8*) &acfg->image->aotid); char *aotid = mono_guid_to_string (acfg->image->aotid); - if (acfg->dedup_phase != DEDUP_COLLECT && !acfg->aot_opts.deterministic) + if (!acfg->dedup_collect_only && !acfg->aot_opts.deterministic) aot_printf (acfg, "AOTID %s\n", aotid); g_free (aotid); @@ -14903,9 +14878,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) if (mini_safepoints_enabled ()) acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS); - // The methods in dedup AOT module must be available on runtime startup + // The methods in dedup-emit amodules must be available on runtime startup // Note: Only one such amodule can have this attribute - if (acfg->dedup_phase == DEDUP_EMIT) + if (ass == dedup_assembly) acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_EAGER_LOAD); if (acfg->aot_opts.instances_logfile_path) { @@ -14997,7 +14972,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) return 1; } - if (acfg->dedup_phase == DEDUP_EMIT) { + if (ass == dedup_assembly) { /* Add collected dedup-able methods */ aot_printf (acfg, "Adding %d dedup-ed methods.\n", g_hash_table_size (dedup_methods)); @@ -15005,6 +14980,8 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) MonoMethod *key; MonoMethod *method; + acfg->dedup_emit_mode = TRUE; + g_hash_table_iter_init (&iter, dedup_methods); while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&method)) add_method_full (acfg, method, TRUE, 0); @@ -15087,7 +15064,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options) TV_GETTIME (btv); acfg->stats.jit_time = GINT64_TO_INT (TV_ELAPSED (atv, btv)); - if (acfg->dedup_phase == DEDUP_COLLECT) { + if (acfg->dedup_collect_only) { /* We only collected methods from this assembly */ acfg_free (acfg); return 0; diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index fa11dc8ed57d4..84b032829be53 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -4547,6 +4547,7 @@ mono_aot_can_dedup (MonoMethod *method) #else return FALSE; #endif + break; case MONO_WRAPPER_OTHER: { WrapperInfo *info = mono_marshal_get_wrapper_info (method);