Skip to content
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

[release/8.0] Emit less metadata for not-reflection-visible types #91703

Merged
merged 5 commits into from
Sep 11, 2023

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Sep 6, 2023

Backport of #91660 to release/8.0

/cc @MichalStrehovsky

Customer Impact

In .NET 8.0 we deleted the concept of reflection-not-visible types. In pathological situations such as the one found in WinForms, this can result in massive size on disk regression compared to .NET 7. In WinForms, the regression doubles the size of the app. Impact on non-WinForms scenarios is hard to estimate but it will likely be a small size improvement everywhere.

There are people using NativeAOT in WinForms even though it's not officially supported, through e.g. https://github.com/kant2002/WinFormsComInterop project.

Testing

Manual test on WinForms, plus all of our CI testing.

Risk

This is a low risk compiler fix. The fix will result in small dependency graph size increase within the compiler due to extra analysis and associated increase in memory use/log size. The increase is negligible.

IMPORTANT: If this backport is for a servicing release, please verify that:

  • The PR target branch is release/X.0-staging, not release/X.0.

  • If the change touches code that ships in a NuGet package, you have added the necessary package authoring and gotten it explicitly reviewed.

In .NET 8 we massively regressed the size of an empty WinForms app. A WinForms app now brings in a big chunk of WPF with it. I traced it down to the `ICommand` interface having a WPF `TypeConverter` and `ValueSerializer` attribute on it: https://github.com/dotnet/runtime/blob/04bd438844482c907062583153a43a9e3b37dbb8/src/libraries/System.ObjectModel/src/System/Windows/Input/ICommand.cs#L13-L16.

An empty app will have a call to a method on `ICommand`, but nothing actually implements `ICommand`. Previously this would mean we generate an unconstructed `MethodTable` for `ICommand`, the unconstructed `MethodTable`s get no reflection metadata, and that's the end of the story.

After #85810 however, the reflection stack can no longer reason about `MethodTable`s that don't have reflection metadata, so we need to generate it. This means we end up with the custom attribute and all the reflection dataflow that comes out of it.

But this metadata is not actually visible in trim safe apps (the only place where reflection could see these method tables in trim safe code is if they're used in a type comparison `x == typeof(Foo)` and we were able to optimize the method table to the unconstructed version because of that). So we can generate less of it and still get away with it.

In this PR I'm adding support for skipping generation of custom attribute metadata for such types. The size of an empty WinForms app goes from 50-something MB to 20-something MB. I think we'll be able to further reduce this number to ~7 MB or less because 12 MB of this are embedded resources that look designer related.
@ghost
Copy link

ghost commented Sep 6, 2023

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

Backport of #91660 to release/8.0

/cc @MichalStrehovsky

Customer Impact

Testing

Risk

IMPORTANT: If this backport is for a servicing release, please verify that:

  • The PR target branch is release/X.0-staging, not release/X.0.

  • If the change touches code that ships in a NuGet package, you have added the necessary package authoring and gotten it explicitly reviewed.

Author: github-actions[bot]
Assignees: -
Labels:

area-NativeAOT-coreclr

Milestone: -

@agocke
Copy link
Member

agocke commented Sep 6, 2023

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jeffschwMSFT jeffschwMSFT left a comment

Choose a reason for hiding this comment

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

approved. please get a code review. once ready this can be merged

@jeffschwMSFT jeffschwMSFT added the Servicing-approved Approved for servicing release label Sep 7, 2023
@jeffschwMSFT
Copy link
Member

@MichalStrehovsky / @agocke can y'all take a look at the PR failures and let me know when we are ready to merge.

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky / @agocke can y'all take a look at the PR failures and let me know when we are ready to merge.

This looks good to merge. runtime-extra-platforms haven't been fully green in years. We're separating out native aot testing into a separate pipeline that we can better keep green.

@jeffschwMSFT jeffschwMSFT merged commit af44ecb into release/8.0 Sep 11, 2023
8 checks passed
@jkotas jkotas deleted the backport/pr-91660-to-release/8.0 branch September 11, 2023 20:19
@radical radical mentioned this pull request Sep 26, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Oct 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-NativeAOT-coreclr Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants