JIT: Refactor async-to-sync call optimization#124798
Merged
jakobbotsch merged 11 commits intodotnet:mainfrom Feb 28, 2026
Merged
JIT: Refactor async-to-sync call optimization#124798jakobbotsch merged 11 commits intodotnet:mainfrom
jakobbotsch merged 11 commits intodotnet:mainfrom
Conversation
- Introduce `getAsyncOtherVariant` JIT-EE API that returns the other async variant of an async/task-returning method - Remove the `AwaitVirtual` token kind that was used to allow the VM to tell the JIT to prefer a task-returning instead of async variant - Implement the same optimization on the JIT side instead using the `getAsyncOtherVariant`, when we notice that a call will be direct Fix dotnet#124545
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors the async-to-sync call optimization by removing VM-driven “prefer task-returning for direct calls” token handling and moving the decision logic into the JIT using a new JIT↔EE API (getAsyncOtherVariant).
Changes:
- Add
ICorJitInfo::getAsyncOtherVariantAPI and plumb it through VM, JIT wrappers, NativeAOT JIT interface, and SuperPMI record/replay. - Remove
CORINFO_TOKENKIND_AwaitVirtualand simplify await token resolution to always request the async variant from the VM. - Teach the JIT importer to switch back to the synchronous Task-returning call for direct calls when the async variant is a thunk.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/jitinterface.cpp | Removes AwaitVirtual-specific resolution logic; adds EE implementation of getAsyncOtherVariant. |
| src/coreclr/jit/importer.cpp | Implements JIT-side “avoid thunk for direct calls” logic using getAsyncOtherVariant. |
| src/coreclr/jit/ee_il_dll.hpp | Replaces combine(...) helper with CORINFO_CALLINFO_FLAGS `operator |
| src/coreclr/inc/corinfo.h | Removes CORINFO_TOKENKIND_AwaitVirtual; adds ICorStaticInfo::getAsyncOtherVariant. |
| src/coreclr/inc/icorjitinfoimpl_generated.h | Declares the new EE-side virtual method override. |
| src/coreclr/inc/jiteeversionguid.h | Updates the JIT/EE interface version GUID for the API shape change. |
| src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp | Adds wrapper forwarding for getAsyncOtherVariant. |
| src/coreclr/jit/ICorJitInfo_names_generated.h | Adds name for the new API. |
| src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp | Adds SuperPMI ICJI forwarding/recording hook. |
| src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp | Adds shim forwarding for the new API. |
| src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp | Adds shim call counting + forwarding for the new API. |
| src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp | Records/replays getAsyncOtherVariant including variantIsThunk. |
| src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h | Adds record/replay declarations + packet ID for getAsyncOtherVariant. |
| src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp | Implements record/replay storage for getAsyncOtherVariant. |
| src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h | Adds LWM map entry for GetAsyncOtherVariant. |
| src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt | Adds new API to thunk generator inputs. |
| src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | Removes CORINFO_TOKENKIND_AwaitVirtual from managed enum mirror. |
| src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs | Adds unmanaged callback plumbing for getAsyncOtherVariant. |
| src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | Updates await-token handling; adds (currently stubbed) getAsyncOtherVariant managed implementation. |
| src/coreclr/tools/aot/jitinterface/jitinterface_generated.h | Adds callback pointer + wrapper method for getAsyncOtherVariant. |
| src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs | Removes NativeAOT scanner-side “avoid thunk for direct calls” logic. |
| src/coreclr/interpreter/compiler.cpp | Removes AwaitVirtual usage in interpreter async-call peep token resolution. |
| src/coreclr/tools/aot/ilc.slnx | Adds ILLink.CodeFixProvider project to the solution. |
| src/coreclr/tools/aot/crossgen2.slnx | Adds ILLink.CodeFixProvider project to the solution. |
This was referenced Feb 24, 2026
This was referenced Feb 25, 2026
janvorli
approved these changes
Feb 26, 2026
Member
janvorli
left a comment
There was a problem hiding this comment.
LGTM (I haven't looked at the JIT changes), I have just few nits.
davidwrighton
approved these changes
Feb 26, 2026
Member
Author
|
/ba-g No space left on device |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
getAsyncOtherVariantJIT-EE API that returns the other async variant of an async/task-returning methodAwaitVirtualtoken kind that was used to allow the VM to tell the JIT to prefer a task-returning instead of async variantgetAsyncOtherVariant, when we notice that a call will be directActiveIssueasync EH tests under interpreter against Crash inToString_Asynctest on Apple mobile with CoreCLR R2R and interpreter #124044Fix #124545