Skip to content

Commit

Permalink
[wasm] Don't allocate jiterpreter AOT tables unless AOT was enabled a…
Browse files Browse the repository at this point in the history
…t build time (#90978)

At present the jiterpreter has to allocate a lot of space for AOT-only optimizations. This PR flows through the RunAOTCompilation msbuild property when linking the wasm runtime JS, which allows us to skip allocating that space for applications that were not AOTed and improves startup performance.
  • Loading branch information
kg authored Aug 24, 2023
1 parent f8d9b3c commit f9b07d4
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/mono/mono/utils/options-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-e
// In degenerate cases the jiterpreter could end up generating lots of WASM, so shut off jitting once it reaches this limit
// Each wasm byte likely maps to multiple bytes of native code, so it's important for this limit not to be too high
DEFINE_INT(jiterpreter_wasm_bytes_limit, "jiterpreter-wasm-bytes-limit", 6 * 1024 * 1024, "Disable jiterpreter code generation once this many bytes of WASM have been generated")
DEFINE_INT(jiterpreter_table_size, "jiterpreter-table-size", 5 * 1024, "Size of the jiterpreter trace function table")
DEFINE_INT(jiterpreter_table_size, "jiterpreter-table-size", 6 * 1024, "Size of the jiterpreter trace function table")
// In real-world scenarios these tables can fill up at this size, but making them bigger causes startup time
// to bloat to an unacceptable degree. In practice this is still better than nothing.
// FIXME: In the future if we find a way to reduce the number of unique tables we can raise this constant
Expand Down
2 changes: 2 additions & 0 deletions src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@
<EmscriptenEnvVars Include="WASM_ENABLE_EH=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" />
<EmscriptenEnvVars Include="ENABLE_AOT_PROFILER=$([System.Convert]::ToInt32($(WasmProfilers.Contains('aot'))))" />
<EmscriptenEnvVars Include="ENABLE_BROWSER_PROFILER=$([System.Convert]::ToInt32($(WasmProfilers.Contains('browser'))))" />
<EmscriptenEnvVars Include="RUN_AOT_COMPILATION=1" Condition="'$(RunAOTCompilation)' == 'true'" />
<EmscriptenEnvVars Include="RUN_AOT_COMPILATION=0" Condition="'$(RunAOTCompilation)' != 'true'" />
</ItemGroup>

<ItemGroup Condition="'$(WasmAllowUndefinedSymbols)' == 'true'">
Expand Down
2 changes: 2 additions & 0 deletions src/mono/wasm/runtime/es6/dotnet.es6.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const WASM_ENABLE_SIMD = process.env.WASM_ENABLE_SIMD === "1";
const WASM_ENABLE_EH = process.env.WASM_ENABLE_EH === "1";
const ENABLE_BROWSER_PROFILER = process.env.ENABLE_BROWSER_PROFILER === "1";
const ENABLE_AOT_PROFILER = process.env.ENABLE_AOT_PROFILER === "1";
const RUN_AOT_COMPILATION = process.env.RUN_AOT_COMPILATION === "1";
var methodIndexByName = undefined;
var gitHash = undefined;

Expand Down Expand Up @@ -98,6 +99,7 @@ function injectDependencies() {
`linkerWasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` +
`linkerEnableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` +
`linkerEnableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}, ` +
`linkerRunAOTCompilation: ${RUN_AOT_COMPILATION ? "true" : "false"}, ` +
`gitHash: "${gitHash}", ` +
`});`;

Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/runtime/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export let linkerWasmEnableSIMD = true;
export let linkerWasmEnableEH = true;
export let linkerEnableAotProfiler = false;
export let linkerEnableBrowserProfiler = false;
export let linkerRunAOTCompilation = false;
export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard

export function passEmscriptenInternals(internals: EmscriptenInternals): void {
Expand All @@ -38,6 +39,7 @@ export function passEmscriptenInternals(internals: EmscriptenInternals): void {
linkerWasmEnableEH = internals.linkerWasmEnableEH;
linkerEnableAotProfiler = internals.linkerEnableAotProfiler;
linkerEnableBrowserProfiler = internals.linkerEnableBrowserProfiler;
linkerRunAOTCompilation = internals.linkerRunAOTCompilation;
runtimeHelpers.quit = internals.quit_;
runtimeHelpers.ExitStatus = internals.ExitStatus;
runtimeHelpers.moduleGitHash = internals.gitHash;
Expand Down Expand Up @@ -92,4 +94,4 @@ export function mono_assert(condition: unknown, messageFactory: string | (() =>
: messageFactory);
const error = new Error(message);
runtimeHelpers.abort(error);
}
}
15 changes: 9 additions & 6 deletions src/mono/wasm/runtime/jiterpreter-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import MonoWasmThreads from "consts:monoWasmThreads";
import { NativePointer, ManagedPointer, VoidPtr } from "./types/emscripten";
import { Module, mono_assert, runtimeHelpers } from "./globals";
import { Module, mono_assert, runtimeHelpers, linkerRunAOTCompilation } from "./globals";
import { WasmOpcode, WasmSimdOpcode, WasmValtype } from "./jiterpreter-opcodes";
import { MintOpcode } from "./mintops";
import cwraps from "./cwraps";
Expand Down Expand Up @@ -1947,11 +1947,12 @@ function jiterpreter_allocate_table(type: JiterpreterTable, base: number, size:
const wasmTable = getWasmFunctionTable();
const firstIndex = base, lastIndex = firstIndex + size - 1;
mono_assert(lastIndex < wasmTable.length, () => `Last index out of range: ${lastIndex} >= ${wasmTable.length}`);
// HACK: Always populate the first slot
wasmTable.set(firstIndex, fillValue);
// In threaded builds we need to populate all the reserved slots with safe placeholder functions
// This operation is expensive in v8, so avoid doing it in single-threaded builds (which SHOULD
// be safe, since it was previously not necessary)
if (MonoWasmThreads) {
wasmTable.set(firstIndex, fillValue);
// HACK: If possible, we want to copy any backing state associated with the first placeholder item,
// so that additional work doesn't have to be done by the runtime for the following table sets
const preparedValue = wasmTable.get(firstIndex);
Expand All @@ -1976,20 +1977,22 @@ export function jiterpreter_allocate_tables(module: any) {
// A partial solution would be to merge the tables based on argument count instead of exact type,
// then create special placeholder functions that examine the rmethod to determine which kind
// of method is being called.
const tableSize = options.tableSize, interpEntryTableSize = options.aotTableSize,
const traceTableSize = options.tableSize,
jitCallTableSize = linkerRunAOTCompilation ? options.tableSize : 1,
interpEntryTableSize = linkerRunAOTCompilation ? options.aotTableSize : 1,
numInterpEntryTables = JiterpreterTable.LAST - JiterpreterTable.InterpEntryStatic0 + 1,
totalSize = (tableSize * 2) + (numInterpEntryTables * interpEntryTableSize) + 1,
totalSize = traceTableSize + jitCallTableSize + (numInterpEntryTables * interpEntryTableSize) + 1,
wasmTable = getWasmFunctionTable(module);
let base = wasmTable.length;
const beforeGrow = performance.now();
wasmTable.grow(totalSize);
const afterGrow = performance.now();
if (options.enableStats)
mono_log_info(`Allocated ${totalSize} function table entries for jiterpreter, bringing total table size to ${wasmTable.length}`);
base = jiterpreter_allocate_table(JiterpreterTable.Trace, base, tableSize, getRawCwrap("mono_jiterp_placeholder_trace"));
base = jiterpreter_allocate_table(JiterpreterTable.Trace, base, traceTableSize, getRawCwrap("mono_jiterp_placeholder_trace"));
// FIXME: Install mono_jiterp_do_jit_call_indirect somehow.
base = jiterpreter_allocate_table(JiterpreterTable.DoJitCall, base, 1, getRawCwrap("mono_llvm_cpp_catch_exception"));
base = jiterpreter_allocate_table(JiterpreterTable.JitCall, base, tableSize, getRawCwrap("mono_jiterp_placeholder_jit_call"));
base = jiterpreter_allocate_table(JiterpreterTable.JitCall, base, jitCallTableSize, getRawCwrap("mono_jiterp_placeholder_jit_call"));
for (let table = JiterpreterTable.InterpEntryStatic0; table <= JiterpreterTable.LAST; table++)
base = jiterpreter_allocate_table(table, base, interpEntryTableSize, wasmTable.get(cwraps.mono_jiterp_get_interp_entry_func(table)));
const afterTables = performance.now();
Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/runtime/types/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ export type EmscriptenInternals = {
linkerWasmEnableEH: boolean,
linkerEnableAotProfiler: boolean,
linkerEnableBrowserProfiler: boolean,
linkerRunAOTCompilation: boolean,
quit_: Function,
ExitStatus: ExitStatusError,
gitHash: string,
Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/wasm.proj
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@
<_CmakeEnvironmentVariable Include="WASM_ENABLE_SIMD=0" Condition="'$(WasmEnableSIMD)' == 'false'" />
<_CmakeEnvironmentVariable Include="WASM_ENABLE_EH=1" Condition="'$(WasmEnableExceptionHandling)' != 'false'" />
<_CmakeEnvironmentVariable Include="WASM_ENABLE_EH=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" />
<_CmakeEnvironmentVariable Include="RUN_AOT_COMPILATION=1" Condition="'$(RunAOTCompilation)' == 'true'" />
<_CmakeEnvironmentVariable Include="RUN_AOT_COMPILATION=0" Condition="'$(RunAOTCompilation)' != 'true'" />
</ItemGroup>

<Copy SourceFiles="$(PInvokeTableFile)"
Expand Down Expand Up @@ -450,7 +452,7 @@
DestinationFolder="$(NativeBinDir)"
SkipUnchangedFiles="true" />

<Exec Command="$(CMakeBuildRuntimeConfigureCmd)" WorkingDirectory="$(NativeBinDir)"
<Exec Command="$(CMakeBuildRuntimeConfigureCmd)" WorkingDirectory="$(NativeBinDir)"
EnvironmentVariables="@(_CmakeEnvironmentVariable)" />
<Exec Command="$(CMakeBuildRuntimeCmd)" WorkingDirectory="$(NativeBinDir)"
EnvironmentVariables="@(_CmakeEnvironmentVariable)" />
Expand Down

0 comments on commit f9b07d4

Please sign in to comment.