Skip to content

Conversation

@jtschuster
Copy link
Member

@jtschuster jtschuster commented Dec 18, 2025

Emits Task-returning async method thunks in crossgen2 as MethodSignatures with the AsyncVariant flag set

Adds GetPrimaryMethodDesc to get the most natural "primary" method desc for MethodDesc's that point to the same Ecma/Instantiated method. This is used in the places where we cast to EcmaMethod to get relevant metadata information.

GCRefMap emission also needed to be updated to account for the continuation parameter. Runtime's FakeGcScanRoots (used to verify the ReadyToRun images GCRefMap in debug config) also needed to updated to handle the continuation parameter.

In R2R exception info clauses, a new flag is added to use when the handler catches System.Exception. It's not guaranteed that a token for System.Exception exists in the context of the EH info struct, and there is no equivalent of a module override for the structs.

In the MethodWithToken constructor, it's expected that callers pass the Token that points to the exact method that is being called on the correct instantiated type. It's again not guaranteed that we have valid tokens for the method being called in the context of an instantiated type (technically any call to G<MyClass>.M() will have a token for G, but when we compile the canonicalize method, we call the async G<!0>.M() in the IL, and we don't have a token for G<!0>). For this reason, we wrap the MethodIL in a ManifestModuleWrappedMethodIL, and when we construct a MethodWithToken, we resolve the OwningType with the MutableModule token, but swap out the Token for the typical method definition token and force emission of a full MethodSignature in the Fixup.

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

This PR implements support for emitting Task-returning async method thunks in crossgen2 by encoding them as MethodSignatures with the AsyncVariant flag set. The changes introduce a new GetPrimaryMethodDesc helper method to navigate between different MethodDesc variants (async, unboxing, P/Invoke) and their primary metadata representations. The GC reference map emission is updated to account for the additional async continuation parameter.

Key changes:

  • Adds AsyncVariant flag to ReadyToRunMethodSigFlags enum (requiring uint instead of byte to accommodate 0x100 value)
  • Implements GetPrimaryMethodDesc extension method to resolve various MethodDesc wrappers to their primary ECMA method
  • Updates ArgIterator and GCRefMapBuilder to handle async continuation parameter in both managed and native code
  • Modifies ReadyToRunILProvider to emit Task-returning thunks for async methods

Reviewed changes

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

Show a summary per file
File Description
src/coreclr/vm/frames.cpp Adds async continuation parameter handling in FakeGcScanRoots for GC scanning
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs Adds display support for ASYNC flag in method signatures
src/coreclr/tools/aot/ILCompiler.ReadyToRun/TypeSystem/MethodDescExtensions.cs New file introducing GetPrimaryMethodDesc helper to unwrap MethodDesc variants
src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs Updates token resolution to use GetPrimaryMethodDesc and removes version bubble checks
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj Adds new MethodDescExtensions.cs file to project
src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/ReadyToRunILProvider.cs Implements Task-returning async thunk emission for async methods
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs Updates module resolution to use GetPrimaryMethodDesc
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs Updates async variant assertion to use new helper method
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs Adds IsPrimaryMethodDesc check in debug code and minor formatting fix
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs Adds AsyncVariant flag emission in method signatures
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs Replaces unboxing check with IsPrimaryMethodDesc for fixup optimization
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapBuilder.cs Adds async continuation parameter to GC reference map generation
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs Implements async continuation argument offset calculation and allocation logic
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncResumptionStub.cs Exposes TargetMethod property for GetPrimaryMethodDesc navigation
src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs Changes ReadyToRunMethodSigFlags from byte to uint and adds AsyncVariant flag
src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs Adds GetAsyncVariant and GetTargetOfAsyncVariant extension methods

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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 16 out of 16 changed files in this pull request and generated no new comments.

@jkotas
Copy link
Member

jkotas commented Dec 19, 2025

/azp run runtime-coreclr crossgen2 outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jtschuster
Copy link
Member Author

/azp run runtime-coreclr crossgen2 outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jtschuster
Copy link
Member Author

/azp run runtime-coreclr crossgen2 outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jtschuster
Copy link
Member Author

/azp run runtime-coreclr crossgen2 outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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 1 comment.

- Clear ClassTokenOrOffset when setting R2R_SYSTEM_EXCEPTION flag
- Add COR_ILEXCEPTION_CLAUSE_R2R_SYSTEM_EXCEPTION to R2R dumper
@jtschuster
Copy link
Member Author

/azp run runtime-coreclr crossgen2 outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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 25 out of 25 changed files in this pull request and generated no new comments.

@jtschuster jtschuster requested a review from jkotas January 23, 2026 19:36
@jtschuster jtschuster enabled auto-merge (squash) January 24, 2026 00:31
@jtschuster
Copy link
Member Author

/ba-g timeout appears unrelated

@jtschuster jtschuster merged commit 1b15c7c into dotnet:main Jan 26, 2026
102 of 104 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants