erikrose opened PR #14579 from erikrose:interrupt-poll-instruction to bytecodealliance:main:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind.
erikrose updated PR #14579.
erikrose updated PR #14579.
github-actions[bot] added the label cranelift on PR #14579.
github-actions[bot] added the label cranelift:area:aarch64 on PR #14579.
github-actions[bot] added the label cranelift:area:x64 on PR #14579.
github-actions[bot] added the label cranelift:area:machinst on PR #14579.
github-actions[bot] added the label cranelift:docs on PR #14579.
github-actions[bot] added the label cranelift:meta on PR #14579.
github-actions[bot] added the label wasmtime:api on PR #14579.
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind.
erikrose updated PR #14579.
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind. Other names I considered include "preempt_poll" (but it ultimately functions cooperatively, so nah), "yield_poll" (too tightly coupled to the one use case I'm chasing right now), and "probe" instead of "poll". HotSpot uses "poll" for their mechanism, so that'll be familiar to some, and it carries a little bit more meaning (repeatedly doing something).
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from next time
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind. Other names I considered include "preempt_poll" (but it ultimately functions cooperatively, so nah), "yield_poll" (too tightly coupled to the one use case I'm chasing right now), and "probe" instead of "poll". HotSpot uses "poll" for their mechanism, so that'll be familiar to some, and it carries a little bit more meaning (repeatedly doing something).
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from next time
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind. Other names I considered include "preempt_poll" (but it ultimately functions cooperatively, so nah), "yield_poll" (too tightly coupled to the one use case I'm chasing right now), and "probe" instead of "poll". HotSpot uses "poll" for their mechanism, so that'll be familiar to some, and it usefully suggests that it will have to be done repeatedly in the usual case.
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from next time
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind. Other names I considered include "preempt_poll" (but it ultimately functions cooperatively, so nah), "yield_poll" (too tightly coupled to the one use case I'm chasing right now), and "probe" instead of "poll". HotSpot uses "poll" for their mechanism, so that'll be familiar to some, and it usefully suggests that it will have to be done repeatedly in the usual case.
I recommend reviewing this commit-by-commit.
erikrose has marked PR #14579 as ready for review.
erikrose requested alexcrichton for a review on PR #14579.
erikrose requested wasmtime-compiler-reviewers for a review on PR #14579.
erikrose requested wasmtime-wasi-reviewers for a review on PR #14579.
erikrose requested wasmtime-core-reviewers for a review on PR #14579.
fitzgen requested cfallin for a review on PR #14579.
erikrose updated PR #14579.
erikrose edited PR #14579:
This is the first step toward implementing MMU-triggered interruption of Wasm (originally suggested in #1749). It's the first little PR broken off the large #12990 for ease of review.
This PR introduces a Cranelift instruction that facilitates resumeable preemptions: in this case, with MMU-based Wasm interruption in mind. However, the same technique is used by HotSpot for stop-the-world GC, so there is potential for other applications. A good place to start is this description.
The original name for this instruction was
dead_load_with_context. At the time, that was sufficiently descriptive. However, since then, we've added…
- Reserving a second register as scratch space for trampolining
- Returning a new ptr to load from next time
Thus, it's become specialized enough to the task of implementing virtual-memory-triggered interruption mechanisms that it makes sense to rename it with that in mind. Other names I considered include "preempt_poll" (but it ultimately functions cooperatively, so nah), "yield_poll" (too tightly coupled to the one use case I'm chasing right now), and "probe" instead of "poll". HotSpot uses "poll" for their mechanism, so that'll be familiar to some, and it usefully suggests that it will have to be done repeatedly in the usual case.
I recommend reviewing this commit-by-commit.
:memo: cfallin submitted PR review:
Thanks -- a bunch of comments on how this is documented/described below (but that's the main task here, to define a clean semantics for the IR operator). Overall shape seems fine.
:speech_balloon: cfallin created PR review comment:
"All current backends (x64 and aarch64)" seems wrong here, since Cranelift has more backends than that.
Also I don't think we want to specify details of the register allocation here, unless we want that to become part of the instruction definition/contract.
Finally this description should say more about
next_load_ptr's semantics. When resuming, is that pointer then loaded instead? Or is it just the output (defined value) of this instruction, to be used however the user of this instruction wants?In other words: let's think carefully about defining this as an instruction with well-defined semantics, rather than describing the whole machinery (instruction and its "canonical use") in this one comment.
It might help to define this with pseudocode. Is something like this correct?:
ABI-defined context reg := context <discard> := memory[load_ptr] result := ABI-defined next-load-ptr reg
:speech_balloon: cfallin created PR review comment:
Don't say
task_switch_trampolinehere -- Cranelift should not know or care about (or depend on) the particular way that Wasmtime uses this instruction.
:speech_balloon: cfallin created PR review comment:
I'm not sure I understand this comment -- what do you mean by "conceptually flow in the other direction"?
:speech_balloon: cfallin created PR review comment:
Let's fix the indentation here.
:speech_balloon: cfallin created PR review comment:
Another thought: to clarify the interface between the different moving parts and decouple the instruction from the use-case, it might help to rename the ABI regs. Maybe "context input" and "context output" (for
contextandnext_load_ptrrespectively)?
:speech_balloon: cfallin created PR review comment:
Finally: what do the semantics say about
next_load_ptrif the load doesn't trap? Is the value justload_ptr?So then is it something like this?
ABI-defined context reg := context ABI-defined next-load-ptr reg := load_ptr <discard> := memory[load_ptr] result := ABI-defined next-load-ptr reg
:speech_balloon: cfallin created PR review comment:
Similar comment here as in the aarch64 case.
:speech_balloon: cfallin created PR review comment:
This test only tests the IR verifier; let's add compile tests for x64 and aarch64 to lock down the lowerings (so we see if they change/break later) as well.
:speech_balloon: cfallin created PR review comment:
Not just "for efficiency" but necessary for the instruction semantics to be coherent, right? Otherwise nothing would write the "result" (defined SSA value) of the instruction in the non-trapping case.
Last updated: Oct 11 2026 at 04:10 UTC