Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WASM] Add ILStrip task to wasm app build process #88926

Merged
merged 21 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/workflow/building/mono/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ For `build.sh`

`/p:DisableCrossgen=true` - Skips building the installer if you don't need it (builds faster)

`-p:KeepNativeSymbols=true` - Keep the symbols in the binary instead of stripping them out to a separate file. This helps with debugging Mono with lldb.
`/p:KeepNativeSymbols=true` - Keep the symbols in the binary instead of stripping them out to a separate file. This helps with debugging Mono with lldb.

The build has a number of options that you can learn about using build -?.

Expand Down
7 changes: 7 additions & 0 deletions src/libraries/tests.proj
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,13 @@
<ProjectExclusions Include="$(MSBuildThisFileDirectory)System.Net.WebSockets.Client\tests\System.Net.WebSockets.Client.Tests.csproj" />
</ItemGroup>

<!-- Test WASM with WASMStripIL enabled -->
<ItemGroup Condition="'$(TargetOS)' == 'browser' and '$(RunAOTCompilation)' == 'true'">
<SmokeTestProject Include="$(RepoRoot)\src\tests\FunctionalTests\WebAssembly\Browser\StartupHook\WebAssembly.Browser.StartupHook.Test.csproj"
AdditionalProperties="%(AdditionalProperties);WASMStripIL=true;TestProjectName=WebAssembly_Browser_StartupHook_Test_ILStripped"
BuildInParallel="false" />
</ItemGroup>

<!-- Aggressive Trimming related failures -->
<ItemGroup Condition="('$(TargetOS)' != 'browser' and '$(RunAOTCompilation)' == 'true' and '$(MonoForceInterpreter)' != 'true') or ('$(TargetOS)' == 'browser' and '$(BuildAOTTestsOnHelix)' == 'true' and '$(RunDisabledWasmTests)' != 'true')">
</ItemGroup>
Expand Down
36 changes: 18 additions & 18 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ typedef struct MonoAotOptions {
char *llvm_outfile;
char *data_outfile;
char *export_symbols_outfile;
char *compiled_methods_outfile;
char *trimming_eligible_methods_outfile;
GList *profile_files;
GList *mibc_profile_files;
gboolean save_temps;
Expand Down Expand Up @@ -420,7 +420,7 @@ typedef struct MonoAotCompile {
FILE *logfile;
FILE *instances_logfile;
FILE *data_outfile;
FILE *compiled_methods_outfile;
FILE *trimming_eligible_methods_outfile;
int datafile_offset;
int gc_name_offset;

Expand Down Expand Up @@ -8804,8 +8804,8 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
opts->llvm_outfile = g_strdup (arg + strlen ("llvm-outfile="));
} else if (str_begins_with (arg, "export-symbols-outfile=")) {
opts->export_symbols_outfile = g_strdup (arg + strlen ("export-symbols-outfile="));
} else if (str_begins_with (arg, "compiled-methods-outfile=")) {
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
opts->compiled_methods_outfile = g_strdup (arg + strlen ("compiled-methods-outfile="));
} else if (str_begins_with (arg, "trimming-eligible-methods-outfile=")) {
opts->trimming_eligible_methods_outfile = g_strdup (arg + strlen ("trimming-eligible-methods-outfile="));
} else if (str_begins_with (arg, "temp-path=")) {
opts->temp_path = clean_path (g_strdup (arg + strlen ("temp-path=")));
} else if (str_begins_with (arg, "save-temps")) {
Expand Down Expand Up @@ -9864,9 +9864,9 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)

mono_atomic_inc_i32 (&acfg->stats.ccount);

if (acfg->aot_opts.compiled_methods_outfile && acfg->compiled_methods_outfile != NULL) {
if (!mono_method_is_generic_impl (method) && method->token != 0) {
fprintf (acfg->compiled_methods_outfile, "%x\n", method->token);
if (acfg->aot_opts.trimming_eligible_methods_outfile && acfg->trimming_eligible_methods_outfile != NULL) {
if (!mono_method_is_generic_impl (method) && method->token != 0 && !cfg->deopt && !cfg->interp_entry_only && mini_get_interp_callbacks ()->jit_call_can_be_supported (method, mono_method_signature_internal (method))) {
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
fprintf (acfg->trimming_eligible_methods_outfile, "%x\n", method->token);
}
}
}
Expand Down Expand Up @@ -14884,13 +14884,13 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
acfg->logfile = fopen (acfg->aot_opts.logfile, "a+");
}

if (acfg->aot_opts.compiled_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) {
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);
if (acfg->aot_opts.trimming_eligible_methods_outfile && acfg->dedup_phase != DEDUP_COLLECT) {
acfg->trimming_eligible_methods_outfile = fopen (acfg->aot_opts.trimming_eligible_methods_outfile, "w+");
if (!acfg->trimming_eligible_methods_outfile)
aot_printerrf (acfg, "Unable to open trimming-eligible-methods-outfile specified file %s\n", acfg->aot_opts.trimming_eligible_methods_outfile);
else {
fprintf(acfg->compiled_methods_outfile, "%s\n", ass->image->filename);
fprintf(acfg->compiled_methods_outfile, "%s\n", ass->image->guid);
fprintf(acfg->trimming_eligible_methods_outfile, "%s\n", ass->image->filename);
fprintf(acfg->trimming_eligible_methods_outfile, "%s\n", ass->image->guid);
}
}

Expand Down Expand Up @@ -15244,8 +15244,8 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)

