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

Adjust for FullAOT removal #844

Merged
merged 3 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions doc/debugger-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ reload the debugged page.

### AOT Debugging and mono tracing (.NET 5 only)

When running with PG-AOT/FullAOT, exceptions generally do not provide stack traces, as WebAssembly as of the MVP does not yet support stack walking.
When running with PG-AOT, exceptions generally do not provide stack traces, as WebAssembly as of the MVP does not yet support stack walking.

For the time being, it's still possible view browser stack traces in the log by enabling mono tracing.
For the time being, it's still possible to view browser stack traces in the log by enabling mono tracing.

First, you'll need to add the following class to your app:

Expand Down
106 changes: 67 additions & 39 deletions doc/runtime-execution-modes.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
---
uid: Uno.Wasm.Bootstrap.Runtime.Execution
---
## Runtime Execution Modes
The mono for WebAssembly runtime provides three execution modes, Interpreter, AOT (Ahead of Time) and Mixed Mode Interpreter/AOT.
# Runtime Execution Modes

The mono for WebAssembly runtime provides three execution modes, Interpreter, AOT (Ahead of Time), and Mixed Mode Interpreter/AOT.

The execution mode can be set as follows:

```xml
<WasmShellMonoRuntimeExecutionMode>Interpreter</WasmShellMonoRuntimeExecutionMode>
```

The possible values are:

- `Interpreter` (the default mode)
- `InterpreterAndAOT`

