-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Use EcmaMethod as the async "impl" variant and create async "thunk" MethodDesc classes #121218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…sc classes - EcmaMethod represents the variant encoded in metadata, either async or Task-returning. The Signature is adjusted accordingly to align with the calling convention. - AsyncMethodDesc is replaced with AsyncMethodThunk, which is the Async variant thunk of a Task-returning implementation method. - TaskReturningAsyncThunk is the variant of an async implementation method - AsyncMethodData was borrowed from the runtime implementation and added to the managedTypeSystem. - IsTaskReturning is now on MethodDesc and uses the AsyncMethodData to determine whether the type returns Task/ValueTask. It has different semantics than the runtime method of the same name, as this returns true for Async methods too. - GetAsyncOtherVariant() is also borrowed from the runtime implementation. This makes the factory unnecessary, as the unique "other variant" can be retrieved from the definition without creating a new instance each time.
There was a problem hiding this 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 refactors the async method handling infrastructure in the CoreCLR AOT compiler's type system. It moves async method variant management from the JIT interface layer into the core type system, making async method thunks first-class citizens with proper lifetimes.
Key changes:
- Moved async method thunk creation from
JitInterfaceto the core type system with newAsyncMethodThunkandTaskReturningAsyncThunkclasses - Introduced
AsyncMethodDataandAsyncMethodKindto track method async characteristics and signatures - Updated
EcmaMethod,MethodForInstantiatedType, andInstantiatedMethodto support async variant tracking
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| ILCompiler.TypeSystem.csproj | Adds new async thunk source files to the project |
| ILCompiler.ReadyToRun.csproj | Removes old JitInterface async method files |
| EcmaMethod.cs | Adds async method data tracking and variant generation, reformats constants |
| TaskReturningAsyncThunk.cs | New thunk class for async-callable variants of Task-returning methods |
| MethodForInstantiatedType.cs | Adds async variant support for instantiated type methods |
| MethodDesc.cs | Adds core async infrastructure: ReturnsTaskOrValueTask(), CreateAsyncSignature(), AsyncMethodData, AsyncMethodKind, GetAsyncOtherVariant() |
| MethodDelegator.cs | Makes AsyncMethodData abstract for delegator implementations |
| InstantiatedMethod.cs | Adds async variant support for generic method instantiations |
| AsyncMethodThunk.cs | New thunk class for async variants of Task-returning methods |
| AsyncMethodDescFactory.cs | Deleted - factory no longer needed with new approach |
| AsyncMethodDesc.cs | Deleted - replaced by new thunk classes in type system |
src/coreclr/tools/Common/TypeSystem/Common/TaskReturningAsyncThunk.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/TypeSystem/Common/TaskReturningAsyncThunk.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/TypeSystem/Common/TaskReturningAsyncThunk.cs
Outdated
Show resolved
Hide resolved
src/coreclr/tools/Common/TypeSystem/Common/InstantiatedMethod.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 11 out of 11 changed files in this pull request and generated 2 comments.
src/coreclr/tools/Common/TypeSystem/Common/TaskReturningAsyncThunk.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 23 out of 23 changed files in this pull request and generated 1 comment.
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Diagnostics; |
Copilot
AI
Oct 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing using System.Threading; directive. The code uses Interlocked.CompareExchange on line 46 but doesn't import the System.Threading namespace. While the main InstantiatedMethod.cs file has this import, partial class files need their own using directives for the types they reference.
| using System.Diagnostics; | |
| using System.Diagnostics; | |
| using System.Threading; |
|
What considerations lead to turning This is not the first time we're in a situation where a single method can have different entrypoints with different signature. We have similar situation with unboxing thunks (R2R + NAOT), instantiating thunks (R2R), special default interface method instantiating thunks (NAOT), or even p/invokes (NAOT, distinguishing the marshalled and "naked" entrypoints), In the CoreCLR type system the distinction between "entry point" and "method" is kind of fuzzy (even before async) - it's all kinds of In our managed compilers, we represent entry points using For example, with unboxing thunks, most of the system doesn't care about their existence. Some parts of the system deal with them by carrying a pair of In native AOT, there's also an instantiating unboxing runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs Lines 23 to 30 in 9ebda3d
This one also exists, but its existence is pretty limited because very few components will get to the It was added in dotnet/corert#2566 and the implementation is still pretty much the same. The runtime async methods look like normal method when looking at them in IL. The callsites to them look regular. They are weird when one looks at the method body. So my instinct would be not to make Resolving a MemberRef that was created before runtime async into a definition that is runtime async will need special casing in signature comparisons: runtime/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs Lines 321 to 336 in 9ebda3d
Reflection metadata generation will need to undo the async transform: runtime/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs Lines 159 to 178 in 9ebda3d
We'll need to special case async in virtual method resolution. Etc. My initial instinct would be to leave the metadata as it is in the IL file and make very local Line 964 in 9ebda3d
|
| _metadataSignature = signature; | ||
| } | ||
|
|
||
| public override MethodSignature Signature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @MichalStrehovsky . This should stay as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The managed type system "features" have been designed as incremental. E.g. adding *CodeGen* or *Sorting* does not change how any of the core methods work. This change would be violating this design.
Previously, AsyncMethodDesc was used to represent the Async variant of a method with IsAsync==true, regardless of what was in metadata. I think it makes more sense to use EcmaMethod to represent what is in metadata, and create two MethodDescs to represent the Async and Task-returning thunk variants.