@@ -238,6 +238,8 @@ typedef struct MonoAotOptions {
238238 gboolean verbose ;
239239 gboolean deterministic ;
240240 gboolean allow_errors ;
241+ gboolean driver ;
242+ gboolean child ;
241243 char * tool_prefix ;
242244 char * as_prefix ;
243245 char * ld_flags ;
@@ -518,6 +520,9 @@ is_direct_pinvoke_specified_for_method (MonoAotCompile *acfg, MonoMethod *method
518520static inline const char *
519521lookup_direct_pinvoke_symbol_name_aot (MonoAotCompile * acfg , MonoMethod * method );
520522
523+ static int
524+ compile_assemblies_in_child (MonoAssembly * * assemblies , int nassemblies , GPtrArray * runtime_args , const char * aot_options );
525+
521526static gboolean
522527mono_aot_mode_is_full (MonoAotOptions * opts )
523528{
@@ -9080,6 +9085,10 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
90809085 // direct pinvokes (managed-to-native wrappers) and fallbacks to JIT for majority of managed methods.
90819086 } else if (str_begins_with (arg , "wrappers-only" )) {
90829087 opts -> wrappers_only = TRUE;
9088+ } else if (!strcmp (arg , "compile-in-child" )) {
9089+ opts -> driver = TRUE;
9090+ } else if (!strcmp (arg , "_child" )) {
9091+ opts -> child = TRUE;
90839092 } else if (str_begins_with (arg , "help" ) || str_begins_with (arg , "?" )) {
90849093 printf ("Supported options for --aot:\n" );
90859094 printf (" asmonly - \n" );
@@ -9130,6 +9139,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
91309139 printf (" verbose - \n" );
91319140 printf (" allow-errors - \n" );
91329141 printf (" no-opt - \n" );
9142+ printf (" compile-in-child - \n" );
91339143 printf (" llvmopts=<value> - \n" );
91349144 printf (" llvmllc=<value> - \n" );
91359145 printf (" clangxx=<value> - \n" );
@@ -14887,14 +14897,14 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1488714897 if (acfg -> jit_opts & MONO_OPT_GSHAREDVT )
1488814898 mono_set_generic_sharing_vt_supported (TRUE);
1488914899
14890- if (acfg -> dedup_phase != DEDUP_COLLECT )
14900+ if (acfg -> dedup_phase != DEDUP_COLLECT && ! acfg -> aot_opts . child )
1489114901 aot_printf (acfg , "Mono Ahead of Time compiler - compiling assembly %s\n" , image -> name );
1489214902
1489314903 if (!acfg -> aot_opts .deterministic )
1489414904 generate_aotid ((guint8 * ) & acfg -> image -> aotid );
1489514905
1489614906 char * aotid = mono_guid_to_string (acfg -> image -> aotid );
14897- if (acfg -> dedup_phase != DEDUP_COLLECT && !acfg -> aot_opts .deterministic )
14907+ if (acfg -> dedup_phase != DEDUP_COLLECT && !acfg -> aot_opts .deterministic && ! acfg -> aot_opts . child )
1489814908 aot_printf (acfg , "AOTID %s\n" , aotid );
1489914909 g_free (aotid );
1490014910
@@ -15086,6 +15096,15 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
1508615096 acfg -> llvm_eh_frame_symbol = g_strdup_printf ("%s_eh_frame" , acfg -> global_prefix );
1508715097 }
1508815098
15099+ if (acfg -> aot_opts .driver ) {
15100+ /* Run the compilation part in a child process */
15101+ res = compile_assemblies_in_child (& acfg -> image -> assembly , 1 , acfg -> aot_opts .runtime_args , acfg -> aot_opts .aot_options );
15102+ if (res )
15103+ return res ;
15104+
15105+ return assemble_link (acfg );
15106+ }
15107+
1508915108 acfg -> method_index = 1 ;
1509015109
1509115110 if (mono_aot_mode_is_full (& acfg -> aot_opts ) || mono_aot_mode_is_hybrid (& acfg -> aot_opts ))
@@ -15556,6 +15575,10 @@ emit_aot_image (MonoAotCompile *acfg)
1555615575 if (acfg -> aot_opts .dump_json )
1555715576 aot_dump (acfg );
1555815577
15578+ if (acfg -> aot_opts .child )
15579+ /* The rest is done in the parent */
15580+ return 0 ;
15581+
1555915582 res = assemble_link (acfg );
1556015583 if (res )
1556115584 return res ;
@@ -15576,6 +15599,61 @@ emit_aot_image (MonoAotCompile *acfg)
1557615599 return 0 ;
1557715600}
1557815601
15602+ static int
15603+ compile_assemblies_in_child (MonoAssembly * * assemblies , int nassemblies , GPtrArray * runtime_args , const char * aot_options )
15604+ {
15605+ /* Find --aot argument */
15606+ int aot_index = -1 ;
15607+ for (guint32 i = 1 ; i < runtime_args -> len ; ++ i ) {
15608+ const char * arg = (const char * )g_ptr_array_index (runtime_args , i );
15609+ if (strncmp (arg , "--aot=" , strlen ("--aot=" )) == 0 ) {
15610+ aot_index = i ;
15611+ break ;
15612+ }
15613+ }
15614+ g_assert (aot_index != -1 );
15615+
15616+ GString * command ;
15617+
15618+ command = g_string_new ("" );
15619+
15620+ g_string_append_printf (command , "%s" , (const char * )g_ptr_array_index (runtime_args , 0 ));
15621+
15622+ for (guint32 i = 1 ; i < runtime_args -> len ; ++ i ) {
15623+ const char * arg = (const char * )g_ptr_array_index (runtime_args , i );
15624+ if (strncmp (arg , "--response=" , strlen ("--response=" )) == 0 )
15625+ /* Already expanded */
15626+ continue ;
15627+ if (i != aot_index )
15628+ g_string_append_printf (command , " %s" , arg );
15629+ }
15630+
15631+ /* Pass '_child' instead of 'compile-in-child' */
15632+ GPtrArray * aot_split_args = mono_aot_split_options (aot_options );
15633+ GString * new_aot_args = g_string_new ("" );
15634+ for (guint32 i = 0 ; i < aot_split_args -> len ; ++ i ) {
15635+ const char * aot_arg = (const char * )g_ptr_array_index (aot_split_args , i );
15636+ if (i > 0 )
15637+ g_string_append_printf (new_aot_args , "," );
15638+ if (!strcmp (aot_arg , "compile-in-child" ))
15639+ g_string_append_printf (new_aot_args , "%s" , "_child" );
15640+ else
15641+ g_string_append_printf (new_aot_args , "%s" , aot_arg );
15642+ }
15643+
15644+ g_string_append_printf (command , " --aot=%s" , g_string_free (new_aot_args , FALSE));
15645+
15646+ for (int i = 0 ; i < nassemblies ; ++ i )
15647+ g_string_append_printf (command , " %s" , assemblies [i ]-> image -> name );
15648+
15649+ char * cmd = g_string_free (command , FALSE);
15650+ printf ("Executing: %s\n" , cmd );
15651+ int res = execute_system (cmd );
15652+ g_free (cmd );
15653+
15654+ return res ;
15655+ }
15656+
1557915657int
1558015658mono_aot_assemblies (MonoAssembly * * assemblies , int nassemblies , guint32 jit_opts , GPtrArray * runtime_args , const char * aot_options )
1558115659{
@@ -15598,6 +15676,17 @@ mono_aot_assemblies (MonoAssembly **assemblies, int nassemblies, guint32 jit_opt
1559815676 goto early_exit ;
1559915677 }
1560015678
15679+ if (aot_opts .driver ) {
15680+ if (aot_opts .temp_path [0 ] == '\0' ) {
15681+ fprintf (stderr , "The 'compile-in-child' option requires the 'temp-path=' option.\n" );
15682+ res = 1 ;
15683+ goto early_exit ;
15684+ }
15685+ // FIXME:
15686+ if (nassemblies > 1 )
15687+ aot_opts .driver = FALSE;
15688+ }
15689+
1560115690 if (aot_opts .dedup_include ) {
1560215691 /* Find the assembly which will contain the dedup-ed code */
1560315692 int dedup_aindex = -1 ;
0 commit comments