@@ -217,7 +217,7 @@ typedef struct MonoAotOptions {
217
217
gboolean use_trampolines_page ;
218
218
gboolean no_instances ;
219
219
// We are collecting inflated methods and emitting non-inflated
220
- gboolean dedup ;
220
+ gboolean dedup_skip ;
221
221
// The name of the assembly for which the AOT module is going to have all deduped methods moved to.
222
222
// When set, we are emitting inflated methods only
223
223
char * dedup_include ;
@@ -295,6 +295,13 @@ typedef struct _UnwindInfoSectionCacheItem {
295
295
} UnwindInfoSectionCacheItem ;
296
296
#endif
297
297
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
+
298
305
typedef struct MonoAotCompile {
299
306
MonoImage * image ;
300
307
GPtrArray * methods ;
@@ -381,7 +388,6 @@ typedef struct MonoAotCompile {
381
388
gboolean llvm ;
382
389
gboolean has_jitted_code ;
383
390
gboolean is_full_aot ;
384
- gboolean dedup_collect_only ;
385
391
MonoAotFileFlags flags ;
386
392
MonoDynamicStream blob ;
387
393
gboolean blob_closed ;
@@ -416,8 +422,8 @@ typedef struct MonoAotCompile {
416
422
FILE * compiled_methods_outfile ;
417
423
int datafile_offset ;
418
424
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 ;
421
427
} MonoAotCompile ;
422
428
423
429
typedef struct {
@@ -519,6 +525,12 @@ mono_aot_mode_is_hybrid (MonoAotOptions *opts)
519
525
return opts -> mode == MONO_AOT_MODE_HYBRID ;
520
526
}
521
527
528
+ static void
529
+ dedup_change_phase (MonoAotCompile * acfg , int next_phase )
530
+ {
531
+ acfg -> dedup_phase = next_phase ;
532
+ }
533
+
522
534
static void
523
535
aot_printf (MonoAotCompile * acfg , const gchar * format , ...)
524
536
{
@@ -4300,6 +4312,21 @@ get_method_index (MonoAotCompile *acfg, MonoMethod *method)
4300
4312
return index - 1 ;
4301
4313
}
4302
4314
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
+
4303
4330
static int
4304
4331
add_method_full (MonoAotCompile * acfg , MonoMethod * method , gboolean extra , int depth )
4305
4332
{
@@ -4389,16 +4416,8 @@ add_extra_method_full (MonoAotCompile *acfg, MonoMethod *method, gboolean prefer
4389
4416
mono_error_assert_ok (error );
4390
4417
}
4391
4418
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 ;
4402
4421
4403
4422
if (acfg -> aot_opts .log_generics )
4404
4423
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
6390
6409
if (callee_cfg ) {
6391
6410
gboolean direct_callable = TRUE;
6392
6411
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 ))
6394
6413
direct_callable = FALSE;
6395
6414
6396
6415
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)
8793
8812
} else if (str_begins_with (arg , "internal-logfile=" )) {
8794
8813
opts -> logfile = g_strdup (arg + strlen ("internal-logfile=" ));
8795
8814
} else if (str_begins_with (arg , "dedup-skip" )) {
8796
- opts -> dedup = TRUE;
8815
+ opts -> dedup_skip = TRUE;
8797
8816
} else if (str_begins_with (arg , "dedup-include=" )) {
8798
8817
opts -> dedup_include = g_strdup (arg + strlen ("dedup-include=" ));
8799
8818
} else if (str_begins_with (arg , "mtriple=" )) {
@@ -14060,6 +14079,7 @@ acfg_create (MonoAssembly *ass, guint32 jit_opts)
14060
14079
acfg -> gshared_instances = g_hash_table_new (NULL , NULL );
14061
14080
acfg -> prefer_instances = g_hash_table_new (NULL , NULL );
14062
14081
acfg -> exported_methods = g_ptr_array_new ();
14082
+ acfg -> dedup_phase = DEDUP_NONE ;
14063
14083
mono_os_mutex_init_recursive (& acfg -> mutex );
14064
14084
14065
14085
init_got_info (& acfg -> got_info );
@@ -14706,15 +14726,20 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
14706
14726
14707
14727
acfg = acfg_create (ass , jit_opts );
14708
14728
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
+ }
14712
14737
14713
14738
if (acfg -> aot_opts .logfile ) {
14714
14739
acfg -> logfile = fopen (acfg -> aot_opts .logfile , "a+" );
14715
14740
}
14716
14741
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 ) {
14718
14743
acfg -> compiled_methods_outfile = fopen (acfg -> aot_opts .compiled_methods_outfile , "w+" );
14719
14744
if (!acfg -> compiled_methods_outfile )
14720
14745
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)
14765
14790
if (acfg -> jit_opts & MONO_OPT_GSHAREDVT )
14766
14791
mono_set_generic_sharing_vt_supported (TRUE);
14767
14792
14768
- if (! acfg -> dedup_collect_only )
14793
+ if (acfg -> dedup_phase != DEDUP_COLLECT )
14769
14794
aot_printf (acfg , "Mono Ahead of Time compiler - compiling assembly %s\n" , image -> name );
14770
14795
14771
14796
if (!acfg -> aot_opts .deterministic )
14772
14797
generate_aotid ((guint8 * ) & acfg -> image -> aotid );
14773
14798
14774
14799
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 )
14776
14801
aot_printf (acfg , "AOTID %s\n" , aotid );
14777
14802
g_free (aotid );
14778
14803
@@ -14878,9 +14903,9 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
14878
14903
if (mini_safepoints_enabled ())
14879
14904
acfg -> flags = (MonoAotFileFlags )(acfg -> flags | MONO_AOT_FILE_FLAG_SAFEPOINTS );
14880
14905
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
14882
14907
// Note: Only one such amodule can have this attribute
14883
- if (ass == dedup_assembly )
14908
+ if (acfg -> dedup_phase == DEDUP_EMIT )
14884
14909
acfg -> flags = (MonoAotFileFlags )(acfg -> flags | MONO_AOT_FILE_FLAG_EAGER_LOAD );
14885
14910
14886
14911
if (acfg -> aot_opts .instances_logfile_path ) {
@@ -14972,16 +14997,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
14972
14997
return 1 ;
14973
14998
}
14974
14999
14975
- if (ass == dedup_assembly ) {
15000
+ if (acfg -> dedup_phase == DEDUP_EMIT ) {
14976
15001
/* Add collected dedup-able methods */
14977
15002
aot_printf (acfg , "Adding %d dedup-ed methods.\n" , g_hash_table_size (dedup_methods ));
14978
15003
14979
15004
GHashTableIter iter ;
14980
15005
MonoMethod * key ;
14981
15006
MonoMethod * method ;
14982
15007
14983
- acfg -> dedup_emit_mode = TRUE;
14984
-
14985
15008
g_hash_table_iter_init (& iter , dedup_methods );
14986
15009
while (g_hash_table_iter_next (& iter , (gpointer * )& key , (gpointer * )& method ))
14987
15010
add_method_full (acfg , method , TRUE, 0 );
@@ -15064,7 +15087,7 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
15064
15087
TV_GETTIME (btv );
15065
15088
15066
15089
acfg -> stats .jit_time = GINT64_TO_INT (TV_ELAPSED (atv , btv ));
15067
- if (acfg -> dedup_collect_only ) {
15090
+ if (acfg -> dedup_phase == DEDUP_COLLECT ) {
15068
15091
/* We only collected methods from this assembly */
15069
15092
acfg_free (acfg );
15070
15093
return 0 ;
0 commit comments