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

Avoid copy action for root assemblies #96363

Merged
merged 21 commits into from
Jan 12, 2024
Merged

Conversation

sbomer
Copy link
Member

@sbomer sbomer commented Dec 30, 2023

Changes TrimmerRootAssembly (and the underlying option -a) to root all members of the assembly, without setting the action to copy. This allows us to perform branch removal and attribute removal for the assembly.

Fixes #95429

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Dec 30, 2023
@ghost ghost added the linkable-framework Issues associated with delivering a linker friendly framework label Dec 30, 2023
@ghost ghost assigned sbomer Dec 30, 2023
@ghost
Copy link

ghost commented Dec 30, 2023

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

Issue Details

null

Author: sbomer
Assignees: -
Labels:

linkable-framework, area-Tools-ILLink

Milestone: -

Preserve existing marking behavior by letting MarkStep do the same
work that it does for copy assemblies, including marking attributes.
With the change to MarkEntireType that calls MarkType instead of
Annotations.Mark, we are now reaching MarkType for the dependency
from the copy assembly to the attribute it contains, producing an
unexpected IL2045. Silence this by checking the DependencyKind.
@sbomer

This comment was marked as resolved.

BitVector32.CreateMask(int.MinValue) was incorrectly being treated
as returning constant 1. The IL from the beginning of that method:

    IL_0000:  ldarg.0
    IL_0001:  brtrue.s   IL_0005
    IL_0003:  ldc.i4.1
    IL_0004:  ret

The brtrue.s branch was being analyzed as not taken because the
argument was not 1. The branch should be analyzed as taken for
any non-zero argument.
And don't set ForceParse for rooted methods.
ForceParse was preventing the XML substitutions from applying.

This change may make it possible for substitutions in copy assemblies
to be honored...
@lambdageek
Copy link
Member

lambdageek commented Jan 8, 2024

The ApplyUpdateTests are running for mono wasm in Release mode, where DebuggerSupport was set to false by default. This illink change results in DebuggableAttribute being removed, causing test failures, so I set DebuggerSupport to true for these tests to preserve the attribute. Now I am getting failures which I don't know how to diagnose, and I'm not sure whether they're expected. For example, this assert is hitting:

@lambdageek Could you please advise? Would it be better to simply disable these tests in Release mode, or are these failures worth investigating?

edit: It seems those failures aren't reproing in CI - maybe I was doing something incorrectly locally.

@sbomer The EnC tests depend at runtime on the assemblies built from the projects in the ApplyUpdate subdirectory. Those assemblies need to be compiled by Roslyn with optimizations off and with emitted debug information see https://github.com/dotnet/runtime/blob/main/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/Directory.Build.props

(specifically when a runtime that supports hot reload tries to apply an update to a particular assembly, that assembly must have [assembly:System.Diagnostics.DebuggableAttribute(DebuggingModes.DisableOptimizations)]).

In general the assemblies in the ApplyUpdate directory must not be modified by the trimmer at all - otherwise the hot reload deltas will not match the assembly contents and the runtime will do something nonsensical. (in real world usage the deltas are generated by VS; for the tests it's the *.dll.1.dmeta and *.dll.1.dil files that are generated during the test build ahead of time). You can think of the hot reload deltas as some kind of log that says "add a new row N to table X with contents ABCD; modify row M of table Y with contents SPQR; etc" - if the trimmer disturbs the baseline assembly at all - things will go wrong.

Would it be better to simply disable these tests in Release mode

I would prefer not to do that, if possible. Using a Release runtime with a Release BCL with debuggable untrimmed "user code" is much closer to the actual scenario that users will be running.

FIxing the checkRemainingErrors behavior results in
too many spurious failures. Use
LogDoesNotContainAttribute for now.
@sbomer sbomer marked this pull request as ready for review January 9, 2024 17:40
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 although I'm not an expert on this codebase.

@@ -327,6 +328,8 @@ public static class GetCustomAttribute
{

[Fact]
[ActiveIssue("https://github.com/dotnet/linker/issues/2078", typeof(PlatformDetection), nameof(PlatformDetection.IsTrimmedWithILLink))
Copy link
Member

Choose a reason for hiding this comment

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

Wondered why this wasn't hit with naot and found out illinker has this as a hardcoded list. Weird, but okay I guess. Would be nice to move this to the same plan as all the other attributes at least. I'm not convinced anyone will want to work on 2078 anytime soon.

Copy link
Member Author

Choose a reason for hiding this comment

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

Filed #96907

@@ -1583,7 +1583,7 @@ public bool Analyze (in CalleePayload callee, Stack<MethodDefinition> callStack)
return false;

if (operand is int oint) {
if (oint == 1)
if (oint != 0)
Copy link
Member

Choose a reason for hiding this comment

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

Why was this needed? It's a good change, but surprised to see this in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe I should've separated it out, but I thought this change was small enough to include - allowing branch removal caused this test to fail, due to this bug. More detail in the commit message for aadf946.

@sbomer sbomer merged commit d92db39 into dotnet:main Jan 12, 2024
133 of 135 checks passed
tmds pushed a commit to tmds/runtime that referenced this pull request Jan 23, 2024
Changes TrimmerRootAssembly (and the underlying option -a) to
root all members of the assembly, without setting the action to
copy. This allows us to perform branch removal and attribute
removal for the assembly.

This includes changes to MarkStep to ensure that rooted
assemblies are marked visible to reflection. This for example
ensures that parameter names don't get removed.

With the change to MarkEntireType that calls MarkType instead of
Annotations.Mark, we are now reaching MarkType for the dependency
from the copy assembly to the attribute it contains, producing an
unexpected IL2045. Silence this by checking the DependencyKind.

Also fixes a bug in constant method analysis that this uncovered:

BitVector32.CreateMask(int.MinValue) was incorrectly being treated
as returning constant 1. The IL from the beginning of that method:

    IL_0000:  ldarg.0
    IL_0001:  brtrue.s   IL_0005
    IL_0003:  ldc.i4.1
    IL_0004:  ret

The brtrue.s branch was being analyzed as not taken because the
argument was not 1. The branch should be analyzed as taken for
any non-zero argument.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers linkable-framework Issues associated with delivering a linker friendly framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Library trimming steps should support feature switch substitutions
3 participants