Skip to content

ECMA-335 metadata in native AOT experiment - #135195

Closed
MichalStrehovsky wants to merge 2 commits into
dotnet:mainfrom
MichalStrehovsky:ecma335md
Closed

MichalStrehovsky wants to merge 2 commits into
dotnet:mainfrom
MichalStrehovsky:ecma335md

Conversation

@MichalStrehovsky

@MichalStrehovsky MichalStrehovsky commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Native AOT has its own metadata format because it's smaller. But this makes it more difficult to share reflection stack with CoreCLR. How much size are we getting from the custom format in reality?

Just opening for measurements, Copilot makes it trivial to experiment...

More to investigate:

  • Can we share Strings and UserStrings heaps
  • Can we share blob heaps?
  • If things look promising, would we lose size in mapping tables (single handle previously vs token+containing scope in ECMA)

Knowns problems:

  • Stack trace metadata is missing
  • We need to store EntryPoint somewhere
  • CA blobs need to be rewritten

@MichalStrehovsky MichalStrehovsky added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) NO-REVIEW Experimental/testing PR, do NOT review it area-NativeAOT-coreclr labels Oct 5, 2026
@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.

Register the combined string set in each metadata builder, compact serialized roots, and point their #Strings stream headers at one trailing shared heap. Keep inspection DLLs self-contained.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8bf03cc8-5e10-4bcd-acb1-61fab4910d78
@MichalStrehovsky

Copy link
Copy Markdown
Member Author

Hmm, this looks interesting. @jkotas do you have an opinion whether we should pursue this? The motivation is code sharing of the reflection stack.

As expected it will be a size regression... but smaller than I expected.

Size statistics

Pull request #135195

Project Size before Size after Difference
TodosApi-linux 23059200 23386880 327680
TodosApi-windows 24263168 24587776 324608
avalonia.app-linux 8660480 8750592 90112
avalonia.app-windows 8358912 8442880 83968
hello-linux 1016112 1016112 0
hello-minimal-linux 991544 991544 0
hello-minimal-windows 771584 770048 -1536
hello-windows 827904 826368 -1536
kestrel-minimal-linux 5404752 5441616 36864
kestrel-minimal-windows 4920320 4961792 41472
reflection-linux 1643752 1643752 0
reflection-windows 1521152 1521664 512
webapiaot-linux 9166024 9293000 126976
webapiaot-windows 9684992 9817088 132096
winrt-component-minimal-windows 721920 720384 -1536

@jkotas

jkotas commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

I think the NAOT format is different in two ways:

  • Structural differences: for example, native aot format stores the namespaces as a hierarchy - that just makes it different and complicates computing the namespace string at runtime. The structural differences show up through the metadata reader APIs.
  • Encoding differences: For example, native aot has variable sized rows that allow for more compact encoding. These can be abstracted away behind metadata reader APIs.

Eliminating the structural differences makes sense to me. Fix the format so that the metadata reader API is nearly same shape as S.R.Metadata. It should enable easier sharing of the reflection code that builds on top of it.

I am not sure whether we want to get rid of the encoding differences. It is both about the encoding overhead but also about the size of the code to decode it all that is not small either if we just take S.R.Metadata reader as is.

Also, I do not think we need to maintain the support for resolving type and member refs in NAOT. I do not expect the native metadata split over multiple binaries to ever come back. We should be able to drop all that. The idea would be to keep the native metadata as simple and differentiated as possible so that it can justify its existence.

@MichalStrehovsky

Copy link
Copy Markdown
Member Author

Makes sense, thank you! I'll take a look at eliminating the unnecessary structural differences.

I'm not convinced taking S.R.Metadata for decoding would be size regression though - the variable length records in the native format make decoding the native AOT format more costly and I would expect all of the variable sized integer decoding to be quite expensive size-wise.

@MichalStrehovsky
MichalStrehovsky deleted the ecma335md branch October 6, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-NativeAOT-coreclr NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) NO-REVIEW Experimental/testing PR, do NOT review it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants