Skip to content

Commit 7ba215b

Browse files
authored
Merge pull request #1027 from unoplatform/copilot/fix-aot-profile-filtering
Fix: MonoRuntimeMixedModeExcludedAssembly ignored when WasmShellAOTProfileExcludedMethods unset
2 parents 3f4abe8 + 70ece07 commit 7ba215b

File tree

8 files changed

+193
-1
lines changed

8 files changed

+193
-1
lines changed

build/ci/stage-build-linux-tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ jobs:
170170
dotnet publish -c Debug /m:1 /p:WasmShellEmccLinkOptimization=false /bl:$(build.artifactstagingdirectory)/sample.debug-interpreter-linux-debug.binlog
171171
displayName: Build Debug Interpreter with linking Sample
172172
173+
## MixedModeProfile validation - tests MonoRuntimeMixedModeExcludedAssembly without WasmShellAOTProfileExcludedMethods
174+
- bash: |
175+
cd $(build.sourcesdirectory)/src/Uno.Wasm.Tests.MixedModeProfile
176+
dotnet clean -c Release
177+
dotnet publish -c Release /m:1 /p:WasmShellEmccLinkOptimization=false /bl:$(build.artifactstagingdirectory)/MixedModeProfile-linux.binlog
178+
displayName: Build MixedModeProfile Test (validates AOT profile filtering)
179+
173180
- task: PublishBuildArtifacts@1
174181
condition: always()
175182
inputs:

build/ci/stage-build-windows-tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,13 @@ jobs:
262262
env:
263263
BUILD_SOURCESDIRECTORY: "$(build.sourcesdirectory)"
264264
265+
## MixedModeProfile validation - tests MonoRuntimeMixedModeExcludedAssembly without WasmShellAOTProfileExcludedMethods
266+
- pwsh: |
267+
cd $(build.sourcesdirectory)/src/Uno.Wasm.Tests.MixedModeProfile
268+
dotnet clean -c Release
269+
dotnet publish -c Release /m:1 /p:WasmShellEmccLinkOptimization=false /bl:$(build.artifactstagingdirectory)/MixedModeProfile-win.binlog
270+
displayName: Build MixedModeProfile Test (validates AOT profile filtering)
271+
265272
- task: PublishBuildArtifacts@1
266273
condition: always()
267274
inputs:

src/Uno.Wasm.Bootstrap.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{35E8
1919
EndProject
2020
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Tests.Electron", "Uno.Wasm.Tests.Electron\Uno.Wasm.Tests.Electron.csproj", "{C707589F-7E9F-48F3-9725-D012CEA8D4AF}"
2121
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Tests.MixedModeProfile", "Uno.Wasm.Tests.MixedModeProfile\Uno.Wasm.Tests.MixedModeProfile.csproj", "{75514CDF-4C84-4F13-91A9-3290D7D45FC4}"
23+
EndProject
2224
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BA079449-9703-42D1-9B7B-B534C2D1DB88}"
2325
EndProject
2426
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "WasmAot.UITests", "WasmAot.UITests\WasmAot.UITests.njsproj", "{B4C15C47-85E2-444E-B9F3-D970E35601A9}"
@@ -179,6 +181,10 @@ Global
179181
{C707589F-7E9F-48F3-9725-D012CEA8D4AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
180182
{C707589F-7E9F-48F3-9725-D012CEA8D4AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
181183
{C707589F-7E9F-48F3-9725-D012CEA8D4AF}.Release|Any CPU.Build.0 = Release|Any CPU
184+
{75514CDF-4C84-4F13-91A9-3290D7D45FC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
185+
{75514CDF-4C84-4F13-91A9-3290D7D45FC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
186+
{75514CDF-4C84-4F13-91A9-3290D7D45FC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
187+
{75514CDF-4C84-4F13-91A9-3290D7D45FC4}.Release|Any CPU.Build.0 = Release|Any CPU
182188
{B4C15C47-85E2-444E-B9F3-D970E35601A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
183189
{B4C15C47-85E2-444E-B9F3-D970E35601A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
184190
{B4C15C47-85E2-444E-B9F3-D970E35601A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -337,6 +343,7 @@ Global
337343
{89275D88-41A5-4B16-9488-0432B2A3D532} = {35E84E5F-1C9B-4168-8333-216B456C12DF}
338344
{A73BC29E-C720-44C8-A406-2A82D6079921} = {B27FC2DE-70CA-4287-9FC1-D108F115D8AA}
339345
{3D59ACEE-12BF-4B69-AEF7-893514C0BA7D} = {BA079449-9703-42D1-9B7B-B534C2D1DB88}
346+
{75514CDF-4C84-4F13-91A9-3290D7D45FC4} = {BA079449-9703-42D1-9B7B-B534C2D1DB88}
340347
{EBCB3142-593E-4815-915D-3B88B75161C1} = {5F914B7D-AFA2-4145-9548-B1B3A16D77AE}
341348
{359A63C4-C5D0-4011-8C39-89D23190B22F} = {35E84E5F-1C9B-4168-8333-216B456C12DF}
342349
{9FFF339E-BD09-4D1C-A756-92AE3625EAFD} = {5F914B7D-AFA2-4145-9548-B1B3A16D77AE}

src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@
313313
GenerateAOTProfile="$(WasmShellGenerateAOTProfile)"
314314
GenerateAOTProfileDebugList="$(WasmShellGenerateAOTProfileDebugList)"
315315
IntermediateOutputPath="$(IntermediateOutputPath)"
316-
MixedModeExcludedAssembly="$(WasmShellMixedModeExcludedAssembly)"
316+
MixedModeExcludedAssembly="@(MonoRuntimeMixedModeExcludedAssembly)"
317317
RunAOTCompilation="$(RunAOTCompilation)"
318318
WasmBuildNative="$(WasmBuildNative)"
319319
>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace Uno.Wasm.Tests.MixedModeProfile
5+
{
6+
class Program
7+
{
8+
static void Main(string[] args)
9+
{
10+
// Use Newtonsoft.Json to ensure its methods are in the AOT profile
11+
var testObject = new { Message = "Mixed Mode Profile Test", Value = 42 };
12+
var json = JsonConvert.SerializeObject(testObject);
13+
Console.WriteLine($"Test output: {json}");
14+
15+
// Deserialize to ensure more methods are used
16+
var deserialized = JsonConvert.DeserializeObject<dynamic>(json);
17+
Console.WriteLine($"Deserialized: {deserialized.Message}");
18+
}
19+
}
20+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Uno.Wasm.Tests.MixedModeProfile
2+
3+
This test project validates that `MonoRuntimeMixedModeExcludedAssembly` works independently without requiring `WasmShellAOTProfileExcludedMethods` to be specified.
4+
5+
## Purpose
6+
7+
This test was created to validate the fix for the issue where `MonoRuntimeMixedModeExcludedAssembly` was not being taken into account if `WasmShellAOTProfileExcludedMethods` was not specified.
8+
9+
## How It Works
10+
11+
1. The project uses Mixed Mode AOT compilation (`WasmShellMonoRuntimeExecutionMode=InterpreterAndAOT`)
12+
2. It specifies `MonoRuntimeMixedModeExcludedAssembly` items to exclude certain assemblies from AOT:
13+
- `Newtonsoft.Json`
14+
- `System.Xml`
15+
3. It deliberately does NOT specify `WasmShellAOTProfileExcludedMethods`
16+
4. It enables `WasmShellGenerateAOTProfileDebugList=true` to generate debug dump files
17+
5. A post-build target validates that:
18+
- Both `AOTProfileDump.Original.txt` and `AOTProfileDump.Filtered.txt` are generated
19+
- Methods from `Newtonsoft.Json` exist in the original profile
20+
- Methods from `Newtonsoft.Json` do NOT exist in the filtered profile
21+
- Methods from `System.Xml` do NOT exist in the filtered profile
22+
23+
## Expected Behavior
24+
25+
When the project builds successfully:
26+
- `AOTProfileDump.Original.txt` is created with all profile methods including those from excluded assemblies
27+
- `AOTProfileDump.Filtered.txt` is created with methods from excluded assemblies removed
28+
- The validation verifies that specific assemblies are actually filtered out, not just that files exist
29+
30+
## Validation
31+
32+
The post-build target `ValidateMixedModeProfileFiltering` will fail the build if:
33+
- The original dump file is not generated
34+
- The filtered dump file is not generated
35+
- No methods from `Newtonsoft.Json` are found in the original profile (test setup issue)
36+
- Any methods from `Newtonsoft.Json` or `System.Xml` are found in the filtered profile (filtering not working)
37+
38+
## Running the Test
39+
40+
To test this manually:
41+
42+
```bash
43+
cd src/Uno.Wasm.Tests.MixedModeProfile
44+
dotnet publish -c Release
45+
```
46+
47+
Check for the generated files in the `obj/Release/net10.0/browser-wasm/` directory:
48+
- `AOTProfileDump.Original.txt` - should contain methods from all assemblies
49+
- `AOTProfileDump.Filtered.txt` - should NOT contain methods from Newtonsoft.Json or System.Xml
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!-- This test validates that MonoRuntimeMixedModeExcludedAssembly works independently
2+
without requiring WasmShellAOTProfileExcludedMethods -->
3+
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
4+
5+
<PropertyGroup>
6+
<TargetFramework>net10.0</TargetFramework>
7+
<OutputType>Exe</OutputType>
8+
<IsPackable>false</IsPackable>
9+
10+
<!-- Enable Mixed Mode AOT -->
11+
<WasmShellMonoRuntimeExecutionMode>InterpreterAndAOT</WasmShellMonoRuntimeExecutionMode>
12+
<RunAOTCompilation>true</RunAOTCompilation>
13+
14+
<!-- Enable AOT profile debug list generation to verify filtering works -->
15+
<WasmShellGenerateAOTProfileDebugList>true</WasmShellGenerateAOTProfileDebugList>
16+
17+
<!-- Use the AOT profile for profiled AOT compilation -->
18+
<WasmAotProfilePath>$(MSBuildThisFileDirectory)aot.profile</WasmAotProfilePath>
19+
20+
<!--<WasmShellGenerateAOTProfile>true</WasmShellGenerateAOTProfile>-->
21+
22+
<!-- Important: We deliberately DO NOT set WasmShellAOTProfileExcludedMethods
23+
to test that MonoRuntimeMixedModeExcludedAssembly works independently -->
24+
</PropertyGroup>
25+
26+
<ItemGroup>
27+
<!-- Add a dependency that we'll exclude from AOT -->
28+
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
29+
</ItemGroup>
30+
31+
<ItemGroup>
32+
<!-- Test that this works without WasmShellAOTProfileExcludedMethods being set -->
33+
<MonoRuntimeMixedModeExcludedAssembly Include="Newtonsoft.Json" />
34+
<MonoRuntimeMixedModeExcludedAssembly Include="System.Xml" />
35+
</ItemGroup>
36+
37+
<Import Project="..\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.props" />
38+
<Import Project="..\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets" />
39+
40+
<ItemGroup>
41+
<ProjectReference Include="..\Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj">
42+
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
43+
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
44+
<UndefineProperties>TargetFramework</UndefineProperties>
45+
</ProjectReference>
46+
</ItemGroup>
47+
48+
<!-- Post-build validation target -->
49+
<Target Name="ValidateMixedModeProfileFiltering" AfterTargets="Publish" Condition="'$(WasmAotProfilePath)' != ''">
50+
<PropertyGroup>
51+
<_originalProfilePath>$(IntermediateOutputPath)AOTProfileDump.Original.txt</_originalProfilePath>
52+
<_filteredProfilePath>$(IntermediateOutputPath)AOTProfileDump.Filtered.txt</_filteredProfilePath>
53+
</PropertyGroup>
54+
55+
<!-- Verify that both debug dump files were generated -->
56+
<Error Condition="!Exists('$(_originalProfilePath)')"
57+
Text="AOTProfileDump.Original.txt was not generated. MonoRuntimeMixedModeExcludedAssembly may not be working correctly." />
58+
59+
<Error Condition="!Exists('$(_filteredProfilePath)')"
60+
Text="AOTProfileDump.Filtered.txt was not generated. Profile filtering for MonoRuntimeMixedModeExcludedAssembly is not being applied." />
61+
62+
<!-- Read and analyze the profile dumps -->
63+
<ReadLinesFromFile File="$(_originalProfilePath)">
64+
<Output TaskParameter="Lines" ItemName="_OriginalProfileLines" />
65+
</ReadLinesFromFile>
66+
67+
<ReadLinesFromFile File="$(_filteredProfilePath)">
68+
<Output TaskParameter="Lines" ItemName="_FilteredProfileLines" />
69+
</ReadLinesFromFile>
70+
71+
<!-- Check that Newtonsoft.Json methods exist in original profile -->
72+
<ItemGroup>
73+
<_NewtonsoftMethodsInOriginal Include="@(_OriginalProfileLines)" Condition="$([System.String]::Copy('%(Identity)').StartsWith('Newtonsoft.Json'))" />
74+
</ItemGroup>
75+
76+
<Error Condition="@(_NewtonsoftMethodsInOriginal->Count()) == 0"
77+
Text="No Newtonsoft.Json methods found in original profile. The test may not be using the assembly correctly." />
78+
79+
<!-- Check that Newtonsoft.Json methods do NOT exist in filtered profile -->
80+
<ItemGroup>
81+
<_NewtonsoftMethodsInFiltered Include="@(_FilteredProfileLines)" Condition="$([System.String]::Copy('%(Identity)').StartsWith('Newtonsoft.Json'))" />
82+
</ItemGroup>
83+
84+
<Error Condition="@(_NewtonsoftMethodsInFiltered->Count()) > 0"
85+
Text="Found @(_NewtonsoftMethodsInFiltered->Count()) Newtonsoft.Json methods in filtered profile. Assembly exclusion is not working! First method: @(_NewtonsoftMethodsInFiltered->'%(Identity)', ' | ')" />
86+
87+
<!-- Check that System.Xml methods do NOT exist in filtered profile -->
88+
<ItemGroup>
89+
<_SystemXmlMethodsInFiltered Include="@(_FilteredProfileLines)" Condition="$([System.String]::Copy('%(Identity)').StartsWith('System.Xml'))" />
90+
</ItemGroup>
91+
92+
<Error Condition="@(_SystemXmlMethodsInFiltered->Count()) > 0"
93+
Text="Found @(_SystemXmlMethodsInFiltered->Count()) System.Xml methods in filtered profile. Assembly exclusion is not working!" />
94+
95+
<Message Importance="high" Text="✓ Profile filtering validated successfully!" />
96+
<Message Importance="high" Text=" - Original profile has @(_OriginalProfileLines->Count()) total methods" />
97+
<Message Importance="high" Text=" - Filtered profile has @(_FilteredProfileLines->Count()) total methods" />
98+
<Message Importance="high" Text=" - Found @(_NewtonsoftMethodsInOriginal->Count()) Newtonsoft.Json methods in original (correctly excluded from filtered)" />
99+
<Message Importance="high" Text=" - MonoRuntimeMixedModeExcludedAssembly is working correctly!" />
100+
</Target>
101+
102+
</Project>
461 KB
Binary file not shown.

0 commit comments

Comments
 (0)