current_acfg = NULL;

if (acfg->compiled_methods_outfile) {
fclose (acfg->compiled_methods_outfile);
if (acfg->trimming_eligible_methods_outfile) {
fclose (acfg->trimming_eligible_methods_outfile);
}

return emit_aot_image (acfg);
Expand Down Expand Up @@ -15623,9 +15623,9 @@ mono_aot_assemblies (MonoAssembly **assemblies, int nassemblies, guint32 jit_opt
dedup_methods = g_hash_table_new (NULL, NULL);
}

if (aot_opts.compiled_methods_outfile) {
if (g_ensure_directory_exists (aot_opts.compiled_methods_outfile) == FALSE) {
fprintf (stderr, "AOT : failed to create the directory to save the compiled method names: %s\n", aot_opts.compiled_methods_outfile);
if (aot_opts.trimming_eligible_methods_outfile) {
if (g_ensure_directory_exists (aot_opts.trimming_eligible_methods_outfile) == FALSE) {
fprintf (stderr, "AOT : failed to create the directory to save the compiled method names: %s\n", aot_opts.trimming_eligible_methods_outfile);
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
exit (1);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ typedef gpointer MonoInterpFrameHandle;
MONO_EE_CALLBACK (void, entry_llvmonly, (gpointer res, gpointer *args, gpointer imethod)) \
MONO_EE_CALLBACK (gpointer, get_interp_method, (MonoMethod *method)) \
MONO_EE_CALLBACK (MonoJitInfo*, compile_interp_method, (MonoMethod *method, MonoError *error)) \
MONO_EE_CALLBACK (gboolean, jit_call_can_be_supported, (MonoMethod *method, MonoMethodSignature *sig)) \

typedef struct _MonoEECallbacks {

Expand Down
6 changes: 6 additions & 0 deletions src/mono/mono/mini/interp-stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ stub_compile_interp_method (MonoMethod *method, MonoError *error)
return NULL;
}

static gboolean
stub_jit_call_can_be_supported (MonoMethod *method, MonoMethodSignature *sig)
{
return TRUE;
}

#undef MONO_EE_CALLBACK
#define MONO_EE_CALLBACK(ret, name, sig) stub_ ## name,

Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/interp/interp-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ mono_mint_type (MonoType *type);
int
mono_interp_type_size (MonoType *type, int mt, int *align_p);

gboolean
interp_jit_call_can_be_supported (MonoMethod *method, MonoMethodSignature *sig);

#if HOST_BROWSER

gboolean
Expand Down
59 changes: 58 additions & 1 deletion src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4081,7 +4081,39 @@ mono_interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClause
}
ip += 5;

goto call;
InterpMethodCodeType code_type = cmethod->code_type;

g_assert (code_type == IMETHOD_CODE_UNKNOWN ||
code_type == IMETHOD_CODE_INTERP ||
code_type == IMETHOD_CODE_COMPILED);

if (G_UNLIKELY (code_type == IMETHOD_CODE_UNKNOWN)) {
// FIXME push/pop LMF
MonoMethodSignature *sig = mono_method_signature_internal (cmethod->method);
if (mono_interp_jit_call_supported (cmethod->method, sig))
code_type = IMETHOD_CODE_COMPILED;
else
code_type = IMETHOD_CODE_INTERP;
cmethod->code_type = code_type;
}

if (code_type == IMETHOD_CODE_INTERP) {

goto call;

} else if (code_type == IMETHOD_CODE_COMPILED) {
frame->state.ip = ip;
error_init_reuse (error);
do_jit_call (context, (stackval*)(locals + return_offset), (stackval*)(locals + call_args_offset), frame, cmethod, error);
if (!is_ok (error)) {
MonoException *call_ex = interp_error_convert_to_exception (frame, error, ip);
THROW_EX (call_ex, ip);
}

CHECK_RESUME_STATE (context);
}

MINT_IN_BREAK;
}
MINT_IN_CASE(MINT_CALLI) {
gboolean need_unbox;
Expand Down Expand Up @@ -8595,6 +8627,31 @@ interp_sufficient_stack (gsize size)
return (context->stack_pointer + size) < (context->stack_start + INTERP_STACK_SIZE);
}

gboolean
interp_jit_call_can_be_supported (MonoMethod *method, MonoMethodSignature *sig)
{
if (sig->param_count > 10)
return FALSE;
if (sig->pinvoke)
return FALSE;
if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
return FALSE;
if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
return FALSE;
if (!mono_llvm_only && method->is_inflated)
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
return FALSE;
if (method->string_ctor)
return FALSE;
if (method->wrapper_type != MONO_WRAPPER_NONE)
return FALSE;

if (method->flags & METHOD_ATTRIBUTE_REQSECOBJ)
/* Used to mark methods containing StackCrawlMark locals */
return FALSE;

return TRUE;
}

static void
interp_cleanup (void)
{
Expand Down
22 changes: 5 additions & 17 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1213,23 +1213,7 @@ mono_interp_jit_call_supported (MonoMethod *method, MonoMethodSignature *sig)
{
GSList *l;

if (sig->param_count > 10)
return FALSE;
if (sig->pinvoke)
return FALSE;
if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
return FALSE;
if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)
return FALSE;
if (!mono_llvm_only && method->is_inflated)
return FALSE;
if (method->string_ctor)
return FALSE;
if (method->wrapper_type != MONO_WRAPPER_NONE)
return FALSE;

if (method->flags & METHOD_ATTRIBUTE_REQSECOBJ)
/* Used to mark methods containing StackCrawlMark locals */
if (!interp_jit_call_can_be_supported (method, sig))
return FALSE;

if (mono_aot_only && m_class_get_image (method->klass)->aot_module && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
Expand Down Expand Up @@ -2991,6 +2975,10 @@ interp_inline_method (TransformData *td, MonoMethod *target_method, MonoMethodHe
int nargs = csignature->param_count + !!csignature->hasthis;
InterpInst *prev_last_ins;

if (header->code_size == 0)
/* IL stripped */
return FALSE;

lambdageek marked this conversation as resolved.
Show resolved Hide resolved
if (csignature->is_inflated)
generic_context = mono_method_get_context (target_method);
else {
Expand Down
4 changes: 2 additions & 2 deletions src/mono/sample/HelloWorld/HelloWorld.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
LibraryFormat="$(_AotLibraryFormat)"
Assemblies="@(AotInputAssemblies)"
OutputDir="$(PublishDir)"
CollectCompiledMethods="$(StripILCode)"
CompiledMethodsOutputDirectory="$(CompiledMethodsOutputDirectory)"
CollectTrimmingEligibleMethods="$(StripILCode)"
TrimmingEligibleMethodsOutputDirectory="$(TrimmingEligibleMethodsOutputDirectory)"
IntermediateOutputPath="$(IntermediateOutputPath)"
UseAotDataFile="$(UseAotDataFile)"
MibcProfilePath="$(MibcProfilePath)"
Expand Down
4 changes: 2 additions & 2 deletions src/mono/sample/HelloWorld/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ TARGET_OS?=$(shell . $(TOP)eng/native/init-os-and-arch.sh && echo $${os})
AOT?=false
USE_LLVM?=false
StripILCode?=false
CompiledMethodsOutputDirectory?= #<path-to-a-writable-directory>
TrimmingEligibleMethodsOutputDirectory?= #<path-to-a-writable-directory>

#MIBC_PROFILE_PATH=<path-to-mibc-for-sample>

Expand All @@ -21,7 +21,7 @@ publish:
/p:RunAOTCompilation=$(AOT) \
/p:MonoEnableLLVM=$(USE_LLVM) \
/p:StripILCode=$(StripILCode) \
/p:CompiledMethodsOutputDirectory=$(CompiledMethodsOutputDirectory) \
/p:TrimmingEligibleMethodsOutputDirectory=$(TrimmingEligibleMethodsOutputDirectory) \
'/p:MibcProfilePath="$(MIBC_PROFILE_PATH)"' \
/bl

Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/build/WasmApp.InTree.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project>
<!-- This depends on the root Directory.Build.targets imported this file -->
<UsingTask TaskName="MonoAOTCompiler" AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" />
<UsingTask TaskName="ILStrip" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
<UsingTask TaskName="RuntimeConfigParserTask" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />

<!-- TODO: this breaks runtime tests on Helix due to the file not being there for some reason. Once this is fixed we can remove the UpdateRuntimePack target here -->
Expand Down
13 changes: 13 additions & 0 deletions src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -685,12 +685,25 @@
CacheFilePath="$(_AOTCompilerCacheFile)"
LLVMDebug="dwarfdebug"
LLVMPath="$(EmscriptenUpstreamBinPath)"
CollectTrimmingEligibleMethods="$(WASMStripIL)"
TrimmingEligibleMethodsOutputDirectory="$(_WasmIntermediateOutputPath)tokens"
IntermediateOutputPath="$(_WasmIntermediateOutputPath)"
AotProfilePath="@(AotProfilePath)">

<Output TaskParameter="CompiledAssemblies" ItemName="_WasmAssembliesInternal" />
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
</MonoAOTCompiler>
<ILStrip
Condition=" '$(WASMStripIL)' == 'true' "
TrimIndividualMethods="true"
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
Assemblies="@(_WasmAssembliesInternal)">
<Output TaskParameter="TrimmedAssemblies" ItemName="_ILStripTrimmedAssemblies" />
</ILStrip>
<Move
Condition=" '$(WASMStripIL)' == 'true' "
SourceFiles="@(_ILStripTrimmedAssemblies->'%(TrimmedAssemblyFileName)')"
DestinationFiles="@(_ILStripTrimmedAssemblies)"
/>

<ItemGroup>
<_BitcodeFile Include="%(_WasmAssembliesInternal.LlvmBitcodeFile)" />
Expand Down
5 changes: 5 additions & 0 deletions src/mono/wasm/build/WasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
- AppBundle directly contains user files
- AppBundle/_framework contains generated files (dlls, runtime scripts, icu)
- AppBundle/_content contains web files from nuget packages (css, js, etc)
- $(WASMStripIL) - Set to true to enable trimming away AOT compiled methods body (IL code)
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
fanyang-mono marked this conversation as resolved.
Show resolved Hide resolved
Defaults to false.

Public items:
- @(WasmExtraFilesToDeploy) - Files to copy to $(WasmAppDir).
Expand Down Expand Up @@ -146,6 +148,9 @@
<WasmAssemblyExtension Condition="'$(WasmEnableWebcil)' == 'true'">.wasm</WasmAssemblyExtension>
<WasmAssemblyExtension Condition="'$(WasmEnableWebcil)' != 'true'">.dll</WasmAssemblyExtension>

<!-- by default, method body IL code trimming is disabled -->
<WASMStripIL Condition="'$(WASMStripIL)' == ''">false</WASMStripIL>

<WasmRuntimeAssetsLocation Condition="'$(WasmRuntimeAssetsLocation)' == ''">_framework</WasmRuntimeAssetsLocation>
</PropertyGroup>

Expand Down
Loading
Loading