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

Enable targeted Assembly trimming #49040

Open
AaronRobinsonMSFT opened this issue Mar 3, 2021 · 8 comments
Open

Enable targeted Assembly trimming #49040

AaronRobinsonMSFT opened this issue Mar 3, 2021 · 8 comments
Labels
area-AssemblyLoader-coreclr linkable-framework Issues associated with delivering a linker friendly framework
Milestone

Comments

@AaronRobinsonMSFT
Copy link
Member

Narrowing the impact of the Linker to a single Assembly to trim would be convenient for scenarios involving large monolithic SDK style assemblies. The scenario would permit consuming one of the assemblies from https://github.com/dotnet/pinvoke and indicating that only the P/Invoke assembly should be trimmed. The Linker would run over the entire application but the trimming operation would be limited to the P/Invoke assembly.

This shouldn't be constrained to a single assembly but rather to a collection that can be impact and all other assemblies just used to determine usage.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-AssemblyLoader-coreclr untriaged New issue has not been triaged by the area owner labels Mar 3, 2021
@ghost
Copy link

ghost commented Mar 3, 2021

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

Issue Details

Narrowing the impact of the Linker to a single Assembly to trim would be convenient for scenarios involving large monolithic SDK style assemblies. The scenario would permit consuming one of the assemblies from https://github.com/dotnet/pinvoke and indicating that only the P/Invoke assembly should be trimmed. The Linker would run over the entire application but the trimming operation would be limited to the P/Invoke assembly.

This shouldn't be constrained to a single assembly but rather to a collection that can be impact and all other assemblies just used to determine usage.

Author: AaronRobinsonMSFT
Assignees: -
Labels:

area-AssemblyLoader-coreclr, untriaged

Milestone: -

@AaronRobinsonMSFT
Copy link
Member Author

@sbomer
Copy link
Member

sbomer commented Mar 3, 2021

There's an option that tells the linker to trim a particular assembly:

  • --action link PInvokeAssembly will let it link (remove unused members from) that assembly

Whatever MSBuild logic adds that assembly to the output could set some metadata on it to pass the above option to the linker.

The current linker defaults will analyze starting from the entry point and any referenced assemblies without IsTrimmable assembly metadata - usually the app and nuget dependencies, since we add this attribute to framework assemblies. If your scenario is compatible with the usual caveats of PublishTrimmed I think this is what we want.

The Linker would run over the entire application but the trimming operation would be limited to the P/Invoke assembly.

If you were specifically looking to avoid trimming any other assemblies (to avoid problems with unanalyzable reflection for example), we could pass

  • --trim-mode copy: this will tell it to also consider IsTrimmable assemblies as "roots" for the analysis

However this is a lot of analysis to do (scanning the entire self-contained app's IL) if we are only going to optimize that one assembly. In that case it might make more sense to develop a solution particularly for your scenario (maybe there are more efficient ways to only look for references to the generated PInvokes).

There's another important caveat, which is that even with --trim-mode copy, the linker may modify the analyzed assemblies by dropping R2R, removing type forwarders, or rewriting type references (though it shouldn't remove any members). The tracking issue for this is dotnet/linker#1669, which @mateoatr is looking into.

@MichalStrehovsky
Copy link
Member

Trimming doesn't happen unless the user specifies PublishTrimmed and at that point we're trimming the entire app (some assemblies more, some less). Is the request that we would run trimming even if the user didn't specify PublishTrimmed in this case?

@AArnott
Copy link
Contributor

AArnott commented Mar 3, 2021

Trimming can cause runtime malfunction do to removal of private members that are accessed via reflection. Yet some assemblies are relatively safe from such regressions and would greatly benefit from trimming, such as the Win32 p/invoke assemblies mentioned above. So yes, I think the ask is to trim specific assemblies all the time.

That said, given trimming requires scanning all assemblies deployed with an app so only APIs unused across the whole app can be removed from the assembly, perhaps that would take an unacceptable toll on build perf, I don't know.

Can we limit trimming when the user does ask for it to just those assemblies that the app knows are "safe" to trim?

@sbomer
Copy link
Member

sbomer commented Mar 3, 2021

Can we limit trimming when the user does ask for it to just those assemblies that the app knows are "safe" to trim?

We do limit trimming to assemblies marked IsTrimmable or with an --action argument, but it doesn't exactly mean they are "safe" to trim, since this depends on the context (for example nothing prevents user code from reflecting over a pinvoke assembly). Instead we try to provide correctness guarantees via analysis warnings.

So yes, I think the ask is to trim specific assemblies all the time.

I think for this we would want to add support for PublishTrimmed of framework-dependent apps (or some equivalent option for build), which will also help with the performance. Assuming the framework is correctly annotated this should provide the same correctness guarantees (analysis warnings) - just note that the above caveats still apply for the analyzed assemblies, and you'd also get warnings about unanalyzable reflection that's unrelated to the pinvoke assemblies.

@marek-safar
Copy link
Contributor

I think you are asking for exactly what Sven shared earlier. You can mark your assembly as https://github.com/mono/linker/blob/main/docs/design/trimmed-assemblies.md#assemblymetadataistrimmable-true trimmable and that will trim it all the time automatically.

@agocke agocke added this to the Future milestone May 10, 2021
@agocke agocke added linkable-framework Issues associated with delivering a linker friendly framework and removed untriaged New issue has not been triaged by the area owner labels May 10, 2021
@ghost
Copy link

ghost commented May 10, 2021

Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer
See info in area-owners.md if you want to be subscribed.

Issue Details

Narrowing the impact of the Linker to a single Assembly to trim would be convenient for scenarios involving large monolithic SDK style assemblies. The scenario would permit consuming one of the assemblies from https://github.com/dotnet/pinvoke and indicating that only the P/Invoke assembly should be trimmed. The Linker would run over the entire application but the trimming operation would be limited to the P/Invoke assembly.

This shouldn't be constrained to a single assembly but rather to a collection that can be impact and all other assemblies just used to determine usage.

Author: AaronRobinsonMSFT
Assignees: -
Labels:

area-AssemblyLoader-coreclr, linkable-framework

Milestone: Future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-AssemblyLoader-coreclr linkable-framework Issues associated with delivering a linker friendly framework
Projects
Status: No status
Development

No branches or pull requests

6 participants