Fix RuntimeMethodHandle cache key for async variants#128432
Open
Copilot wants to merge 4 commits into
Open
Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/865c991f-a15c-4cca-9b66-845450dd5e89 Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/865c991f-a15c-4cca-9b66-845450dd5e89 Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix NativeAOT RuntimeMethodHandle interning for async variants
Fix RuntimeMethodHandle cache key for async variants
May 21, 2026
Member
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
3 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates NativeAOT’s TypeLoader RuntimeMethodHandle interning to treat the “async variant” bit as part of a handle’s identity, preventing cache aliasing between async/non-async variants. It also re-enables the previously excluded System.Text.Json.SourceGeneration.Roslyn4.4.Tests project for most NativeAOT configurations by removing the broad exclusion while keeping existing OS/arch-specific exclusions.
Changes:
- Extended
RuntimeMethodHandleKeyto include the async-variant flag in equality and hashing, and passed the flag when creating interning keys. - Updated hashing logic for
RuntimeMethodHandleKeyto incorporate the async-variant flag. - Removed the unconditional NativeAOT test exclusion for
System.Text.Json.SourceGeneration.Roslyn4.4.Tests(while retaining existing conditional exclusions, e.g., OS/arch-specific cases).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs | Adds isAsyncVariant into the runtime method handle interning key (equals/hash + key construction). |
| src/libraries/tests.proj | Re-enables System.Text.Json.SourceGeneration.Roslyn4.4.Tests for NativeAOT by removing the broad exclusion entry. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment on lines
+113
to
+115
| if (_isAsyncVariant) | ||
| hashCode ^= unchecked((int)0x9e3779b9); | ||
| return hashCode; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #128286
Fixes #128291
NativeAOT TypeLoader was interning dynamically created
RuntimeMethodHandles without including the async-variant bit in the key. This could cause async/non-async lookups for the same method components to alias to one cached handle and resolve the wrong method variant; this change makes async variant part of handle identity and re-enables the affectedSystem.Text.Jsonsource-gen test project.TypeLoader runtime method handle key
RuntimeMethodHandleKeyto includeisAsyncVariantin identity.isAsyncVariant.Equalsto require matching async-variant state.GetHashCodeto include async-variant state via combined hashing.NativeAOT libraries test project inclusion
System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Tests.csprojOriginal prompt
Fix NativeAOT
RuntimeMethodHandleinterning for runtime async variants and re-enable the affected System.Text.Json source generation test project.Context:
System.Text.Json.SourceGeneration.Roslyn4.4.Tests.RuntimeMethodHandles are interned byRuntimeMethodHandleKey, but the key currently includes declaring type, method handle, and generic method arguments only. It does not include the runtime async variant bit, even thoughGetRuntimeMethodHandleForComponents(..., bool isAsyncVariant)stores that bit inMethodHandleInfo.IsAsyncVariant, andRuntimeMethodHandle.Equalscompares_numGenericArgsAndFlag, which includesRuntimeMethodHandleConstants.IsAsyncVariant.RuntimeMethodHandle, depending on cache population order. Later,GetMethodDescForRuntimeMethodHandlereads the stale/mismatchedIsAsyncVariantbit and resolves the wrong method variant.Required changes:
src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs, updateRuntimeMethodHandleKeyso it includesisAsyncVariantas part of identity:_isAsyncVariant.bool isAsyncVariant.Equals(RuntimeMethodHandleKey other)to compare the async variant flag in addition to declaring type, method handle, and generic args.GetHashCode()so async and non-async variants produce different hashes.GetRuntimeMethodHandleForComponentsto passisAsyncVariantwhen constructing the key.isAsyncVariant: falseandisAsyncVariant: truedoes not return the same handle and preserves the requested async bit. If direct test coverage is impractical because this is internal TypeLoader-only functionality, document why in the PR description and rely on existing System.Text.Json NativeAOT test coverage being re-enabled.src/libraries/tests.proj:Validation expectations:
System.Text.Json.SourceGeneration.Roslyn4.4.Testsruns again in the libraries test project.PR title should be concise, e.g.
Fix RuntimeMethodHandle cache key for async variants.The following is the prior conversation context from the user's chat exploration (may be truncated):
User: I'm thinking about the theory of @jakobbotch - this could be the case where we're doing dispatch using a RuntimeMethodHandle that was created dynamically using the type loader in System.Private.TypeLoader. could there be a bug in how we're creating these RuntimeMethodHandles or comparing them (missing the runtime async flag on the handle)?
Assistant: Yes — that theory looks very plausible. I found at least one concrete hole in the dynamic
RuntimeMethodHandlepath: the TypeLoader cache key ignoresisAsyncVariant, even though the allocatedMethodHandleInfostores it andRuntimeMethodHandle.Equalscompares it.The suspicious code is in
TypeLoaderEnvironment.LdTokenResultLookup.cs:But the creation API accepts
isAsyncVariantand stores it intoMethodHandleInfo: