Skip to content

Add AssociatedSourceType for conditional unmanaged exports#128180

Draft
Copilot wants to merge 9 commits into
mainfrom
copilot/api-proposal-unmanaged-callers-only
Draft

Add AssociatedSourceType for conditional unmanaged exports#128180
Copilot wants to merge 9 commits into
mainfrom
copilot/api-proposal-unmanaged-callers-only

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

UnmanagedCallersOnlyAttribute exports with EntryPoint were always rooted and emitted. This adds an associated source type so NativeAOT can keep/export generated native entrypoints only when the source type survives trimming.

  • Public API
    • Adds UnmanagedCallersOnlyAttribute.AssociatedSourceType to implementation and ref assemblies.
    • Leaves the lightweight Runtime.Base attribute copy unchanged.
[UnmanagedCallersOnly(
    EntryPoint = "MyObjectProxy_MyMethod",
    AssociatedSourceType = typeof(MyObject))]
static void MyMethod(IntPtr handle) { }
  • NativeAOT rooting

    • Moves unmanaged entrypoint rooting into a per-assembly UnmanagedEntryPointsNode.
    • Roots normal exports unconditionally.
    • Roots associated exports conditionally on runtime-constructable AssociatedSourceType.
    • Skips associated exports when the associated source type cannot be resolved.
    • Handles associated source types that can be dynamically constructed at runtime, including generic source types and array types without array templates.
  • Shared trim-target dependency handling

    • Extracts runtime-constructable trim-target dependency logic into RuntimeConstructableTypeDependencies.
    • Reuses the helper from both unmanaged entrypoint rooting and external type map handling.
  • Export generation

    • Filters generated export files to compiled method bodies so trimmed associated exports are not passed to the native linker.
  • Coverage

    • Adds TrimmingBehaviors coverage for unconditional, kept associated, trimmed associated, unused array associated-source, dynamically loadable generic associated-source, dynamically loadable array associated-source, and array associated-source constructed through a runtime generic array template.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1ab9107a-9310-4fa2-8342-70d882ff3d8e

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 14, 2026 05:52
@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.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1ab9107a-9310-4fa2-8342-70d882ff3d8e

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 14, 2026 06:06
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1ab9107a-9310-4fa2-8342-70d882ff3d8e

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 14, 2026 06:12
Copilot AI changed the title [WIP] Add AssociatedSourceType to UnmanagedCallersOnlyAttribute Add AssociatedSourceType for conditional unmanaged exports May 14, 2026
Copilot AI requested a review from MichalStrehovsky May 14, 2026 06:14
Copy link
Copy Markdown
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.

Comment thread src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs Outdated
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d8e7b00e-4ed9-4e1b-a82b-817269ef4eaf

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 14, 2026 08:08
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/d8e7b00e-4ed9-4e1b-a82b-817269ef4eaf

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 14, 2026 08:11
/// * Must only have <see href="https://learn.microsoft.com/dotnet/framework/interop/blittable-and-non-blittable-types">blittable</see> arguments.
/// </remarks>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class UnmanagedCallersOnlyAttribute : Attribute
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.

Why does this definition of UnmanagedCallersOnlyAttribute exist? Shouldn't this just use the one in SPCL via a source include or something?

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.

We could, but this rarely changes and Runtime.Base is supposed to be low overhead and ceremony (i.e. people shouldn't have to deal with Runtime.Base build breaks if they modify a file in CoreLib). E.g. we also define the CallConvs types in this file, the ones that we needed.

This addition is unnecessary. @copilot revert changes in this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted the unnecessary Runtime.Base attribute copy change in 3494d17.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/64e55336-9d89-4a8e-b32c-0b3b445781a1

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 15, 2026 01:09
Copy link
Copy Markdown
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.

Comment thread src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs Outdated
Comment thread src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs Outdated
Comment thread src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs Outdated
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/03d7e02a-55b5-4666-b1e8-ce6d2bb62b46

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 15, 2026 04:01
Copilot AI requested a review from MichalStrehovsky May 15, 2026 04:03
Copy link
Copy Markdown
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.

{
foreach (EcmaMethod method in methods)
{
if (compilationResults.IsMethodBodyCompiled(method))
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.

Suggested change
if (compilationResults.IsMethodBodyCompiled(method))
// Some of the exported methods could be conditioned with UnmanagedCallersOnly.AssociatedSourceType
// so need to filter down to compiled methods.
if (compilationResults.IsMethodBodyCompiled(method))

Comment on lines +78 to +79
[UnmanagedCallersOnly(EntryPoint = UnusedSourceExport, AssociatedSourceType = typeof(UnusedSource))]
private static int UnusedSourceEntryPoint() => 3;
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.

Add one more test that uses AssociatedSourceType = typeof(UnusedSource[]) (array of the type). Since the element type is never referenced, that one should not be generated either.

Then add one more test that uses AssociatedSourceType = typeof(UsedAsElementOnly[]) and make sure we use that with a public static object CreateArray<T>() => new T[0]; that is reached through MakeGenericMethod. The associated export should be generated because we constructed the array through a template at runtime.

Comment on lines +18 to +19
[UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode",
Justification = "The test verifies runtime creation of the generic type through a type loader template.")]
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.

You can eliminate this warning by constraining the T in methods used with MakeGeneric to be a class. Example: public static object CreateDynamicSource<T>() where T : class => new DynamicSource<T>();. No warnings are generated for these because we can construct the method at runtime.

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/fea7fc44-9eef-4a72-b701-3e70c6fd0262

Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot May 15, 2026 06:34
Copilot AI requested a review from MichalStrehovsky May 15, 2026 06:35
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.

[API Proposal]: UnmanagedCallersOnlyAttribute.AssociatedSourceType

3 participants