Skip to content

Add wasmtime hot-blocks subcommand#13077

Merged
fitzgen merged 7 commits intobytecodealliance:mainfrom
fitzgen:wasmtime-hot-blocks
Apr 14, 2026
Merged

Add wasmtime hot-blocks subcommand#13077
fitzgen merged 7 commits intobytecodealliance:mainfrom
fitzgen:wasmtime-hot-blocks

Conversation

@fitzgen
Copy link
Copy Markdown
Member

@fitzgen fitzgen commented Apr 13, 2026

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

Depends on #13073

fitzgen added 2 commits April 13, 2026 12:08
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`.
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
```
@fitzgen fitzgen requested review from a team as code owners April 13, 2026 19:39
@fitzgen fitzgen requested review from a team, cfallin and pchickey and removed request for a team April 13, 2026 19:39
fitzgen added 2 commits April 13, 2026 13:04
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.
Copy link
Copy Markdown
Member

@cfallin cfallin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable overall -- with my level of review on all of the output-parsing code calibrated at "this is a useful tool for developers" rather than "production-ready robustness".

A thought below but otherwise I'm happy to see this in-tree for its usefulness. Thanks!

Comment thread src/commands/hot_blocks.rs Outdated
Comment thread src/commands/hot_blocks.rs
@github-actions github-actions Bot added the wasmtime:api Related to the API of the `wasmtime` crate itself label Apr 13, 2026
@fitzgen fitzgen requested a review from cfallin April 14, 2026 14:29
Copy link
Copy Markdown
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Stray thought on this: could debuginfo factor into this as well during rendering? For example at minimum this could print the hex offset in wasm which could then be passed to wasm-tools addr2line, but at most it could run addr2line here in-process and print some information. If it's not easy to add though probably not worth it

@fitzgen
Copy link
Copy Markdown
Member Author

fitzgen commented Apr 14, 2026

Stray thought on this: could debuginfo factor into this as well during rendering? For example at minimum this could print the hex offset in wasm which could then be passed to wasm-tools addr2line, but at most it could run addr2line here in-process and print some information. If it's not easy to add though probably not worth it

Sure, I can investigate this in a follow up. Are you imagining, when we have debuginfo available, output that loks something like this?

 [Samples]   [Assembly]                 [CLIF]                       [Wasm]
    14.07%   add     esi, 1             -                            -
    21.29%   lea     ecx, [rax + rdi]   v14 = iadd.i32 v13, v12      0x12 fib fib.rs:12:4

@fitzgen
Copy link
Copy Markdown
Member Author

fitzgen commented Apr 14, 2026

Hm or maybe something like objdump's mixed source and asm disassembly? That way we could still see the actual Wasm instructions.

@fitzgen fitzgen added this pull request to the merge queue Apr 14, 2026
@alexcrichton
Copy link
Copy Markdown
Member

I was just thinking of source locations for now, so no need to read files on disk and intermingle in source code just yet. What you sketched sounds reasoanble to me!

@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 14, 2026
@fitzgen fitzgen enabled auto-merge April 14, 2026 16:53
@fitzgen fitzgen added this pull request to the merge queue Apr 14, 2026
Merged via the queue into bytecodealliance:main with commit a95057c Apr 14, 2026
48 checks passed
@fitzgen fitzgen deleted the wasmtime-hot-blocks branch April 14, 2026 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants