Skip to content

Commit 9f515ff

Browse files
authored
[wasm] add a total wasm bytes quota to the jiterpreter; adjust parameters (#80266)
* Adjust jiterpreter parameters to avoid making S.T.J AOT tests slower * Add a total wasm bytes quota to the jiterpreter to avoid generating way too much code in degenerate cases
1 parent 7f83765 commit 9f515ff

File tree

5 files changed

+31
-7
lines changed

5 files changed

+31
-7
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,20 @@ DEFINE_BOOL(jiterpreter_dump_traces, "jiterpreter-dump-traces", FALSE, "Dump the
107107
// Currently reduces performance significantly :(
108108
DEFINE_BOOL(jiterpreter_use_constants, "jiterpreter-use-constants", FALSE, "Use runtime imports for pointer constants")
109109
// any trace that doesn't have at least this many meaningful (non-nop) opcodes in it will be rejected
110-
DEFINE_INT(jiterpreter_minimum_trace_length, "jiterpreter-minimum-trace-length", 8, "Reject traces shorter than this number of meaningful opcodes")
110+
DEFINE_INT(jiterpreter_minimum_trace_length, "jiterpreter-minimum-trace-length", 10, "Reject traces shorter than this number of meaningful opcodes")
111111
// once a trace entry point is inserted, we only actually JIT code for it once it's been hit this many times
112112
DEFINE_INT(jiterpreter_minimum_trace_hit_count, "jiterpreter-minimum-trace-hit-count", 5000, "JIT trace entry points once they are hit this many times")
113113
// After a do_jit_call call site is hit this many times, we will queue it to be jitted
114-
DEFINE_INT(jiterpreter_jit_call_trampoline_hit_count, "jiterpreter-jit-call-hit-count", 2000, "Queue specialized do_jit_call trampoline for JIT after this many hits")
114+
DEFINE_INT(jiterpreter_jit_call_trampoline_hit_count, "jiterpreter-jit-call-hit-count", 1000, "Queue specialized do_jit_call trampoline for JIT after this many hits")
115115
// After a do_jit_call call site is hit this many times without being jitted, we will flush the JIT queue
116-
DEFINE_INT(jiterpreter_jit_call_queue_flush_threshold, "jiterpreter-jit-call-queue-flush-threshold", 8000, "Flush the do_jit_call JIT queue after an unJITted call site has this many hits")
116+
DEFINE_INT(jiterpreter_jit_call_queue_flush_threshold, "jiterpreter-jit-call-queue-flush-threshold", 6000, "Flush the do_jit_call JIT queue after an unJITted call site has this many hits")
117117
// After a generic interp_entry wrapper is hit this many times, we will queue it to be jitted
118-
DEFINE_INT(jiterpreter_interp_entry_trampoline_hit_count, "jiterpreter-interp-entry-hit-count", 250, "Queue specialized interp_entry wrapper for JIT after this many hits")
118+
DEFINE_INT(jiterpreter_interp_entry_trampoline_hit_count, "jiterpreter-interp-entry-hit-count", 1000, "Queue specialized interp_entry wrapper for JIT after this many hits")
119119
// After a generic interp_entry wrapper is hit this many times without being jitted, we will flush the JIT queue
120-
DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-entry-queue-flush-threshold", 1000, "Flush the interp_entry JIT queue after an unJITted call site has this many hits")
120+
DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-entry-queue-flush-threshold", 3000, "Flush the interp_entry JIT queue after an unJITted call site has this many hits")
121+
// In degenerate cases the jiterpreter could end up generating lots of WASM, so shut off jitting once it reaches this limit
122+
// Each wasm byte likely maps to multiple bytes of native code, so it's important for this limit not to be too high
123+
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")
121124
#endif // HOST_BROWSER
122125

123126
/* Cleanup */

src/mono/wasm/runtime/jiterpreter-interp-entry.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ function flush_wasm_entry_trampoline_jit_queue () {
207207
trampBuilder = builder = new WasmBuilder(constantSlots);
208208
else
209209
builder.clear(constantSlots);
210+
211+
if (builder.options.wasmBytesLimit <= counters.bytesGenerated) {
212+
jitQueue.length = 0;
213+
return;
214+
}
215+
210216
const started = _now();
211217
let compileStarted = 0;
212218
let rejected = true, threw = false;
@@ -321,6 +327,7 @@ function flush_wasm_entry_trampoline_jit_queue () {
321327
const buffer = builder.getArrayView();
322328
if (trace > 0)
323329
console.log(`jit queue generated ${buffer.length} byte(s) of wasm`);
330+
counters.bytesGenerated += buffer.length;
324331
const traceModule = new WebAssembly.Module(buffer);
325332

326333
const imports : any = {

src/mono/wasm/runtime/jiterpreter-jit-call.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ function getIsWasmEhSupported () : boolean {
167167
for (let i = 0; i < doJitCall16.length; i += 2)
168168
bytes[i / 2] = parseInt(doJitCall16.substring(i, i + 2), 16);
169169

170+
counters.bytesGenerated += bytes.length;
170171
doJitCallModule = new WebAssembly.Module(bytes);
171172
wasmEhSupported = true;
172173
} catch (exc) {
@@ -248,6 +249,11 @@ export function mono_interp_flush_jitcall_queue () : void {
248249
else
249250
builder.clear(0);
250251

252+
if (builder.options.wasmBytesLimit <= counters.bytesGenerated) {
253+
jitQueue.length = 0;
254+
return;
255+
}
256+
251257
if (builder.options.enableWasmEh) {
252258
if (!getIsWasmEhSupported()) {
253259
// The user requested to enable wasm EH but it's not supported, so turn the option back off
@@ -350,6 +356,7 @@ export function mono_interp_flush_jitcall_queue () : void {
350356
const buffer = builder.getArrayView();
351357
if (trace > 0)
352358
console.log(`do_jit_call queue flush generated ${buffer.length} byte(s) of wasm`);
359+
counters.bytesGenerated += buffer.length;
353360
const traceModule = new WebAssembly.Module(buffer);
354361

355362
const imports : any = {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,8 @@ export const counters = {
650650
tracesCompiled: 0,
651651
entryWrappersCompiled: 0,
652652
jitCallsCompiled: 0,
653-
failures: 0
653+
failures: 0,
654+
bytesGenerated: 0
654655
};
655656

656657
export const _now = (globalThis.performance && globalThis.performance.now)
@@ -906,6 +907,8 @@ export type JiterpreterOptions = {
906907
jitCallFlushThreshold: number;
907908
interpEntryHitCount: number;
908909
interpEntryFlushThreshold: number;
910+
// Maximum total number of wasm bytes to generate
911+
wasmBytesLimit: number;
909912
}
910913

911914
const optionNames : { [jsName: string] : string } = {
@@ -927,6 +930,7 @@ const optionNames : { [jsName: string] : string } = {
927930
"jitCallFlushThreshold": "jiterpreter-jit-call-queue-flush-threshold",
928931
"interpEntryHitCount": "jiterpreter-interp-entry-hit-count",
929932
"interpEntryFlushThreshold": "jiterpreter-interp-entry-queue-flush-threshold",
933+
"wasmBytesLimit": "jiterpreter-wasm-bytes-limit",
930934
};
931935

932936
let optionsVersion = -1;

src/mono/wasm/runtime/jiterpreter.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ function generate_wasm (
585585
const buffer = builder.getArrayView();
586586
if (trace > 0)
587587
console.log(`${traceName} generated ${buffer.length} byte(s) of wasm`);
588+
counters.bytesGenerated += buffer.length;
588589
const traceModule = new WebAssembly.Module(buffer);
589590

590591
const imports : any = {
@@ -2936,6 +2937,8 @@ export function mono_interp_tier_prepare_jiterpreter (
29362937
// FIXME: We shouldn't need this check
29372938
if (!mostRecentOptions.enableTraces)
29382939
return JITERPRETER_NOT_JITTED;
2940+
else if (mostRecentOptions.wasmBytesLimit <= counters.bytesGenerated)
2941+
return JITERPRETER_NOT_JITTED;
29392942

29402943
let info = traceInfo[<any>ip];
29412944

@@ -2983,7 +2986,7 @@ export function jiterpreter_dump_stats (b?: boolean) {
29832986
if (!mostRecentOptions.enableStats && (b !== undefined))
29842987
return;
29852988

2986-
console.log(`// jiterpreter produced ${counters.tracesCompiled} traces from ${counters.traceCandidates} candidates (${(counters.tracesCompiled / counters.traceCandidates * 100).toFixed(1)}%), ${counters.jitCallsCompiled} jit_call trampolines, and ${counters.entryWrappersCompiled} interp_entry wrappers`);
2989+
console.log(`// generated: ${counters.bytesGenerated} wasm bytes; ${counters.tracesCompiled} traces (${counters.traceCandidates} candidates, ${(counters.tracesCompiled / counters.traceCandidates * 100).toFixed(1)}%); ${counters.jitCallsCompiled} jit_calls; ${counters.entryWrappersCompiled} interp_entries`);
29872990
console.log(`// time spent: ${elapsedTimes.generation | 0}ms generating, ${elapsedTimes.compilation | 0}ms compiling wasm`);
29882991
if (mostRecentOptions.countBailouts) {
29892992
for (let i = 0; i < BailoutReasonNames.length; i++) {

0 commit comments

Comments
 (0)