- 
                Notifications
    
You must be signed in to change notification settings  - Fork 5.2k
 
Rename AsyncMethodDesc to AsyncMethodVariant, add "AsyncVariant" flag to MethodWithToken and MethodWithGCInfo #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.
| READYTORUN_METHOD_SIG_Constrained = 0x20, | ||
| READYTORUN_METHOD_SIG_OwnerType = 0x40, | ||
| READYTORUN_METHOD_SIG_UpdateContext = 0x80, | ||
| READYTORUN_METHOD_SIG_AsyncThunkVariant = 0x100, | 
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.
Should this be just AsyncVariant (ie cover both Thunk or impl)?
This enum is part of R2R file format. It is used to encode references to methods in other assemblies. This encoding should be resilient to compatible changes in the implementation of other assemblies. If we encode AsyncThunkVariant here, it does not sound like we will be resilient to the implementations in other assemblies changing between async v1 and async v2.
| 
               | 
          ||
| using System; | ||
| using System.Diagnostics; | ||
| using System.Threading; | 
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.
Are the changes in this file still needed?
AsyncMethodVariantis isolated to CorInfoImpl.cs and only used in jit compilation.MethodWithGCInfoandMethodWithToken(Code and R2R method signature providing nodes, respectively) have an additionalAsyncVariantflag. When constructed in CorInfoImpl, anAsyncMethodVariantinstance should unwrap the underlying method and passAsyncVariant=true.AsyncMethodKind is also added to MethodDesc to determine whether the method is AsyncCallConv or not, TaskReturning or void-returning, and thunk or impl.