Skip to content

Commit 997d955

Browse files
committed
[mono][aot] Add a 'compile-in-child' aot argument.
When set, the JIT compilation is done in a child process. This helps to reduce overall memory usage since memory used during JITting is no longer going to be reserved when running external tools like opt/llc.
1 parent 659db01 commit 997d955

File tree

1 file changed

+91
-2
lines changed

1 file changed

+91
-2
lines changed

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

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
518520
static inline const char*
519521
lookup_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+
521526
static gboolean
522527
mono_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+
1557915657
int
1558015658
mono_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

Comments
 (0)