To setup your machine to use AOT modes on Windows, you will need to install [Python from Windows Store](https://www.microsoft.com/store/productId/9P7QFQMJRFP7), or manually through [Python's official site](https://www.python.org/downloads/).

### Interpreter mode
This mode is the slowest, but allows for great flexibility and debugging, as well as an efficient payload size.

This mode is the slowest but allows for great flexibility and debugging, as well as an efficient payload size.

The linker mode can also be completely disabled for troubleshooting, as this will not impact the wasm payload size.

Expand All @@ -24,13 +29,15 @@ The linker mode can also be completely disabled for troubleshooting, as this wil
This mode is a hybrid between the interpreter and the AOT modes, where the interpreter is used to execute the code, but the JIT engine is used to generate some WebAssembly code on the fly. This mode is generally faster than the interpreter, but slower than the AOT mode.

To enable this mode, use the following option:

```xml
<PropertyGroup>
<WasmShellEnableJiterpreter>true</WasmShellEnableJiterpreter>
</PropertyGroup>
```

Additionally, some options can be used to fine tune the Jiterpreter mode, using options found [in this file](https://github.com/dotnet/runtime/blob/6a047a9aec7a36039cffac61186b04bd3f16dbe0/src/mono/mono/utils/options-def.h#L86-L114):
Additionally, some options can be used to fine-tune the Jiterpreter mode, using options found [in this file](https://github.com/dotnet/runtime/blob/6a047a9aec7a36039cffac61186b04bd3f16dbe0/src/mono/mono/utils/options-def.h#L86-L114):

```xml
<PropertyGroup>
<WasmShellRuntimeOptions>--jiterpreter-stats-enable --jiterpreter-estimate-heat</WasmShellRuntimeOptions>
Expand All @@ -40,14 +47,14 @@ Additionally, some options can be used to fine tune the Jiterpreter mode, using
Finally, runtime statistics are maintained by the jiterpreter and can be displayed by running `INTERNAL.jiterpreter_dump_stats()` in the browser debugger console.

### Mixed Interpreter and AOT Mode
This mode enable AOT compilation for most of the assemblies, with [some specific exceptions](https://github.com/dotnet/runtime/issues/50609).

This mode is generally prefered to FullAOT as it allows to load arbitrary assemblies and execute their code through the interpreter.
This mode enables AOT compilation for most of the assemblies, with [some specific exceptions](https://github.com/dotnet/runtime/issues/50609).

> [!IMPORTANT]
> These modes are not supported on macOS as of .NET 6 (Bootstrapper 3.x), and .NET 7 (Bootstrapper 4.x). You'll need to use a [Linux container](https://hub.docker.com/r/unoplatform/wasm-build) to build with AOT, see below for more details.
> This mode is not supported on macOS. You'll need to use a [Linux container](https://hub.docker.com/r/unoplatform/wasm-build) to build with AOT, see below for more details.

## Required configuration for Mixed AOT Mode or static linking on Linux

## Required configuration for AOT, Mixed Mode or static linking on Linux
- Ubuntu 18.04+ or a [container](https://hub.docker.com/r/unoplatform/wasm-build)
- A [stable build of mono](https://www.mono-project.com/download/stable/#download-lin)
- A [.NET SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu) >= 6.0
Expand All @@ -56,40 +63,51 @@ This mode is generally prefered to FullAOT as it allows to load arbitrary assemb
The easiest is to build using the environment provided by the [unoplatform/wasm-build docker image](https://hub.docker.com/r/unoplatform/wasm-build).

## Profile Guided AOT

This mode allows for the AOT engine to selectively optimize methods to WebAssembly, and keep the rest as interpreted. This gives a very good balance when choosing between performance and payload size. It also has the advantage of reducing the build time, as less code needs to be compiled down to WebAssembly.

This feature is used in two passes:

- The first pass needs the creation of a profiled interpreter build, which records any methods invoked during the profiling session.
- The second pass rebuilds the application using the Mixed AOT/Interpreter mode augmented by the recording created during the first pass.

This mode gives very good results, where the RayTracer sample of this repository goes from an uncomressed size of 5.5MB to 2.9MB.
This mode gives very good results, where the RayTracer sample of this repository goes from an uncompressed size of 5.5MB to 2.9MB.

To create a profiled build:
- In your Wasm csproj, add the following:
```xml
<WasmShellGenerateAOTProfile>true</WasmShellGenerateAOTProfile>
```

- In your Wasm csproj, add the following:

```xml
<WasmShellGenerateAOTProfile>true</WasmShellGenerateAOTProfile>
```

- In your `LinkerConfig.xml` file, add the following:
```xml
<assembly fullname="WebAssembly.Bindings" />
```

```xml
<assembly fullname="WebAssembly.Bindings" />
```

- Run the application once, without the debugger (e.g. Ctrl+F5)
- Navigate throughout the application in high usage places.
- Navigate throughout the application in high-usage places.
- Once done, either:
- Press the `Alt+Shift+P` key sequence
- Launch App.saveProfile()
- Download the `aot.profile` file next to the csproj file
- Comment the `WasmShellGenerateAOTProfile` line
- Add the following lines:
```xml
<ItemGroup>
<WasmShellEnableAotProfile Include="aot.profile" />
</ItemGroup>
```

```xml
<ItemGroup>
<WasmShellEnableAotProfile Include="aot.profile" />
</ItemGroup>
```

- Make sure that Mixed mode is enabled:
```xml
<WasmShellMonoRuntimeExecutionMode>InterpreterAndAOT</WasmShellMonoRuntimeExecutionMode>
```

```xml
<WasmShellMonoRuntimeExecutionMode>InterpreterAndAOT</WasmShellMonoRuntimeExecutionMode>
```

- Build you application again

Note that the AOT profile is a snapshot of the current set of assemblies and methods in your application. If that set changes significantly, you'll need to re-create the AOT profile to get optimal results.
Expand All @@ -111,16 +129,19 @@ The `WasmShellAOTProfileExcludedMethods` property specifies a semi-colon separat

The `MixedModeExcludedAssembly` is also used to filter the profile for assemblies, see below for more information.

Dumping the whole list of original and filtered list is possible by adding:
Dumping the whole list of the original and filtered lists is possible by adding:

```xml
<PropertyGroup>
<WasmShellGenerateAOTProfileDebugList>true</WasmShellGenerateAOTProfileDebugList>
</PropertyGroup>
```

This will generate files named `AOTProfileDump.*.txt` in the `obj` folder for inspection.

### Mixed AOT/Interpreter Mode
This modes allows for the WebAssembly generation of parts of the referenced assemblies, and falls back to the interpreter for code that was excluded or not known at build time.

This mode allows for the WebAssembly generation of parts of the referenced assemblies and falls back to the interpreter for code that was excluded or not known at build time.

This allows for a fine balance between payload size and execution performance.

Expand All @@ -131,17 +152,18 @@ At this time, it is only possible to exclude assemblies from being compiled to W
<MonoRuntimeMixedModeExcludedAssembly Include="Newtonsoft.Json" />
</ItemGroup>
```

Adding assemblies to this list will exclude them from being compiled to WebAssembly.

### Troubleshooting Mixed AOT/Interpreter Mode
When using the Mixed AOT/Interpreter mode, it is possible that some methods may not be compiled to
WebAssembly for a variety of reasons. This can cause performance issues, as the interpreter is slower
than the AOT generated code.

When using the Mixed AOT/Interpreter mode, it is possible that some methods may not be compiled to WebAssembly for a variety of reasons. This can cause performance issues, as the interpreter is slower than the AOT-generated code.

In order to determine which methods are still using the interpreter, you can use the following property:

```xml
<PropertyGroup>
<WasmShellPrintAOTSkippedMethods>true</WasmShellPrintAOTSkippedMethods>
<WasmShellPrintAOTSkippedMethods>true</WasmShellPrintAOTSkippedMethods>
</PropertyGroup>
```

Expand All @@ -151,7 +173,7 @@ The logs from the AOT compiler can be found in [binlogs generated](https://aka.p

When building with Mixed AOT/Interpreter modes, the initial memory may need to be adjusted in the project configuration if the following error message appears:

```
```text
wasm-ld: error: initial memory too small, 17999248 bytes needed
```

Expand All @@ -165,32 +187,38 @@ In order to fix this, you'll need to set the [`INITIAL_MEMORY`](https://emscript

which will set the initial memory size accordingly. Note that setting this value to a sufficiently large value (based on your app's usual memory consumption) can improve the startup performance.

## Required configuration for AOT, Mixed Mode or external bitcode support compilation on Windows 10
## Required configuration for AOT, Mixed Mode, or external bitcode support compilation on Windows 10

### Native windows tooling

This is the default mode on Windows. It requires installing [Python from Windows Store](https://www.microsoft.com/store/productId/9P7QFQMJRFP7), or manually through [Python's official site](https://www.python.org/downloads/).

This mode is compatible with CI servers which have Python installed by default, such as [Azure Devops Hosted Agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops).
This mode is compatible with CI servers that have Python installed by default, such as [Azure Devops Hosted Agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops).

#### Powershell setup
The bootstrapper needs to use powershell, and configuration is needed.

The bootstrapper needs to use PowerShell, and configuration is needed.

You'll need to run the following command in an elevated (administrator) PowerShell prompt:
```

```pwsh
Set-ExecutionPolicy RemoteSigned -Force
```

You may also need to enable the developer mode for Windows 10 and 11 by using **Control panel** / **System** / **Privacy & Security** / **For developers** / **PowerShell** and setting **Change execution policy to allow local scripts to run without signing** to **On**.

### Using Windows Subsystem for Linux

This mode can be enabled by adding this property to the `csproj`:

```xml
<PropertyGroup>
<WasmShellEnableEmscriptenWindows>false</WasmShellEnableEmscriptenWindows>
</PropertyGroup>
```

Requirements:

- A Windows 10 machine with [WSL 1 or 2 with Ubuntu 20.04](https://docs.microsoft.com/en-us/windows/wsl/install-win10) installed.
- A [stable build of mono](https://www.mono-project.com/download/stable/#download-lin)
- A [.NET SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu) >= 3.1
Expand All @@ -207,10 +235,10 @@ The boostrapper uses its own installation of emscripten, installed by default in

### WSL Integration for Windows 10

The integration with WSL provides a way for using AOT, Mixed mode or external bitcode support using Windows 10.
The integration with WSL provides a way to use AOT, Mixed mode, or external bitcode support using Windows 10.

This feature is active only if one of those condition is true:
- The `WasmShellMonoRuntimeExecutionMode` property is `FullAOT` or `InterpreterAndAOT

- The `WasmShellMonoRuntimeExecutionMode` property is `InterpreterAndAOT`
- There is a `*.bc` or `*.a` file in the `Content` item group
- The `WasmShellForceUseWSL` is set to `true`

2 changes: 1 addition & 1 deletion src/Uno.Wasm.Bootstrap/build/Uno.Wasm.Bootstrap.targets
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

<UnoWasmPublishDistDir>$(AssemblyName)/dist/</UnoWasmPublishDistDir>

<!-- Possible values: Interpreter, FullAOT, InterpreterAndAOT -->
<!-- Possible values: Interpreter, InterpreterAndAOT -->
<WasmShellMonoRuntimeExecutionMode Condition="'$(WasmShellMonoRuntimeExecutionMode)'==''">Interpreter</WasmShellMonoRuntimeExecutionMode>

<!-- Compatibility with previous version of the task using WasmShellEnableAOT -->
Expand Down
Loading