Skip to content

Commit f9b07d4

Browse files
authored
[wasm] Don't allocate jiterpreter AOT tables unless AOT was enabled at 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.
1 parent f8d9b3c commit f9b07d4

File tree

7 files changed

+21
-9
lines changed

7 files changed

+21
-9
lines changed

src/mono/mono/utils/options-def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-e
146146
// In degenerate cases the jiterpreter could end up generating lots of WASM, so shut off jitting once it reaches this limit
147147
// Each wasm byte likely maps to multiple bytes of native code, so it's important for this limit not to be too high
148148
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")
149-
DEFINE_INT(jiterpreter_table_size, "jiterpreter-table-size", 5 * 1024, "Size of the jiterpreter trace function table")
149+
DEFINE_INT(jiterpreter_table_size, "jiterpreter-table-size", 6 * 1024, "Size of the jiterpreter trace function table")
150150
// In real-world scenarios these tables can fill up at this size, but making them bigger causes startup time
151151
// to bloat to an unacceptable degree. In practice this is still better than nothing.
152152
// FIXME: In the future if we find a way to reduce the number of unique tables we can raise this constant

src/mono/wasm/build/WasmApp.Native.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@
291291
<EmscriptenEnvVars Include="WASM_ENABLE_EH=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" />
292292
<EmscriptenEnvVars Include="ENABLE_AOT_PROFILER=$([System.Convert]::ToInt32($(WasmProfilers.Contains('aot'))))" />
293293
<EmscriptenEnvVars Include="ENABLE_BROWSER_PROFILER=$([System.Convert]::ToInt32($(WasmProfilers.Contains('browser'))))" />
294+
<EmscriptenEnvVars Include="RUN_AOT_COMPILATION=1" Condition="'$(RunAOTCompilation)' == 'true'" />
295+
<EmscriptenEnvVars Include="RUN_AOT_COMPILATION=0" Condition="'$(RunAOTCompilation)' != 'true'" />
294296
</ItemGroup>
295297

296298
<ItemGroup Condition="'$(WasmAllowUndefinedSymbols)' == 'true'">

src/mono/wasm/runtime/es6/dotnet.es6.lib.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const WASM_ENABLE_SIMD = process.env.WASM_ENABLE_SIMD === "1";
1212
const WASM_ENABLE_EH = process.env.WASM_ENABLE_EH === "1";
1313
const ENABLE_BROWSER_PROFILER = process.env.ENABLE_BROWSER_PROFILER === "1";
1414
const ENABLE_AOT_PROFILER = process.env.ENABLE_AOT_PROFILER === "1";
15+
const RUN_AOT_COMPILATION = process.env.RUN_AOT_COMPILATION === "1";
1516
var methodIndexByName = undefined;
1617
var gitHash = undefined;
1718

