Skip to content

Compact NativeAOT dispatch cell info encoding - #130824

Merged
MichalStrehovsky merged 6 commits into
dotnet:mainfrom
MichalStrehovsky:compact-dispatch-cell-info
Jul 23, 2026
Merged

Compact NativeAOT dispatch cell info encoding#130824
MichalStrehovsky merged 6 commits into
dotnet:mainfrom
MichalStrehovsky:compact-dispatch-cell-info

Conversation

@MichalStrehovsky

@MichalStrehovsky MichalStrehovsky commented Jul 15, 2026

Copy link
Copy Markdown
Member

Replaces the dispatch cell info encoding used for interface methods and generic virtual methods to use Native Layout.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Copilot-Session: c5889318-fe12-47b1-946e-6969e02ef71d

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c5889318-fe12-47b1-946e-6969e02ef71d
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 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.

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 changes the NativeAOT dispatch cell info sections to use a more compact encoding when multiple dispatch cells share the same descriptor (dictionary + per-cell index), and updates the runtime decoder accordingly. It also adds smoke tests intended to exercise multiple callsites sharing the same descriptor.

Changes:

  • Add dictionary-based encoding for interface dispatch cell info and GVM dispatch cell info (compiler-side), falling back to the existing direct encoding when it’s smaller.
  • Update NativeAOT runtime dispatch resolution to decode either direct or dictionary-encoded info regions.
  • Add/extend NativeAOT smoke tests to create multiple distinct callsites targeting the same interface/GVM descriptor.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/tests/nativeaot/SmokeTests/UnitTests/Interfaces.cs Adds a new test to create multiple interface dispatch callsites that should share a descriptor.
src/tests/nativeaot/SmokeTests/DynamicGenerics/GenericVirtualMethods.cs Adds multiple no-inline interface GVM call wrappers to increase shared-descriptor callsites.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellInfoSectionNode.cs Emits interface dispatch info using direct vs dictionary encoding based on size.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GvmDispatchCellInfoSectionNode.cs Emits GVM dispatch info using direct vs dictionary encoding based on size.
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DispatchCellNode.cs Introduces a shared helper for dictionary size/index encoding decisions.
src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs Updates decoding logic to understand the new direct/dictionary layouts.

@MichalStrehovsky

Copy link
Copy Markdown
Member Author

I'm on the fence whether this is worth it at all. This adds 200 lines of complexity to get a 0.34% saving in the best case.

Size statistics

Pull request #130824

Project Size before Size after Difference
TodosApi-linux 25084480 25023040 -61440
TodosApi-windows 26148352 26086912 -61440
avalonia.app-linux 19002672 18937136 -65536
avalonia.app-windows 19319296 19253248 -66048
hello-linux 1254592 1254592 0
hello-minimal-linux 1107016 1111112 4096
hello-minimal-windows 788992 789504 512
hello-windows 950784 951296 512
kestrel-minimal-linux 5392992 5388896 -4096
kestrel-minimal-windows 4921344 4913152 -8192
reflection-linux 1845416 1849512 4096
reflection-windows 1716224 1716224 0
webapiaot-linux 9882200 9857624 -24576
webapiaot-windows 10348032 10326016 -22016
winrt-component-minimal-windows 738304 738304 0

Group dispatch cells by descriptor and encode their metadata as compact NativeFormat runs backed by the existing NativeReferences table.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 99d7688e-8d4a-4dcb-a6e4-ca94fdfed0dc
Copilot AI review requested due to automatic review settings July 17, 2026 02:55

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7f337a9d-27d1-43d9-9c0c-cc6a3ea449a7
Copilot AI review requested due to automatic review settings July 17, 2026 05:54

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs Outdated
Replaced exceptions with assertions for cell index and slot checks, and updated external references initialization.
Copilot AI review requested due to automatic review settings July 17, 2026 08:21

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f55b8ade-cf37-4d2c-91af-cee7b726a3ea
Copilot AI review requested due to automatic review settings July 21, 2026 08:56

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

@MichalStrehovsky

Copy link
Copy Markdown
Member Author

Looks like this now costs next to nothing in extra complexity (the NativeArray is a general purpose data structure we can use elsewhere) and still provides a nice saving:

Size statistics

Project Size before Size after Difference
TodosApi-linux 25084480 24990272 -94208
TodosApi-windows 26148352 26053120 -95232
avalonia.app-linux 19002672 18904368 -98304
avalonia.app-windows 19319296 19220992 -98304
hello-linux 1254592 1254592 0
hello-minimal-linux 1107016 1111112 4096
hello-minimal-windows 788992 790016 1024
hello-windows 950784 951808 1024
kestrel-minimal-linux 5392992 5384800 -8192
kestrel-minimal-windows 4921344 4908032 -13312
reflection-linux 1845416 1849512 4096
reflection-windows 1716224 1716736 512
webapiaot-linux 9882200 9845336 -36864
webapiaot-windows 10348032 10312704 -35328
winrt-component-minimal-windows 738304 738816 512

@MichalStrehovsky
MichalStrehovsky marked this pull request as ready for review July 21, 2026 11:39
@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.

@MichalStrehovsky

Copy link
Copy Markdown
Member Author

/azp run runtime-nativeaot-outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Comment thread src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 02:24

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs:106

  • GetDispatchCellInfo ignores the return value of InitializeNativeReferences. If the NativeReferences blob is missing/corrupt, subsequent GetIntPtrFromIndex calls will read from an uninitialized table and fail unpredictably. This should fail fast with BadImageFormatException (similar to other TypeLoader code paths).
            externalReferences = default;
            externalReferences.InitializeNativeReferences(typeManager);

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs:115

  • The fallback loop that decrements cellIndex can underflow in release builds (cellIndex is uint) if TryGetAt never succeeds (e.g., malformed/empty info region), leading to an infinite loop. Add a defensive termination condition (and ideally a small max scan bound) that throws BadImageFormatException.
            NativeParser parser;
            while (!entries.TryGetAt(cellIndex, out parser))
            {
                Debug.Assert(cellIndex > 0);
                cellIndex--;
            }

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Dispatch.cs:109

  • GetDispatchCellInfo allocates a new NativeReader (class) on every first-time dispatch resolution. If many dispatch cells are resolved during startup, this can create avoidable GC pressure compared to the previous pointer-based indexing. Consider caching a per-module NativeReader/NativeArray (or otherwise avoiding per-call allocation) and include perf measurements showing this doesn’t regress first-call/startup time.
            NativeReader reader = new NativeReader(pInfo, checked((uint)length));
            NativeArray entries = new NativeArray(new NativeParser(reader, 0));

@jkotas jkotas left a comment

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.

(make sure to update the PR description before merging)

@MichalStrehovsky
MichalStrehovsky merged commit 756cb59 into dotnet:main Jul 23, 2026
117 checks passed
@MichalStrehovsky
MichalStrehovsky deleted the compact-dispatch-cell-info branch July 23, 2026 01:32
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-rc1 milestone Jul 24, 2026
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.

3 participants