Skip to content

JIT: Refactor async-to-sync call optimization#124798

Open
jakobbotsch wants to merge 11 commits intodotnet:mainfrom
jakobbotsch:fix-static-virtuals-2
Open

JIT: Refactor async-to-sync call optimization#124798
jakobbotsch wants to merge 11 commits intodotnet:mainfrom
jakobbotsch:fix-static-virtuals-2

Conversation

@jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Feb 24, 2026

  • 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 ilc.slnx and crossgen2.slnx to compile from VS
  • ActiveIssue async EH tests under interpreter against Crash in ToString_Async test on Apple mobile with CoreCLR R2R and interpreter #124044

Fix #124545

- 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
Copilot AI review requested due to automatic review settings February 24, 2026 16:19
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 24, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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::getAsyncOtherVariant API and plumb it through VM, JIT wrappers, NativeAOT JIT interface, and SuperPMI record/replay.
  • Remove CORINFO_TOKENKIND_AwaitVirtual and 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.

Copilot AI review requested due to automatic review settings February 24, 2026 16:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 3 comments.

Copilot AI review requested due to automatic review settings February 25, 2026 14:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings February 26, 2026 12:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.

Copy link
Member

@janvorli janvorli left a comment

Choose a reason for hiding this comment

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

LGTM (I haven't looked at the JIT changes), I have just few nits.

// non-async task-returning call. There is no reason to create
// and go through the thunk.
ResolveToken(token, CORINFO_TOKENKIND_Method, &resolvedCallToken);
m_ip = origIP + 5;
Copy link
Member

Choose a reason for hiding this comment

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

It seems we don't need to save the origIP as at this point the m_ip would always be the same as origIP, unless I am mising something.

Copy link
Member Author

Choose a reason for hiding this comment

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

m_ip gets changed by AsyncCallPeeps.FindAndApplyPeep above -- this is undoing the change when we decide to not actually dispatch through the async call. Let me add a comment.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Static virtual calls go through task-returning thunks always

4 participants