@@ -98,6 +99,7 @@ function injectDependencies() {
9899
`linkerWasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` +
99100
`linkerEnableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` +
100101
`linkerEnableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}, ` +
102+
`linkerRunAOTCompilation: ${RUN_AOT_COMPILATION ? "true" : "false"}, ` +
101103
`gitHash: "${gitHash}", ` +
102104
`});`;
103105

src/mono/wasm/runtime/globals.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export let linkerWasmEnableSIMD = true;
2929
export let linkerWasmEnableEH = true;
3030
export let linkerEnableAotProfiler = false;
3131
export let linkerEnableBrowserProfiler = false;
32+
export let linkerRunAOTCompilation = false;
3233
export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard
3334

3435
export function passEmscriptenInternals(internals: EmscriptenInternals): void {
@@ -38,6 +39,7 @@ export function passEmscriptenInternals(internals: EmscriptenInternals): void {
3839
linkerWasmEnableEH = internals.linkerWasmEnableEH;
3940
linkerEnableAotProfiler = internals.linkerEnableAotProfiler;
4041
linkerEnableBrowserProfiler = internals.linkerEnableBrowserProfiler;
42+
linkerRunAOTCompilation = internals.linkerRunAOTCompilation;
4143
runtimeHelpers.quit = internals.quit_;
4244
runtimeHelpers.ExitStatus = internals.ExitStatus;
4345
runtimeHelpers.moduleGitHash = internals.gitHash;
@@ -92,4 +94,4 @@ export function mono_assert(condition: unknown, messageFactory: string | (() =>
9294
: messageFactory);
9395
const error = new Error(message);
9496
runtimeHelpers.abort(error);
95-
}
97+
}

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import MonoWasmThreads from "consts:monoWasmThreads";
55
import { NativePointer, ManagedPointer, VoidPtr } from "./types/emscripten";
6-
import { Module, mono_assert, runtimeHelpers } from "./globals";
6+
import { Module, mono_assert, runtimeHelpers, linkerRunAOTCompilation } from "./globals";
77
import { WasmOpcode, WasmSimdOpcode, WasmValtype } from "./jiterpreter-opcodes";
88
import { MintOpcode } from "./mintops";
99
import cwraps from "./cwraps";
@@ -1947,11 +1947,12 @@ function jiterpreter_allocate_table(type: JiterpreterTable, base: number, size:
19471947
const wasmTable = getWasmFunctionTable();
19481948
const firstIndex = base, lastIndex = firstIndex + size - 1;
19491949
mono_assert(lastIndex < wasmTable.length, () => `Last index out of range: ${lastIndex} >= ${wasmTable.length}`);
1950+
// HACK: Always populate the first slot
1951+
wasmTable.set(firstIndex, fillValue);
19501952
// In threaded builds we need to populate all the reserved slots with safe placeholder functions
19511953
// This operation is expensive in v8, so avoid doing it in single-threaded builds (which SHOULD
19521954
// be safe, since it was previously not necessary)
19531955
if (MonoWasmThreads) {
1954-
wasmTable.set(firstIndex, fillValue);
19551956
// HACK: If possible, we want to copy any backing state associated with the first placeholder item,
19561957
// so that additional work doesn't have to be done by the runtime for the following table sets
19571958
const preparedValue = wasmTable.get(firstIndex);
@@ -1976,20 +1977,22 @@ export function jiterpreter_allocate_tables(module: any) {
19761977
// A partial solution would be to merge the tables based on argument count instead of exact type,
19771978
// then create special placeholder functions that examine the rmethod to determine which kind
19781979
// of method is being called.
1979-
const tableSize = options.tableSize, interpEntryTableSize = options.aotTableSize,
1980+
const traceTableSize = options.tableSize,
1981+
jitCallTableSize = linkerRunAOTCompilation ? options.tableSize : 1,
1982+
interpEntryTableSize = linkerRunAOTCompilation ? options.aotTableSize : 1,
19801983
numInterpEntryTables = JiterpreterTable.LAST - JiterpreterTable.InterpEntryStatic0 + 1,
1981-
totalSize = (tableSize * 2) + (numInterpEntryTables * interpEntryTableSize) + 1,
1984+
totalSize = traceTableSize + jitCallTableSize + (numInterpEntryTables * interpEntryTableSize) + 1,
19821985
wasmTable = getWasmFunctionTable(module);
19831986
let base = wasmTable.length;
19841987
const beforeGrow = performance.now();
19851988
wasmTable.grow(totalSize);
19861989
const afterGrow = performance.now();
19871990
if (options.enableStats)
19881991
mono_log_info(`Allocated ${totalSize} function table entries for jiterpreter, bringing total table size to ${wasmTable.length}`);
1989-
base = jiterpreter_allocate_table(JiterpreterTable.Trace, base, tableSize, getRawCwrap("mono_jiterp_placeholder_trace"));
1992+
base = jiterpreter_allocate_table(JiterpreterTable.Trace, base, traceTableSize, getRawCwrap("mono_jiterp_placeholder_trace"));
19901993
// FIXME: Install mono_jiterp_do_jit_call_indirect somehow.
19911994
base = jiterpreter_allocate_table(JiterpreterTable.DoJitCall, base, 1, getRawCwrap("mono_llvm_cpp_catch_exception"));
1992-
base = jiterpreter_allocate_table(JiterpreterTable.JitCall, base, tableSize, getRawCwrap("mono_jiterp_placeholder_jit_call"));
1995+
base = jiterpreter_allocate_table(JiterpreterTable.JitCall, base, jitCallTableSize, getRawCwrap("mono_jiterp_placeholder_jit_call"));
19931996
for (let table = JiterpreterTable.InterpEntryStatic0; table <= JiterpreterTable.LAST; table++)
19941997
base = jiterpreter_allocate_table(table, base, interpEntryTableSize, wasmTable.get(cwraps.mono_jiterp_get_interp_entry_func(table)));
19951998
const afterTables = performance.now();

src/mono/wasm/runtime/types/internal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ export type EmscriptenInternals = {
280280
linkerWasmEnableEH: boolean,
281281
linkerEnableAotProfiler: boolean,
282282
linkerEnableBrowserProfiler: boolean,
283+
linkerRunAOTCompilation: boolean,
283284
quit_: Function,
284285
ExitStatus: ExitStatusError,
285286
gitHash: string,

src/mono/wasm/wasm.proj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@
409409
<_CmakeEnvironmentVariable Include="WASM_ENABLE_SIMD=0" Condition="'$(WasmEnableSIMD)' == 'false'" />
410410
<_CmakeEnvironmentVariable Include="WASM_ENABLE_EH=1" Condition="'$(WasmEnableExceptionHandling)' != 'false'" />
411411
<_CmakeEnvironmentVariable Include="WASM_ENABLE_EH=0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" />
412+
<_CmakeEnvironmentVariable Include="RUN_AOT_COMPILATION=1" Condition="'$(RunAOTCompilation)' == 'true'" />
413+
<_CmakeEnvironmentVariable Include="RUN_AOT_COMPILATION=0" Condition="'$(RunAOTCompilation)' != 'true'" />
412414
</ItemGroup>
413415

414416
<Copy SourceFiles="$(PInvokeTableFile)"
@@ -450,7 +452,7 @@
450452
DestinationFolder="$(NativeBinDir)"
451453
SkipUnchangedFiles="true" />
452454

453-
<Exec Command="$(CMakeBuildRuntimeConfigureCmd)" WorkingDirectory="$(NativeBinDir)"
455+
<Exec Command="$(CMakeBuildRuntimeConfigureCmd)" WorkingDirectory="$(NativeBinDir)"
454456
EnvironmentVariables="@(_CmakeEnvironmentVariable)" />
455457
<Exec Command="$(CMakeBuildRuntimeCmd)" WorkingDirectory="$(NativeBinDir)"
456458
EnvironmentVariables="@(_CmakeEnvironmentVariable)" />

0 commit comments

Comments
 (0)