Skip to content

Add AsyncVariantLookup::ReturnDroppingThunk for parallel RDT lookup in FindOrCreateAssociatedMethodDesc#129442

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/enable-async-method-thunk-test
Draft

Add AsyncVariantLookup::ReturnDroppingThunk for parallel RDT lookup in FindOrCreateAssociatedMethodDesc#129442
Copilot wants to merge 3 commits into
mainfrom
copilot/enable-async-method-thunk-test

Conversation

Copilot AI commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

The assert !pPrimaryMD->IsReturnDroppingThunk() in FindOrCreateAssociatedMethodDesc fires for generic virtual methods with covariant return, when the primary MethodDesc is itself a ReturnDroppingThunk (RDT) and we need to look up a parallel RDT that differs only in something other than async kind (e.g. generic arguments). The instantiated-method-desc hash table also keyed on a single bool isAsyncVariant, which cannot distinguish a regular async variant from an RDT (both have IsAsyncVariantMethod() == true).

Changes

  • AsyncVariantLookup::ReturnDroppingThunk enum value (method.hpp) — matched only by methods where IsReturnDroppingThunk() is true. Existing Async continues to match only regular async variants (not RDTs).

  • MethodDesc::GetAsyncVariantLookup() helper — returns the lookup value matching a method's own async kind (Ordinary/Async/ReturnDroppingThunk).

  • Convenience overload of FindOrCreateAssociatedMethodDesc — replaces the _ASSERTE(!pPrimaryMD->IsReturnDroppingThunk()) with a 3-way selection of the variant lookup based on the primary MD:

    AsyncVariantLookup variantLookup = pPrimaryMD->IsReturnDroppingThunk() ? AsyncVariantLookup::ReturnDroppingThunk :
                                       pPrimaryMD->IsAsyncVariantMethod()  ? AsyncVariantLookup::Async :
                                                                             AsyncVariantLookup::Ordinary;
  • Hash table API widenedInstMethodHashTable::FindMethodDesc and InstantiatedMethodDesc::FindLoadedInstantiatedMethodDesc now take AsyncVariantLookup instead of bool isAsyncVariant; ContainsMethodDesc passes pMD->GetAsyncVariantLookup(). All 9 call sites in genmeth.cpp updated. This is required because a bool key cannot disambiguate regular-async from RDT entries that hash to the same bucket — without it, GetAsyncVariant() on an RDT can return the RDT itself.

Notes

  • The original assertion no longer fires; GetAsyncVariant() on an RDT now correctly returns its parallel regular-async variant.
  • Enabling TestGenericVirtualMethod on CoreCLR surfaces a separate, deeper bug in shared-canonical GVM dispatch (recursive re-entry into the RDT, stack overflow). That is out of scope for this change set, so the existing [ActiveIssue(...)] attribute on the test is intentionally left in place. The enum/lookup changes here are self-contained prerequisites that remove the misleading assert and unblock further investigation.

Note

This PR description and the changes were generated with assistance from GitHub Copilot.

Copilot AI requested review from Copilot and removed request for Copilot June 15, 2026 20:59
Copilot AI linked an issue Jun 15, 2026 that may be closed by this pull request
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

…reateAssociatedMethodDesc

Co-authored-by: VSadov <8218165+VSadov@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 15, 2026 21:51
Copilot AI changed the title [WIP] Fix generic virtual method test for CoreCLR Add AsyncVariantLookup::ReturnDroppingThunk for parallel RDT lookup in FindOrCreateAssociatedMethodDesc Jun 15, 2026
Copilot AI requested a review from VSadov June 15, 2026 21:52
Copilot AI review requested due to automatic review settings June 16, 2026 02:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates CoreCLR’s async-variant method lookup so that ReturnDroppingThunk (RDT) methods can be distinguished from “regular” async variants during FindOrCreateAssociatedMethodDesc / instantiated-method-desc hashtable lookups, preventing incorrect matches when multiple async-kind variants share the same method identity apart from async kind.

Changes:

  • Adds AsyncVariantLookup::ReturnDroppingThunk plus MethodDesc::GetAsyncVariantLookup() and updates matching logic (MatchesAsyncVariantLookup) to disambiguate regular async variants vs RDTs.
  • Widens instantiated-method-desc lookup APIs from bool isAsyncVariant to AsyncVariantLookup and updates call sites accordingly.
  • Modifies the covariant-return async test by removing an ActiveIssue skip annotation on TestGenericVirtualMethod.

Reviewed changes

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

Show a summary per file
File Description
src/tests/async/covariant-return/covariant-returns.cs Removes the ActiveIssue gate for TestGenericVirtualMethod, re-enabling the test.
src/coreclr/vm/method.hpp Introduces AsyncVariantLookup::ReturnDroppingThunk, adds GetAsyncVariantLookup(), and refines async-kind matching logic.
src/coreclr/vm/instmethhash.h Updates InstMethodHashTable::FindMethodDesc signature to accept AsyncVariantLookup (and adds a forward declaration).
src/coreclr/vm/instmethhash.cpp Uses MatchesAsyncVariantLookup + GetAsyncVariantLookup() to filter and validate hashtable entries.
src/coreclr/vm/genmeth.cpp Plumbs AsyncVariantLookup through instantiated method desc lookups/creation paths.

Comment on lines 226 to 227
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/127197", typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsNotNativeAot))]
public static void TestGenericVirtualMethod()
Comment thread src/coreclr/vm/method.hpp
Comment on lines 1729 to +1732
// by default async lookup matches the primaryMD
AsyncVariantLookup variantLookup = pPrimaryMD->IsAsyncVariantMethod() ? AsyncVariantLookup::Async : AsyncVariantLookup::Ordinary;
AsyncVariantLookup variantLookup = pPrimaryMD->IsReturnDroppingThunk() ? AsyncVariantLookup::ReturnDroppingThunk :
pPrimaryMD->IsAsyncVariantMethod() ? AsyncVariantLookup::Async :
AsyncVariantLookup::Ordinary;
Comment on lines 19 to 21
class AllocMemTracker;
enum class AsyncVariantLookup : int;

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.

[Runtime async] Generic virtual method test failing on CoreCLR

3 participants