Skip to content

Make IL Scanner report both variants#128107

Open
eduardo-vp wants to merge 1 commit into
dotnet:mainfrom
eduardo-vp:ilcscanner-report-both-variants
Open

Make IL Scanner report both variants#128107
eduardo-vp wants to merge 1 commit into
dotnet:mainfrom
eduardo-vp:ilcscanner-report-both-variants

Conversation

@eduardo-vp
Copy link
Copy Markdown
Member

IL Scanner currently reports only the async variant inside a runtime async method. While the JIT initially chooses this variant too, it can switch to the task returning variant if the async variant is a thunk. Make IL Scanner report both variants such that the JIT can choose either one.

Fixes #127179.

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the NativeAOT IL scanner’s call dependency tracking for runtime-async “task await” patterns so it no longer reports only the async-variant method, but instead reports both the original method and its async variant, allowing the JIT to select either implementation during compilation.

Changes:

  • Stop rewriting the scanned call target to the async variant; instead, keep the original call target and track the async variant in parallel.
  • Add dependency reporting for the async variant alongside the original call target, including generic-lookup-related nodes where applicable.

Comment on lines +820 to +826
if (asyncVariantMethod != null && _canonMethod.IsSharedByGenericInstantiations)
{
MethodDesc avTargetMethod = asyncVariantMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
if (avTargetMethod.RequiresInstMethodDescArg())
_dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodDictionary, asyncVariantRuntimeDeterminedMethod), reason);
else if (avTargetMethod.RequiresInstMethodTableArg())
_dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, asyncVariantRuntimeDeterminedMethod.OwningType), reason);
Comment on lines +480 to +483
// If this is the task await pattern, the JIT will first resolve the call to the
// async variant, then may switch back to the original if the async variant is just
// a thunk (for non-runtime-async methods). Report both variants as dependencies such
// that the JIT can pick either one.
Comment on lines +820 to +826
if (asyncVariantMethod != null && _canonMethod.IsSharedByGenericInstantiations)
{
MethodDesc avTargetMethod = asyncVariantMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
if (avTargetMethod.RequiresInstMethodDescArg())
_dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.MethodDictionary, asyncVariantRuntimeDeterminedMethod), reason);
else if (avTargetMethod.RequiresInstMethodTableArg())
_dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, asyncVariantRuntimeDeterminedMethod.OwningType), reason);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be really difficult to review for correctness. I wonder if we can instead split ImportCall into two methods:

private void ImportCall(ILOpcode opcode, int token);
private void ImportCall(ILOpcode opcode, MethodDesc method, MethodDesc runtimeDeterminedMethod)

and have the token based ImportCall call the other one, potentially twice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes this is much better, will do

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.

ILC crash with runtime-async enabled calling JsonSerializer.DeserializeAsync<T>(...) from a generic method in NativeAOT

3 participants