Skip to content

Commit a95057c

Browse files
authored
Add wasmtime hot-blocks subcommand (#13077)
* Add `Component::{text,address_map,functions}` methods These are similar to the methods with the same names on `Module`. Also publicly export `ModuleFunction`, since it is returned by `Module::functions` (and now also `Component::functions`). Also publicly re-export `StaticModuleIndex` and `FuncIndex`, since they appear inside `ModuleFunction`. * Add `wasmtime hot-blocks` subcommand This commit adds a new `wasmtime hot-blocks` subcommand that profiles Wasm execution using `perf` and identifies the hottest basic blocks in the compiled Wasm code. Example output: ``` $ cargo run -- hot-blocks -F 999 -p 100 tests/all/cli_tests/fib.wat `fib` :: block 0x16 :: 81.62% total samples [Samples] [Assembly] [CLIF] [Wasm] 14.07% add esi, 1 - - 21.29% lea ecx, [rax + rdi] v14 = iadd.i32 v13, v12 i32.add 13.29% mov rdi, rax " " 17.64% mov rax, rcx " " 15.33% jmp 0xe jump block3(v18, v13, v14) br $loop `fib` :: block 0x0 :: 18.33% total samples [Samples] [Assembly] [CLIF] [Wasm] 18.33% cmp esi, edx brif v11, block2, block5 br_if $break jae 0x2a " " `wasm[0]::function[1]` :: block 0x37 :: 0.04% total samples [Samples] [Assembly] [CLIF] [Wasm] 0.04% add ebx, 1 - - jmp 0x6b jump block3(v14) br $loop ``` * Use RunCommon helpers and forward run flags in hot-blocks Replace direct CommonOptions usage with RunCommon, using its load_module helper and RunTarget enum to deserialize the compiled cwasm. This avoids duplicating the module/component detection and deserialization logic. Forward --dir, --env, -Wunknown-imports-trap, and -Wunknown-imports-default flags through to the nested `perf record` subprocess so the profiled execution honors WASI directory preopens, environment variables, and unknown import handling. * Fix `hot_blocks_fib` test on CI * Address review feedback * Fix clippy * Don't bother running `wasmtime hot-blocks` unit tests under MIRI
1 parent 80be8d6 commit a95057c

11 files changed

Lines changed: 1517 additions & 137 deletions

File tree

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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ tempfile = { workspace = true, optional = true }
7777
object = { workspace = true, optional = true }
7878
cranelift-codegen = { workspace = true, optional = true, features = ['disas'] }
7979
capstone = { workspace = true, optional = true }
80+
wasmprinter = { workspace = true, optional = true }
8081
termcolor = { workspace = true, optional = true }
8182
gimli = { workspace = true, optional = true }
8283
pulley-interpreter = { workspace = true, optional = true }
@@ -478,6 +479,7 @@ default = [
478479
"config",
479480
"completion",
480481
"objdump",
482+
"hot-blocks",
481483
"wizer",
482484

483485
# On-by-default WASI features
@@ -620,6 +622,11 @@ objdump = [
620622
'dep:gimli',
621623
'pulley-interpreter/disas',
622624
]
625+
hot-blocks = [
626+
'dep:capstone',
627+
'dep:tempfile',
628+
'dep:wasmprinter',
629+
]
623630
wizer = [
624631
"wasmtime-wizer",
625632
"dep:wasmtime-wasi",

src/bin/wasmtime.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ enum Subcommand {
9090
#[cfg(feature = "objdump")]
9191
Objdump(wasmtime_cli::commands::ObjdumpCommand),
9292

93+
/// Profile a Wasm module's execution and print the hottest basic blocks.
94+
#[cfg(all(feature = "hot-blocks", target_os = "linux"))]
95+
HotBlocks(wasmtime_cli::commands::HotBlocksCommand),
96+
9397
#[cfg(feature = "wizer")]
9498
Wizer(wasmtime_cli::commands::WizerCommand),
9599
}
@@ -130,6 +134,9 @@ impl Wasmtime {
130134
#[cfg(feature = "objdump")]
131135
Subcommand::Objdump(c) => c.execute(),
132136

137+
#[cfg(all(feature = "hot-blocks", target_os = "linux"))]
138+
Subcommand::HotBlocks(c) => c.execute(),
139+
133140
#[cfg(feature = "wizer")]
134141
Subcommand::Wizer(c) => c.execute(),
135142
}

src/commands.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ mod objdump;
4040
#[cfg(feature = "objdump")]
4141
pub use self::objdump::*;
4242

43+
#[cfg(all(feature = "hot-blocks", target_os = "linux"))]
44+
mod hot_blocks;
45+
#[cfg(all(feature = "hot-blocks", target_os = "linux"))]
46+
pub use self::hot_blocks::*;
47+
4348
#[cfg(feature = "wizer")]
4449
mod wizer;
4550
#[cfg(feature = "wizer")]

0 commit comments

Comments
 (0)