Source code

Revision control

Copy as Markdown

Other Tools

// |jit-test| test-also=--setpref=wasm_lazy_tiering --setpref=wasm_lazy_tiering_synchronous; skip-if: wasmCompileMode() != "baseline+ion" || !getPrefValue("wasm_lazy_tiering")
// Tests the inliner on a recursive function, in particular to establish that
// the inlining heuristics have some way to stop the compiler looping
// indefinitely and, more constrainingly, that it has some way to stop
// excessive but finite inlining.
// `func $recursive` has 95 bytecode bytes. With module- and function-level
// inlining budgeting disabled, it is inlined into itself 1110 times,
// processing an extra 105450 bytecode bytes. This is definitely excessive.
//
// With budgeting re-enabled, it is inlined just 9 times, as intended.
let t = `
(module
(func $recursive (export "recursive") (param i32) (result i32)
(i32.le_u (local.get 0) (i32.const 1))
if (result i32)
(i32.const 1)
else
(i32.const 1)
(call $recursive (i32.sub (local.get 0) (i32.const 1)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 2)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 1)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 2)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 1)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 2)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 1)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 2)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 1)))
i32.add
(call $recursive (i32.sub (local.get 0) (i32.const 2)))
i32.add
end
)
)`;
let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(t)));
assertEq(i.exports.recursive(10), 14517361);
// This assertion will fail if there is runaway recursion, because the
// optimised compilation will run long and hence not be completed by the time
// the assertion is evaluated.
assertEq(wasmFunctionTier(i.exports.recursive), "optimized");