Skip to content

Commit

Permalink
[wasm] Fix regressed file sizes for blazor (#92664)
Browse files Browse the repository at this point in the history
* [wasm] Add getter for __indirect_function_table

.. so that can work even if it gets renamed during minimization.

* [wasm] build: Revert to older behavior for WasmNativeStrip

The earlier change was done in 678fd6a,
which changed to pass `-g` to the link step also. But that resulted in
increased native file sizes.

Changed sizes for the `minimum blazor template - publish` scenario:

```
                                                          | Last rc1 run     | With the change
----------------------------------------------------------|----------------- |------------------
SOD - Minimum Blazor Template - Publish                   |8590723.000 bytes |7889806.000 bytes
Total Uncompressed _framework                             |4304274.000 bytes |4202273.000 bytes
pub/wwwroot/_framework/dotnet.js                          |35722.000 bytes   |35838.000 bytes
pub/wwwroot/_framework/dotnet.native.8.0.0-VERSION.js     |239307.000 bytes  |134566.000 bytes
pub/wwwroot/_framework/dotnet.native.wasm                 |1174394.000 bytes |1148841.000 bytes
pub/wwwroot/_framework/dotnet.runtime.8.0.0-VERSION.js    |221356.000 bytes  |221712.000 bytes
```

(cherry picked from commit ae93e81)

* [wasm] cleanup corresponding tests

(cherry picked from commit 0207d60)

* [wasm] Remove WasmNativeStrip from wasm.proj as it will have no effect

(cherry picked from commit 91379dd)

* disable non-wasm perf builds

* address feedback from Katelyn Gadd

* address review feedback

* remove debug bits

* Revert "address review feedback"

This reverts commit 68e954d.

This caused tests to fail with:
```
fail: [out of order message from the browser]: http://127.0.0.1:36071/_framework/dotnet.runtime.js 2:12344 "MONO_WASM: onRuntimeInitializedAsync() failed" TypeError: t.getWasmIndirectFunctionTable is not a function
          at br (http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:55253)
          at zr (http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:60544)
          at http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:214955
fail: [out of order message from the browser]: http://127.0.0.1:36071/_framework/dotnet.js 2:917 "MONO_WASM: TypeError: t.getWasmIndirectFunctionTable is not a function\n    at br (http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:55253)\n    at zr (http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:60544)\n    at http://127.0.0.1:36071/_framework/dotnet.runtime.js:3:214955"
```

* lifting emscripten internals

* Update src/mono/wasm/runtime/jiterpreter-support.ts

* Update src/mono/wasm/runtime/jiterpreter-support.ts

* track changes

* Fix build

* workload-testing.targets: fix shared framework install when dotnet-none is already installed

* import ENVIRONMENT_IS_NODE

* fix build

---------

Co-authored-by: pavelsavara <pavel.savara@gmail.com>
Co-authored-by: Larry Ewing <lewing@microsoft.com>
  • Loading branch information
3 people committed Dec 6, 2023
1 parent 42255ea commit ec31705
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 84 deletions.
107 changes: 64 additions & 43 deletions src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using Xunit;
using Xunit.Abstractions;

Expand All @@ -12,6 +13,7 @@ namespace Wasm.Build.Tests
{
public class WasmNativeDefaultsTests : TestMainJsTestBase
{
private static Regex s_regex = new("\\*\\* WasmBuildNative:.*");
public WasmNativeDefaultsTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
: base(output, buildContext)
{
Expand Down Expand Up @@ -39,19 +41,20 @@ public static TheoryData<string, string, bool, bool, bool> SettingDifferentFromV
// Config=Release always causes relinking when publishing
bool publishValue = forPublish && config == "Release" ? true : false;
// Setting the default value from the runtime pack shouldn't trigger relinking
data.Add(config, $"<{defaultPair.propertyName}>{defaultPair.defaultValueInRuntimePack}</{defaultPair.propertyName}>",
data.Add(config, $"<{defaultPair.propertyName}>{defaultPair.defaultValueInRuntimePack.ToString().ToLower()}</{defaultPair.propertyName}>",
/*aot*/ false, /*build*/ false, /*publish*/ publishValue);
// Leaving the property unset, so checking the default
data.Add(config, "", /*aot*/ false, /*build*/ false, /*publish*/ publishValue);

// Setting the !default value should trigger relinking
data.Add(config, $"<{defaultPair.propertyName}>{!defaultPair.defaultValueInRuntimePack}</{defaultPair.propertyName}>",
data.Add(config, $"<{defaultPair.propertyName}>{(!defaultPair.defaultValueInRuntimePack).ToString().ToLower()}</{defaultPair.propertyName}>",
/*aot*/ false, /*build*/ true, /*publish*/ true);
}
}

return data;
}

public static TheoryData<string, string, bool, bool, bool> DefaultsTestData(bool forPublish)
{
TheoryData<string, string, bool, bool, bool> data = new()
Expand Down Expand Up @@ -93,45 +96,34 @@ public static TheoryData<string, string, bool, bool, bool> DefaultsTestData(bool
return data;
}

#pragma warning disable xUnit1026 // For unused *buildValue*, and *publishValue* parameters
[Theory]
[MemberData(nameof(DefaultsTestData), parameters: false)]
[MemberData(nameof(SettingDifferentFromValuesInRuntimePack), parameters: false)]
public void DefaultsWithBuild(string config, string extraProperties, bool aot, bool expectWasmBuildNativeForBuild, bool expectWasmBuildNativeForPublish)
{
string output = CheckWasmNativeDefaultValue("native_defaults_build", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: false);

bool expectedWasmNativeStripValue = true;
if (/*isBuild && */ expectWasmBuildNativeForBuild && config == "Debug")
expectedWasmNativeStripValue = false;
(string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_build", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForBuild, publish: false);

// bool expectedWasmNativeStripValue = !(wasmBuildNativeForBuild && config == "Debug");
// for build
Assert.Contains($"** WasmBuildNative: '{expectWasmBuildNativeForBuild.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output);
Assert.Contains("Stopping the build", output);
InferAndCheckPropertyValues(line, isPublish: false, wasmBuildNative: expectWasmBuildNativeForBuild, config: config);
}

#pragma warning disable xUnit1026 // For unused *buildValue* parameter
[Theory]
[MemberData(nameof(DefaultsTestData), parameters: true)]
[MemberData(nameof(SettingDifferentFromValuesInRuntimePack), parameters: true)]
public void DefaultsWithPublish(string config, string extraProperties, bool aot, bool expectWasmBuildNativeForBuild, bool expectWasmBuildNativeForPublish)
{
string output = CheckWasmNativeDefaultValue("native_defaults_publish", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: true);
(string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_publish", config, extraProperties, aot, dotnetWasmFromRuntimePack: !expectWasmBuildNativeForPublish, publish: true);

// for build
// Assert.DoesNotContain($"** WasmBuildNative: '{buildValue.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: ''", output);
// for publish
Assert.Contains($"** WasmBuildNative: '{expectWasmBuildNativeForPublish.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: 'true'", output);
Assert.Contains("Stopping the build", output);
InferAndCheckPropertyValues(line, isPublish: true, wasmBuildNative: expectWasmBuildNativeForPublish, config: config);
}
#pragma warning restore xunit1026

public static TheoryData<string, string, bool, bool> SetWasmNativeStripExplicitlyTestData(bool publish) => new()
{
{"Debug", "<WasmNativeStrip>true</WasmNativeStrip>", false, true },
{"Release", "<WasmNativeStrip>true</WasmNativeStrip>", publish, true },
{"Debug", "<WasmNativeStrip>false</WasmNativeStrip>", true, false },
{"Release", "<WasmNativeStrip>false</WasmNativeStrip>", true, false }
{"Debug", "<WasmNativeStrip>true</WasmNativeStrip>", /*wasmBuildNative*/ false, /*wasmNativeStrip*/ true },
{"Release", "<WasmNativeStrip>true</WasmNativeStrip>", /*wasmBuildNative*/ publish, /*wasmNativeStrip*/ true },
{"Debug", "<WasmNativeStrip>false</WasmNativeStrip>", /*wasmBuildNative*/ true, /*wasmNativeStrip*/ false },
{"Release", "<WasmNativeStrip>false</WasmNativeStrip>", /*wasmBuildNative*/ true, /*wasmNativeStrip*/ false }
};

public static TheoryData<string, string, bool, bool> SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData() => new()
Expand All @@ -147,48 +139,52 @@ public void DefaultsWithPublish(string config, string extraProperties, bool aot,
[MemberData(nameof(SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData))]
public void WasmNativeStripDefaultWithBuild(string config, string extraProperties, bool expectedWasmBuildNativeValue, bool expectedWasmNativeStripValue)
{
string output = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: false);
(string output, string? line) = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: false);

Assert.Contains($"** WasmBuildNative: '{expectedWasmBuildNativeValue.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output);
Assert.Contains("Stopping the build", output);
CheckPropertyValues(line,
wasmBuildNative: expectedWasmBuildNativeValue,
wasmNativeStrip: expectedWasmNativeStripValue,
wasmNativeDebugSymbols: true,
wasmBuildingForNestedPublish: null);
}

[Theory]
[MemberData(nameof(SetWasmNativeStripExplicitlyTestData), parameters: /*publish*/ true)]
[MemberData(nameof(SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData))]
public void WasmNativeStripDefaultWithPublish(string config, string extraProperties, bool expectedWasmBuildNativeValue, bool expectedWasmNativeStripValue)
{
string output = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: true);
(string output, string? line) = CheckWasmNativeDefaultValue("native_strip_defaults", config, extraProperties, aot: false, dotnetWasmFromRuntimePack: !expectedWasmBuildNativeValue, publish: true);

Assert.Contains($"** WasmBuildNative: '{expectedWasmBuildNativeValue.ToString().ToLower()}', WasmNativeStrip: '{expectedWasmNativeStripValue.ToString().ToLower()}', WasmBuildingForNestedPublish: 'true'", output);
Assert.Contains("Stopping the build", output);
CheckPropertyValues(line,
wasmBuildNative: expectedWasmBuildNativeValue,
wasmNativeStrip: expectedWasmNativeStripValue,
wasmNativeDebugSymbols: true,
wasmBuildingForNestedPublish: true);
}

[Theory]
/* always relink */
[InlineData("Debug", "", /*build*/ true, /*publish*/ true)]
[InlineData("Release", "", /*build*/ true, /*publish*/ true)]
[InlineData("Release", "<PublishTrimmed>false</PublishTrimmed>", /*build*/ true, /*publish*/ true)]
public void WithNativeReference(string config, string extraProperties, bool buildValue, bool publishValue)
[InlineData("Debug", "", /*publish*/ false)]
[InlineData("Debug", "", /*publish*/ true)]
[InlineData("Release", "", /*publish*/ false)]
[InlineData("Release", "", /*publish*/ true)]
[InlineData("Release", "<PublishTrimmed>false</PublishTrimmed>", /*publish*/ true)]
public void WithNativeReference(string config, string extraProperties, bool publish)
{
string nativeLibPath = Path.Combine(BuildEnvironment.TestAssetsPath, "native-libs", "native-lib.o");
string nativeRefItem = @$"<NativeFileReference Include=""{nativeLibPath}"" />";
string output = CheckWasmNativeDefaultValue("native_defaults_publish",
(string output, string? line) = CheckWasmNativeDefaultValue("native_defaults_publish",
config,
extraProperties,
aot: false,
dotnetWasmFromRuntimePack: !publishValue,
publish: true,
dotnetWasmFromRuntimePack: !publish,
publish: publish,
extraItems: nativeRefItem);

// for build - FIXME:
Assert.DoesNotContain($"** WasmBuildNative: '{buildValue.ToString().ToLower()}', WasmBuildingForNestedPublish: ''", output);
// for publish
Assert.Contains($"** WasmBuildNative: '{publishValue.ToString().ToLower()}', WasmNativeStrip: 'true', WasmBuildingForNestedPublish: 'true'", output);
Assert.Contains("Stopping the build", output);
InferAndCheckPropertyValues(line, isPublish: publish, wasmBuildNative: true, config: config);
}

private string CheckWasmNativeDefaultValue(string projectName,
private (string, string?) CheckWasmNativeDefaultValue(string projectName,
string config,
string extraProperties,
bool aot,
Expand All @@ -201,7 +197,7 @@ private string CheckWasmNativeDefaultValue(string projectName,

string printValueTarget = @"
<Target Name=""PrintWasmBuildNative"" AfterTargets=""_BeforeWasmBuildApp"">
<Message Text=""** WasmBuildNative: '$(WasmBuildNative)', WasmNativeStrip: '$(WasmNativeStrip)', WasmBuildingForNestedPublish: '$(WasmBuildingForNestedPublish)'"" Importance=""High"" />
<Message Text=""** WasmBuildNative: '$(WasmBuildNative)', WasmNativeStrip: '$(WasmNativeStrip)', WasmNativeDebugSymbols: '$(WasmNativeDebugSymbols)', WasmBuildingForNestedPublish: '$(WasmBuildingForNestedPublish)'"" Importance=""High"" />
" + (publish
? @"<Error Text=""Stopping the build"" Condition=""$(WasmBuildingForNestedPublish) == 'true'"" />"
: @"<Error Text=""Stopping the build"" />")
Expand All @@ -223,7 +219,32 @@ private string CheckWasmNativeDefaultValue(string projectName,
BuildOnlyAfterPublish: false,
Publish: publish));

return output;
Assert.Contains("Stopping the build", output);

Match m = s_regex.Match(output);
Assert.Equal(1, m.Groups.Count);
return (output, m.Success ? m.Groups[0]?.ToString() : null);
}

private void InferAndCheckPropertyValues(string? line, bool isPublish, bool wasmBuildNative, string config)
{
bool expectedWasmNativeStripValue;
if (!isPublish && wasmBuildNative && config == "Debug")
expectedWasmNativeStripValue = false;
else
expectedWasmNativeStripValue = true;

CheckPropertyValues(line, wasmBuildNative, expectedWasmNativeStripValue, /*wasmNativeDebugSymbols*/true, isPublish);
}

private void CheckPropertyValues(string? line, bool wasmBuildNative, bool wasmNativeStrip, bool wasmNativeDebugSymbols, bool? wasmBuildingForNestedPublish)
{
Assert.NotNull(line);
Assert.Contains($"** WasmBuildNative: '{wasmBuildNative.ToString().ToLower()}', " +
$"WasmNativeStrip: '{wasmNativeStrip.ToString().ToLower()}', " +
$"WasmNativeDebugSymbols: '{wasmNativeDebugSymbols.ToString().ToLower()}', " +
$"WasmBuildingForNestedPublish: '{(wasmBuildingForNestedPublish.HasValue && wasmBuildingForNestedPublish == true ? "true" : "")}'",
line);
}
}
}
28 changes: 16 additions & 12 deletions src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
$(_BeforeWasmBuildAppDependsOn);
_SetupEmscripten;
_SetWasmBuildNativeDefaults;
_SetWasmNativeStripDefault;
_ReadEmccProps
</_BeforeWasmBuildAppDependsOn>

Expand Down Expand Up @@ -120,6 +119,7 @@
<_BoolPropertiesThatTriggerRelinking Include="InvariantTimezone" DefaultValueInRuntimePack="false" />
<_BoolPropertiesThatTriggerRelinking Include="InvariantGlobalization" DefaultValueInRuntimePack="false" />
<_BoolPropertiesThatTriggerRelinking Include="WasmNativeStrip" DefaultValueInRuntimePack="true" />
<!--<_BoolPropertiesThatTriggerRelinking Include="WasmNativeDebugSymbols" DefaultValueInRuntimePack="true" />-->
</ItemGroup>

<PropertyGroup>
Expand All @@ -134,7 +134,6 @@
<WasmBuildNative Condition="'$(RunAOTCompilation)' == 'true' and '$(RunAOTCompilationAfterBuild)' == 'true'">true</WasmBuildNative>

<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and @(NativeFileReference->Count()) > 0" >true</WasmBuildNative>
<WasmBuildNative Condition="'$(WasmBuildNative)' == ''">false</WasmBuildNative>
</PropertyGroup>

<!-- When Publishing -->
Expand All @@ -148,10 +147,23 @@

<!-- default to relinking in Release config -->
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and '$(Configuration)' == 'Release'">true</WasmBuildNative>
</PropertyGroup>

<PropertyGroup>
<WasmBuildNative Condition="'$(WasmBuildNative)' == ''">false</WasmBuildNative>
</PropertyGroup>

<!-- Default with nothing set: Build+relink+config=debug -->
<PropertyGroup Condition="'$(WasmNativeDebugSymbols)' == '' and '$(WasmNativeStrip)' == '' and '$(WasmBuildingForNestedPublish)' != 'true' and '$(WasmBuildNative)' == 'true' and '$(Configuration)' == 'Debug'">
<WasmNativeDebugSymbols>true</WasmNativeDebugSymbols>
<WasmNativeStrip>false</WasmNativeStrip>
</PropertyGroup>

<PropertyGroup>
<WasmNativeDebugSymbols Condition="'$(WasmNativeDebugSymbols)' == ''">true</WasmNativeDebugSymbols>
<WasmNativeStrip Condition="'$(WasmNativeStrip)' == ''">true</WasmNativeStrip>
</PropertyGroup>

<!-- If we want to default to true, and sdk is missing, then just warn, and set it to false -->
<Warning Condition="'$(WasmBuildNative)' == 'true' and '$(_IsEMSDKMissing)' == 'true'"
Text="$(_EMSDKMissingErrorMessage) Emscripten SDK is required for building native files." />
Expand All @@ -161,14 +173,6 @@
</PropertyGroup>
</Target>

<Target Name="_SetWasmNativeStripDefault" Condition="'$(WasmNativeStrip)' == ''">
<PropertyGroup>
<!-- Build+relink+config=debug -->
<WasmNativeStrip Condition="'$(WasmBuildingForNestedPublish)' != 'true' and '$(WasmBuildNative)' == 'true' and '$(Configuration)' == 'Debug'">false</WasmNativeStrip>
<WasmNativeStrip Condition="'$(WasmNativeStrip)' == ''">true</WasmNativeStrip>
</PropertyGroup>
</Target>

<Target Name="_WasmBuildNativeCore" DependsOnTargets="$(_WasmBuildNativeCoreDependsOn)" Condition="'$(WasmBuildNative)' == 'true'" />

<Target Name="_PrepareForWasmBuildNative">
Expand All @@ -179,7 +183,6 @@
<_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm'))</_MonoAotCrossCompilerPath>
<_EmccDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp'))</_EmccDefaultFlagsRsp>
<_EmccDefaultLinkFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-link.rsp'))</_EmccDefaultLinkFlagsRsp>
<WasmNativeDebugSymbols Condition="'$(WasmNativeDebugSymbols)' == ''">true</WasmNativeDebugSymbols>
<WasmLinkIcalls Condition="'$(WasmLinkIcalls)' == ''">$(WasmBuildNative)</WasmLinkIcalls>

<_WasmICallTablePath>$(_WasmIntermediateOutputPath)icall-table.h</_WasmICallTablePath>
Expand Down Expand Up @@ -222,7 +225,7 @@

<_EmccCommonFlags Include="$(_DefaultEmccFlags)" />
<_EmccCommonFlags Include="$(EmccFlags)" />
<_EmccCommonFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" />
<_EmccCommonFlags Include="-g" Condition="'$(WasmNativeStrip)' == 'false'" />
<_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" />
<_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" />
<_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmEnableExceptionHandling)' == 'true'" />
Expand Down Expand Up @@ -251,6 +254,7 @@
<_EmccCFlags Include="-emit-llvm" />

<_EmccCFlags Include="&quot;-I%(_EmccIncludePaths.Identity)&quot;" />
<_EmccCFlags Include="-g" Condition="'$(WasmNativeDebugSymbols)' == 'true'" />

<!-- Adding optimization flag at the top, so it gets precedence -->
<_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" />
Expand Down
Loading

0 comments on commit ec31705

Please sign in to comment.