Uh oh!
There was an error while loading. Please reload this page.
Implement computed goto dispatch for the CoreCLR interpreter - #129216
Conversation
BrzVlad
commented
Jun 10, 2026
/azp run runtime-interpreter |
|
Azure Pipelines successfully started running 1 pipeline(s). |
BrzVlad
commented
Jun 10, 2026
/azp run runtime-libraries-interpreter |
|
Azure Pipelines successfully started running 1 pipeline(s). |
BrzVlad
commented
Jun 11, 2026
Assembly before Assembly after |
Instead of making each opcode dispatch to the loop start where we switch on the opcode, we transform every switch case into a label, we let the compiler statically populate the s_dispatchTable which maps each opcode to the label address. This makes opcode dispatch a simple load + branch to the label address from this table. This makes the interpreter 25% faster. It is unclear whether this has any impact on wasm. Likely not, because wasm has control flow limitations that make random branches impossible.
Removing this can improve execution speed by around 3%. Instead we explicitly save pFrame->ip in opcodes that can trigger GC or throw exception. Add InterpThrow helper to ensure pFrame->ip is set before all throws.
1f2bd0a to
e39e619CompareBrzVlad
commented
Jun 17, 2026
/azp run runtime-interpreter |
|
No pipelines are associated with this pull request. |
BrzVlad
commented
Jun 17, 2026
/azp run runtime-interpreter |
|
Azure Pipelines successfully started running 1 pipeline(s). |
BrzVlad
commented
Jun 17, 2026
/azp run runtime-libraries-interpreter |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
BrzVlad
commented
Jun 18, 2026
/ba-g unrelated timeouts in non-interpreter jobs |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
We disable this on windows where vc compiler doesn't supported it.
If we ever get to interpreting an invalid opcode, the most likely value would be 0. Having this opcode do random operations (like returning from the frame as it was the case before with INTOP_RET having the 0 value) could make it harder to diagnose this types of bugs if they will ever appear in the future. On mono we've had multiple cases where we were trying to execute code from invalid memory, hitting this case.
BrzVlad
commented
Jun 23, 2026
Could I get a final review on this ? @janvorli your previous review got stale after a rebase. |
BrzVlad
commented
Jun 23, 2026
/ba-g non-interpreter failures |
Uh oh!
There was an error while loading. Please reload this page.
Instead of making each opcode dispatch to the loop start where we switch on the opcode, we transform every switch case into a label, we let the compiler statically populate the s_dispatchTable which maps each opcode to the label address. This makes opcode dispatch a simple load + branch to the label address from this table. This makes the interpreter 25% faster. It is unclear whether this has any impact on wasm. Likely not, because wasm has control flow limitations that make random branches impossible. As an additional optimization, we avoid saving `pFrame->ip` for each opcode. Removing this can improve execution speed by around 3%. Instead we explicitly save `pFrame->ip` in opcodes that can trigger GC or throw exception. Add InterpThrow helper to ensure `pFrame->ip` is set before all throws.
Instead of making each opcode dispatch to the loop start where we switch on the opcode, we transform every switch case into a label, we let the compiler statically populate the s_dispatchTable which maps each opcode to the label address. This makes opcode dispatch a simple load + branch to the label address from this table. This makes the interpreter 25% faster.
It is unclear whether this has any impact on wasm. Likely not, because wasm has control flow limitations that make random branches impossible.
As an additional optimization, we avoid saving
pFrame->ipfor each opcode. Removing this can improve execution speed by around 3%. Instead we explicitly savepFrame->ipin opcodes that can trigger GC or throw exception. Add InterpThrow helper to ensurepFrame->ipis set before all throws.