Skip to content

Commit 5f91722

Browse files
authored
Optimize a test exercising Cranelift's limits (#9637)
This is a test which generates a wasm function that exceeds Cranelift's limits of virtual registers. Previously in debug mode this test took upwards of 40 seconds to execute and now it takes around 5. The main optimization here was to disable Cranelift optimizations. The test has also been updated to generate the module with `wasm-encoder` instead of `wast` to skip the text parsing step too.
1 parent 8995bcc commit 5f91722

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ object = { workspace = true, features = ['std'] }
121121
wasmtime-test-macros = { path = "crates/test-macros" }
122122
pulley-interpreter = { workspace = true, features = ["disas"] }
123123
wasmtime-wast-util = { path = 'crates/wast-util' }
124+
wasm-encoder = { workspace = true }
124125

125126
[target.'cfg(windows)'.dev-dependencies]
126127
windows-sys = { workspace = true, features = ["Win32_System_Memory"] }

tests/all/code_too_large.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,59 @@
11
#![cfg(not(miri))]
22

3+
use wasm_encoder::Instruction as I;
34
use wasmtime::*;
45

56
#[test]
67
fn code_too_large_without_panic() -> Result<()> {
7-
const N: usize = 120000;
8+
const N: usize = 80000;
89

910
// Build a module with a function whose body will allocate too many
1011
// temporaries for our current (Cranelift-based) compiler backend to
1112
// handle. This test ensures that we propagate the failure upward
1213
// and return it programmatically, rather than panic'ing. If we ever
1314
// improve our compiler backend to actually handle such a large
1415
// function body, we'll need to increase the limits here too!
15-
let mut s = String::new();
16-
s.push_str("(module\n");
17-
s.push_str("(table 1 1 funcref)\n");
18-
s.push_str("(func (export \"\") (result i32)\n");
19-
s.push_str("i32.const 0\n");
16+
let mut module = wasm_encoder::Module::default();
17+
18+
let mut types = wasm_encoder::TypeSection::new();
19+
types.ty().function([], [wasm_encoder::ValType::I32]);
20+
module.section(&types);
21+
22+
let mut funcs = wasm_encoder::FunctionSection::new();
23+
funcs.function(0);
24+
module.section(&funcs);
25+
26+
let mut tables = wasm_encoder::TableSection::new();
27+
tables.table(wasm_encoder::TableType {
28+
element_type: wasm_encoder::RefType::FUNCREF,
29+
table64: false,
30+
minimum: 1,
31+
maximum: Some(1),
32+
shared: false,
33+
});
34+
module.section(&tables);
35+
36+
let mut exports = wasm_encoder::ExportSection::new();
37+
exports.export("", wasm_encoder::ExportKind::Func, 0);
38+
module.section(&exports);
39+
40+
let mut func = wasm_encoder::Function::new([]);
41+
func.instruction(&I::I32Const(0));
2042
for _ in 0..N {
21-
s.push_str("table.get 0\n");
22-
s.push_str("ref.is_null\n");
43+
func.instruction(&I::TableGet(0));
44+
func.instruction(&I::RefIsNull);
2345
}
24-
s.push_str("))\n");
46+
func.instruction(&I::End);
47+
let mut code = wasm_encoder::CodeSection::new();
48+
code.function(&func);
49+
module.section(&code);
50+
51+
let mut config = Config::new();
52+
config.cranelift_opt_level(OptLevel::None);
53+
let engine = Engine::new(&config)?;
2554

26-
let store = Store::<()>::default();
27-
let result = Module::new(store.engine(), &s);
55+
let store = Store::new(&engine, ());
56+
let result = Module::new(store.engine(), &module.finish());
2857
match result {
2958
Err(e) => assert!(e
3059
.to_string()

0 commit comments

Comments
 (0)