Skip to content

Implement Interop Type Map support in NativeAOT #116355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
Jun 20, 2025

Conversation

jkoritzinsky
Copy link
Member

@jkoritzinsky jkoritzinsky commented Jun 5, 2025

Implement support for the Interop Type Mapping feature in NativeAOT with the expected trimming behavior.

Contributes to #110691
Fixes #113362
Fixes #115323

Trimming behavior

The various type map attributes are explicitly trimmed out by ILC. Once we add trimmer support, we can change these attributes to be trimmed out by the attributes XML (depending on how we implement support in the trimmer).

External type map

An entry in the external type map is kept if one of the two following cases is true:

  1. The trimTarget type's NecessaryTypeSymbol is marked in the graph.

  2. When the ILScanner is enabled, a ScannedCastNode node for trimTarget is in the graph.

We need this additional node as the whole-program optimization provided by the IL scanner can optimize checks like if (obj is Foo) or if (obj.GetType() == typeof(Foo)) to if(false) if that's the only mention of the type. However, by spec, we want to still keep any TypeMapAttribute that has that type as a trim target.

If a check like the ones mentioned above is the only mention of a type and the target type has no relation to the trimTarget type, the trimTarget type will not be unnecessarily preserved, only the entry in the table (and the target type's MaximallyConstructableType node) will be preserved.

This node is not needed when not running the ILScanner, as we don't do this type of whole-program optimization without the scanner.

Proxy type map

An entry in the proxy type map is kept if the sourceType's MaximallyConstructableType node is kept.

TypeMapping API

The dictionaries exposed by the TypeMapping API are implemented using the NativeAOT NativeFormat to embed them into the image.

Tests

I've added a NativeAOT Test app to validate the behavior after publishing with the ILScanner enabled and updated the Interop/TypeMap test suite for the NativeAOT implementation.

I've also added a trimming test. I did notice, however, that the trimming test looks at the results of scanning, not codegen, so the exact list of things kept vs not kept differs between the NativeAOT test app and the trimming test (as the NativeAOT test app tests the output after codegen).

@jkoritzinsky jkoritzinsky added this to the 10.0.0 milestone Jun 5, 2025
@Copilot Copilot AI review requested due to automatic review settings June 5, 2025 22:59
Copy link
Contributor

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

This PR implements Interop Type Map support in NativeAOT, adding new nodes and APIs to handle external and associated type maps and ensuring proper trimming behavior. Key changes include:

  • Updating ILScanNodeFactory’s constructor to accept a TypeMapManager.
  • Introducing new dependency analysis nodes (for external and associated type maps) and updating related handling logic.
  • Extending the CompilationBuilder, MetadataManager, and other components to integrate type map management, together with updates to the NativeFormat writer and type mapping lazy dictionary.

Reviewed Changes

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

Show a summary per file
File Description
ILScanNodeFactory.cs Updated constructor to add TypeMapManager parameter.
ExternalTypeMap*.cs, AssociatedTypeMap*.cs Added new nodes and associated logic for external and associated type maps.
CompilationBuilder.Aot.cs & AnalysisBasedMetadataManager.cs Integrated type mapping support into AOT compilation and metadata processing.
TypeMapLazyDictionary.NativeAot.cs New implementation for creating type map dictionaries for interop.
Various project and configuration files Updated project definitions and suppression files to support the changes.
Comments suppressed due to low confidence (1)

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AssociatedTypeMapNode.cs:39

  • The GetName method in AssociatedTypeMapNode returns 'External type map', which is inconsistent with the class name. Consider changing it to 'Associated type map' for clarity.
protected override string GetName(NodeFactory context) => "External type map";

Copy link
Member

@MichalStrehovsky MichalStrehovsky left a comment

Choose a reason for hiding this comment

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

Looks reasonable to me otherwise.

@jkoritzinsky
Copy link
Member Author

/ba-g failures are unrelated

@jkoritzinsky jkoritzinsky merged commit 7e91402 into dotnet:main Jun 20, 2025
155 of 162 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-NativeAOT-coreclr linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support precompiling fast type switches in ILC cctor interpreter (Native AOT) [API Proposal]: Type Mapping API
8 participants