Skip to content

Fix NativeAOT resource string inlining for async IL - #133970

Merged
jakobbotsch merged 1 commit into
dotnet:mainfrom
jakobbotsch:fix-133954
Sep 16, 2026
Merged

jakobbotsch merged 1 commit into
dotnet:mainfrom
jakobbotsch:fix-133954

Conversation

@jakobbotsch

@jakobbotsch jakobbotsch commented Sep 15, 2026

Copy link
Copy Markdown
Member

Preserve ECMA module identity for async IL wrappers and recognize it when injecting and resolving resource string tokens.

Fix #133954

Before fix After fix
Runtime async disabled 1,601,536 bytes 1,601,536 bytes
Runtime async enabled 2,196,480 bytes 1,610,240 bytes

The remaining size difference is coming from

[AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder))]
[RuntimeAsyncMethodGeneration(false)]
public static async ValueTask InvokeAsync<TState>(Action<TState> action, TState state, CancellationToken cancellationToken)
which is reachable by the app and which pulls in async1 infrastructure.

Preserve ECMA module identity for async IL wrappers and recognize it when injecting and resolving resource string tokens.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf8623a5-a7a4-4c7d-8371-a97b53478abe
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@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.

@jakobbotsch
jakobbotsch marked this pull request as ready for review September 16, 2026 07:17
Copilot AI lite review requested due to automatic review settings September 16, 2026 07:17
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

🔵 Needs a closer look

Add regression coverage for async resource-string inlining and verify the resource is not rooted.

Pull request overview

Fixes NativeAOT resource-string inlining for runtime-async IL by preserving ECMA module identity.

Changes:

  • Adds an ECMA-aware async IL wrapper.
  • Updates resource token injection and resolution for ECMA-backed IL.
File summaries
File Summary
src/coreclr/tools/Common/TypeSystem/IL/NativeAotILProvider.cs Preserves module identity for async IL wrappers.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs Enables resource-string token handling for ECMA-backed async IL.
Review details

Suppressed comments (2)

src/coreclr/tools/Common/TypeSystem/IL/NativeAotILProvider.cs:374

  • Could you add a NativeAOT regression test that exercises a real runtime-async method containing an SR resource-property access? The existing FrameworkStrings coverage only exercises resource-string substitution from synchronous IL, so it would still pass if this wrapper failed to preserve its ECMA module. The assertion should verify the resource is not rooted (or inspect the resulting size/dependency output), not only that the async call returns the expected string, since the old implementation can still return the value by retaining the resource.
                return wrappedIL is EcmaMethodIL ecmaIL
                    ? new EcmaAsyncMethodIL(asyncVariantImpl, ecmaIL)
                    : new AsyncMethodIL(asyncVariantImpl, wrappedIL);

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs:635

  • Please add a NativeAOT regression test for this path. The existing runtime-async tests do not exercise SubstitutedILProvider's resource-string inlining, so a future regression in the async wrapper's ECMA-module identity or injected-token resolution could recreate the size/rooting issue without failing tests. The test should compile an async method containing a generated SR accessor and verify that the accessor is inlined and its resource is not rooted.

[!NOTE]
This review comment was created by GitHub Copilot.

            if (hasGetResourceStringCall && method.GetMethodILDefinition() is IEcmaMethodIL ecmaMethodIL)
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

@jakobbotsch

Copy link
Copy Markdown
Member Author

/backport to release/11.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

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.

Problem with runtime async in .NET 11 RC1: unexpectedly larger binary size

3 participants