Uh oh!
There was an error while loading. Please reload this page.
Virtual methods with runtime async - #121443
Conversation
This makes virtual methods work with runtime async. Depends on dotnet#121438. Runtime async methods can be virtually called two ways: as Task-returning, or as runtime-async. We can even end up in situation where Task-returning non-runtime-async virtual methods get called as runtime-async. The easiest way to solve this is to give each Task-returning method two separate virtual slots. We still track the slot use so unused slots will not get generated. The `VirtualMethodAlgorithm` abstraction that we added for universal shared generics comes in handy because it lets us centralize where all of this work happens. As a result, we don't need to teach pretty much any node dealing with virtuals about runtime async, it just falls out. This doesn't make generic virtual methods yet, those need more fixes.
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
There was a problem hiding this comment.
Pull Request Overview
This PR enhances the compiler type system context to support async-aware virtual method resolution. The key changes introduce a custom AsyncAwareVirtualMethodResolutionAlgorithm that handles async variant methods during virtual method dispatch, replacing the basic MetadataVirtualMethodAlgorithm in the AOT compilation path while maintaining the simple algorithm for ReadyToRun.
Key Changes:
- Implements async-aware virtual method resolution algorithm that properly handles async variant methods during virtual dispatch
- Adds support for EmitAsyncMethodThunk to generate thunks for async calling conventions
- Fixes the
IsAsyncVariantextension method to properly check method definitions
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ReadyToRunCompilerContext.cs | Adds MetadataVirtualMethodAlgorithm field to ReadyToRun compiler context partial class |
| CompilerTypeSystemContext.Aot.cs | Adds AsyncAwareVirtualMethodResolutionAlgorithm field initialization for AOT scenarios |
| CompilerTypeSystemContext.cs | Removes the base MetadataVirtualMethodAlgorithm field (moved to specific contexts) |
| CompilerTypeSystemContext.Async.cs | Implements AsyncAwareVirtualMethodResolutionAlgorithm and GetTargetOfAsyncVariantMethod helper |
| AsyncThunks.cs | Adds EmitAsyncMethodThunk method to generate async thunks (currently throws NotSupportedException) |
| NativeAotILProvider.cs | Replaces TODO with call to EmitAsyncMethodThunk for async variant implementations |
| AsyncMethodVariant.cs | Fixes IsAsyncVariant to check method definition instead of instance type |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
jkotas
commented
Nov 8, 2025
Failures look related |
MichalStrehovsky
commented
Nov 8, 2025
/ba-g android timeouts |
This makes virtual methods work with runtime async. Depends on #121438.
Runtime async methods can be virtually called two ways: as Task-returning, or as runtime-async. We can even end up in situation where Task-returning non-runtime-async virtual methods get called as runtime-async.
The easiest way to solve this is to give each Task-returning method two separate virtual slots. We still track the slot use so unused slots will not get generated.
The
VirtualMethodAlgorithmabstraction that we added for universal shared generics comes in handy because it lets us centralize where all of this work happens. As a result, we don't need to teach pretty much any node dealing with virtuals about runtime async, it just falls out.This doesn't make generic virtual methods yet, those need more fixes.
Cc @dotnet/ilc-contrib