erikrose opened PR #12990 from erikrose:epoch-mmu to bytecodealliance:main:
This is an implementation of #1749, specifically @cfallin's roadmap, with the goal of reducing the overhead of checking for the end of epochs.
Paul ran some benchmarks on this (broadly agreeing with our real-world experiments) which tell us:
- Current compare-against-a-deadline
-Wepoch-interruption=yis a 14.4% hit versus doing nothing.- Doing only dead loads in function prologues and loop headers (which were all that was implemented in this patch at the time of the bench) brings that down to a 2.8% hit. There will be some additional hit from the signal handler that actually effects the task switch, but that's on the cold path.
The above numbers are from SpiderMonkey, which I deem the most representative benchmark.
Status:
- [X] Add unmapped-on-interrupt page and pointer to it in vmctx.
- [X] Add method for embedder to call to bring an epoch to a close.
- [X] Add
DeadLoadWithContextCranelift instruction, and use it.- [ ] Have
DeadLoadWithContextemit metadata into compiled-artifact tables to tell the signal handler this is an interruption-point load.- [ ] Add logic to signal handler that, when seeing such a PC, updates state to redirect to the stub, saving the original PC (probably in the scratch register).
- [ ] Add that stub, which saves all register state and invokes a hostcall with the recovered vmctx.
If the TLB shootdown arising from the frobbing of privs on the "interrupt page" proves too expensive, we can try a more indirect load instead, where, instead of messing with page privs, we mess with the address we're dead-loading from so it points to either a (statically) allowed or forbidden page. (Chris floated this idea at the 2026-04-08 Cranelift meeting.) Not many of the other mechanics need change.
github-actions[bot] added the label cranelift on PR #12990.
github-actions[bot] added the label cranelift:area:x64 on PR #12990.
github-actions[bot] added the label cranelift:area:machinst on PR #12990.
github-actions[bot] added the label cranelift:docs on PR #12990.
github-actions[bot] added the label wasmtime:config on PR #12990.
github-actions[bot] added the label wasmtime:api on PR #12990.
github-actions[bot] added the label cranelift:meta on PR #12990.
github-actions[bot] commented on PR #12990:
Label Messager: wasmtime:config
It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:
[ ] If you added a new
Configmethod, you wrote extensive documentation for
it.<details>
Our documentation should be of the following form:
```text
Short, simple summary sentence.More details. These details can be multiple paragraphs. There should be
information about not just the method, but its parameters and results as
well.Is this method fallible? If so, when can it return an error?
Can this method panic? If so, when does it panic?
Example
Optional example here.
```</details>
[ ] If you added a new
Configmethod, or modified an existing one, you
ensured that this configuration is exercised by the fuzz targets.<details>
For example, if you expose a new strategy for allocating the next instance
slot inside the pooling allocator, you should ensure that at least one of our
fuzz targets exercises that new strategy.Often, all that is required of you is to ensure that there is a knob for this
configuration option in [wasmtime_fuzzing::Config][fuzzing-config] (or one
of its nestedstructs).Rarely, this may require authoring a new fuzz target to specifically test this
configuration. See [our docs on fuzzing][fuzzing-docs] for more details.</details>
[ ] If you are enabling a configuration option by default, make sure that it
has been fuzzed for at least two weeks before turning it on by default.[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html
<details>
To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.
To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.</details>
erikrose updated PR #12990.
erikrose edited PR #12990:
This is an implementation of #1749, specifically @cfallin's roadmap, with the goal of reducing the overhead of checking for the end of epochs.
Paul ran some benchmarks on this (broadly agreeing with our real-world experiments) which tell us:
- Current compare-against-a-deadline
-Wepoch-interruption=yis a 14.4% hit versus doing nothing.- Doing only dead loads in function prologues and loop headers (which were all that was implemented in this patch at the time of the bench) brings that down to a 2.8% hit. There will be some additional hit from the signal handler that actually effects the task switch, but that's on the cold path.
The above numbers are from SpiderMonkey, which I deem the most representative benchmark.
Status:
- [X] Add unmapped-on-interrupt page and pointer to it in vmctx.
- [X] Add method for embedder to call to bring an epoch to a close.
- [X] Add
DeadLoadWithContextCranelift instruction, and use it.- [x] Have
DeadLoadWithContextemit metadata into compiled-artifact tables to tell the signal handler this is an interruption-point load.- [ ] Add logic to signal handler that, when seeing such a PC, updates state to redirect to the stub, saving the original PC (probably in the scratch register).
- [ ] Add that stub, which saves all register state and invokes a hostcall with the recovered vmctx.
If the TLB shootdown arising from the frobbing of privs on the "interrupt page" proves too expensive, we can try a more indirect load instead, where, instead of messing with page privs, we mess with the address we're dead-loading from so it points to either a (statically) allowed or forbidden page. (Chris floated this idea at the 2026-04-08 Cranelift meeting.) Not many of the other mechanics need change.
Last updated: Apr 13 2026 at 00:25 UTC