Skip to content

Commit 0a204f5

Browse files
authored
[mono][aot] Enable deduplication of runtime invoke wrappers (#84304)
* Add DedupState enum and remove dedup flags
1 parent 330d46a commit 0a204f5

File tree

2 files changed

+51
-29
lines changed

2 files changed

+51
-29
lines changed

src/mono/mono/mini/aot-compiler.c

+51-28
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ typedef struct MonoAotOptions {
217217
gboolean use_trampolines_page;
218218
gboolean no_instances;
219219
// We are collecting inflated methods and emitting non-inflated
220-
gboolean dedup;
220+
gboolean dedup_skip;
221221
// The name of the assembly for which the AOT module is going to have all deduped methods moved to.
222222
// When set, we are emitting inflated methods only
223223
char *dedup_include;
@@ -295,6 +295,13 @@ typedef struct _UnwindInfoSectionCacheItem {
295295
} UnwindInfoSectionCacheItem;
296296
#endif
297297

298+
typedef enum {
299+
DEDUP_NONE, // dedup is turned off
300+
DEDUP_SKIP, // dedup is on, dedup assembly is not provided
301+
DEDUP_COLLECT, // dedup is on, this assembly is not the dedup image, so just collect the methods
302+
DEDUP_EMIT // dedup is on, this assembly is the dedup image, emit collected methods
303+
} DedupPhase;
304+
298305
typedef struct MonoAotCompile {
299306
MonoImage *image;
300307
GPtrArray *methods;
@@ -381,7 +388,6 @@ typedef struct MonoAotCompile {
381388
gboolean llvm;
382389
gboolean has_jitted_code;
383390
gboolean is_full_aot;
384-
gboolean dedup_collect_only;
385391
MonoAotFileFlags flags;
386392
MonoDynamicStream blob;
387393
gboolean blob_closed;
@@ -416,8 +422,8 @@ typedef struct MonoAotCompile {
416422
FILE *compiled_methods_outfile;
417423
int datafile_offset;
418424
int gc_name_offset;
419-
// In this mode, we are emitting dedupable methods that we encounter
420-
gboolean dedup_emit_mode;
425+
426+
DedupPhase dedup_phase;
421427
} MonoAotCompile;
422428

423429
typedef struct {
@@ -519,6 +525,12 @@ mono_aot_mode_is_hybrid (MonoAotOptions *opts)
519525
return opts->mode == MONO_AOT_MODE_HYBRID;
520526
}
521527

528+
static void
529+
dedup_change_phase (MonoAotCompile *acfg, int next_phase)
530+
{
531+
acfg->dedup_phase = next_phase;
532+
}
533+
522534
static void
523535
aot_printf (MonoAotCompile *acfg, const gchar *format, ...)
524536
{
@@ -4300,6 +4312,21 @@ get_method_index (MonoAotCompile *acfg, MonoMethod *method)
43004312
return index - 1;
43014313
}
43024314

4315+
static gboolean
4316+
collect_dedup_method (MonoAotCompile *acfg, MonoMethod *method)
4317+
{
4318+
// Check if the dedup is enabled, and if the current method can be deduplicated
4319+
if ((acfg->dedup_phase == DEDUP_SKIP || acfg->dedup_phase == DEDUP_COLLECT) && mono_aot_can_dedup (method)) {
4320+
// Remember for later
4321+
if (acfg->dedup_phase == DEDUP_COLLECT && !g_hash_table_lookup (dedup_methods, method))
4322+
g_hash_table_insert (dedup_methods, method, method);
4323+
return TRUE;
4324+
}
4325+
return FALSE;
4326+
}
4327+
4328+
4329+
43034330
static int
43044331
add_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean extra, int depth)
43054332
{
@@ -4389,16 +4416,8 @@ add_extra_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean prefer
43894416
mono_error_assert_ok (error);
43904417
}
43914418

4392-
if ((acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (method)) {
4393-
if (acfg->aot_opts.dedup) {
4394-
/* Don't emit instances */
4395-
return;
4396-
} else if (!acfg->dedup_emit_mode) {
4397-
/* Remember for later */
4398-
if (!g_hash_table_lookup (dedup_methods, method))
4399-
g_hash_table_insert (dedup_methods, method, method);
4400-
}
4401-
}
4419+
if (collect_dedup_method (acfg, method))
4420+
return;
44024421

44034422
if (acfg->aot_opts.log_generics)
44044423
aot_printf (acfg, "%*sAdding method %s.\n", depth, "", mono_method_get_full_name (method));
@@ -6390,7 +6409,7 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc
63906409
if (callee_cfg) {
63916410
gboolean direct_callable = TRUE;
63926411

6393-
if (direct_callable && (acfg->aot_opts.dedup || acfg->aot_opts.dedup_include) && mono_aot_can_dedup (patch_info->data.method))
6412+
if (direct_callable && acfg->dedup_phase != DEDUP_NONE && mono_aot_can_dedup (patch_info->data.method))
63946413
direct_callable = FALSE;
63956414

63966415
if (direct_callable && !acfg->llvm && !(!callee_cfg->has_got_slots && mono_class_is_before_field_init (callee_cfg->method->klass)))
@@ -8793,7 +8812,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
87938812
} else if (str_begins_with (arg, "internal-logfile=")) {
87948813
opts->logfile = g_strdup (arg + strlen ("internal-logfile="));
87958814
} else if (str_begins_with (arg, "dedup-skip")) {
8796-
opts->dedup = TRUE;
8815+
opts->dedup_skip = TRUE;
87978816
} else if (str_begins_with (arg, "dedup-include=")) {
87988817
opts->dedup_include = g_strdup (arg + strlen ("dedup-include="));
87998818
} else if (str_begins_with (arg, "mtriple=")) {
@@ -14060,6 +14079,7 @@ acfg_create (MonoAssembly *ass, guint32 jit_opts)
1406014079
acfg->gshared_instances = g_hash_table_new (NULL, NULL);
1406114080
acfg->prefer_instances = g_hash_table_new (NULL, NULL);
1406214081
acfg->exported_methods = g_ptr_array_new ();
14082+
acfg->dedup_phase = DEDUP_NONE;
1406314083
mono_os_mutex_init_recursive (&acfg->mutex);
1406414084

1406514085
init_got_info (&acfg->got_info);
@@ -14706,15 +14726,20 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1470614726

1470714727
acfg = acfg_create (ass, jit_opts);
1470814728
memcpy (&acfg->aot_opts, aot_options, sizeof (MonoAotOptions));
14709-
14710-
if (acfg->aot_opts.dedup_include && ass != dedup_assembly)
14711-
acfg->dedup_collect_only = TRUE;
14729+
if (acfg->aot_opts.dedup_skip || acfg->aot_opts.dedup_include) {
14730+
if (acfg->aot_opts.dedup_skip)
14731+
dedup_change_phase (acfg, DEDUP_SKIP);
14732+
else if (acfg->aot_opts.dedup_include && ass != dedup_assembly)
14733+
dedup_change_phase (acfg, DEDUP_COLLECT);
14734+
else
14735+
dedup_change_phase (acfg, DEDUP_EMIT);
14736+
}
1471214737

1471314738
if (acfg->aot_opts.logfile) {
1471414739
acfg->logfile = fopen (acfg->aot_opts.logfile, "a+");
1471514740
}
1471614741

14717-
if (acfg->aot_opts.compiled_methods_outfile && !acfg->dedup_collect_only) {
14742+
if (acfg->aot_opts.compiled_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) {
1471814743
acfg->compiled_methods_outfile = fopen (acfg->aot_opts.compiled_methods_outfile, "w+");
1471914744
if (!acfg->compiled_methods_outfile)
1472014745
aot_printerrf (acfg, "Unable to open compiled-methods-outfile specified file %s\n", acfg->aot_opts.compiled_methods_outfile);
@@ -14765,14 +14790,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1476514790
if (acfg->jit_opts & MONO_OPT_GSHAREDVT)
1476614791
mono_set_generic_sharing_vt_supported (TRUE);
1476714792

14768-
if (!acfg->dedup_collect_only)
14793+
if (acfg->dedup_phase != DEDUP_COLLECT)
1476914794
aot_printf (acfg, "Mono Ahead of Time compiler - compiling assembly %s\n", image->name);
1477014795

1477114796
if (!acfg->aot_opts.deterministic)
1477214797
generate_aotid ((guint8*) &acfg->image->aotid);
1477314798

1477414799
char *aotid = mono_guid_to_string (acfg->image->aotid);
14775-
if (!acfg->dedup_collect_only && !acfg->aot_opts.deterministic)
14800+
if (acfg->dedup_phase != DEDUP_COLLECT && !acfg->aot_opts.deterministic)
1477614801
aot_printf (acfg, "AOTID %s\n", aotid);
1477714802
g_free (aotid);
1477814803

@@ -14878,9 +14903,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1487814903
if (mini_safepoints_enabled ())
1487914904
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS);
1488014905

14881-
// The methods in dedup-emit amodules must be available on runtime startup
14906+
// The methods in dedup AOT module must be available on runtime startup
1488214907
// Note: Only one such amodule can have this attribute
14883-
if (ass == dedup_assembly)
14908+
if (acfg->dedup_phase == DEDUP_EMIT)
1488414909
acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_EAGER_LOAD);
1488514910

1488614911
if (acfg->aot_opts.instances_logfile_path) {
@@ -14972,16 +14997,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1497214997
return 1;
1497314998
}
1497414999

14975-
if (ass == dedup_assembly) {
15000+
if (acfg->dedup_phase == DEDUP_EMIT) {
1497615001
/* Add collected dedup-able methods */
1497715002
aot_printf (acfg, "Adding %d dedup-ed methods.\n", g_hash_table_size (dedup_methods));
1497815003

1497915004
GHashTableIter iter;
1498015005
MonoMethod *key;
1498115006
MonoMethod *method;
1498215007

14983-
acfg->dedup_emit_mode = TRUE;
14984-
1498515008
g_hash_table_iter_init (&iter, dedup_methods);
1498615009
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&method))
1498715010
add_method_full (acfg, method, TRUE, 0);
@@ -15064,7 +15087,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1506415087
TV_GETTIME (btv);
1506515088

1506615089
acfg->stats.jit_time = GINT64_TO_INT (TV_ELAPSED (atv, btv));
15067-
if (acfg->dedup_collect_only) {
15090+
if (acfg->dedup_phase == DEDUP_COLLECT) {
1506815091
/* We only collected methods from this assembly */
1506915092
acfg_free (acfg);
1507015093
return 0;

src/mono/mono/mini/aot-runtime.c

-1
Original file line numberDiff line numberDiff line change
@@ -4547,7 +4547,6 @@ mono_aot_can_dedup (MonoMethod *method)
45474547
#else
45484548
return FALSE;
45494549
#endif
4550-
break;
45514550
case MONO_WRAPPER_OTHER: {
45524551
WrapperInfo *info = mono_marshal_get_wrapper_info (method);
45534552

0 commit comments

Comments
 (0)