-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Replace linker descriptor for AssemblyBuilder with DynamicDependency #38710
Conversation
for better linking when AssemblyBuilder is not instantiated. Contributes to dotnet#38692
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
[DynamicDependency("machine")] | ||
[DynamicDependency("corlib_internal")] | ||
[DynamicDependency("type_forwarders")] | ||
[DynamicDependency("pktoken")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: are you able to use nameof in any of these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use a comment as to why the dependencies are on this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, will switch to nameof
@@ -202,13 +197,12 @@ public sealed class AssemblyBuilder : Assembly | |||
private object? permissions_minimum; | |||
private object? permissions_optional; | |||
private object? permissions_refused; | |||
private PortableExecutableKinds peKind; | |||
private ImageFileMachine machine; | |||
private int peKind; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the field is not used and it drops additional dependencies
I tried using this change locally (with local fixes for #38693 and #38678). However, the ILLinker still isn't able to trim the fields from AssemblyBuilder. @marek-safar pointed out offline that it is because AssemblyBuilder has a runtime/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs Lines 170 to 171 in a92f4f0
Even after changing that, there are other edges into Ref.Emit that are preserving most of the types (because of the other preserve=fields on other types):
and
|
I think this should be doable without any annotations.
But linker is too eager to respect the layout. For reference types (and only reference types), the layout only becomes relevant once you allocate an instance. Linker should defer marking the fields until it sees the type as instantiated (i.e. constructor called). Once linker does that, the annotation will be unnecessary and this will Just Work™. |
Linker change: dotnet/linker#1309 |
@@ -224,7 +218,8 @@ public sealed class AssemblyBuilder : Assembly | |||
[MethodImplAttribute(MethodImplOptions.InternalCall)] | |||
private static extern void UpdateNativeCustomAttributes(AssemblyBuilder ab); | |||
|
|||
internal AssemblyBuilder(AssemblyName n, string? directory, AssemblyBuilderAccess access, bool corlib_internal) | |||
[DynamicDependency(nameof(pktoken))] // Automatically keeps all previous fields too due to StructLayout |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need DynamicDependency at all? The class is marked StructLayout.Sequential
and this annotation is on a constructor - linker is going to keep all the fields anyway if it sees the constructor is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically we don't right now but I wanted to make this dependency more explicit. We could also fix linker to keep only used fields for struct layout classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand how an explicit DynamicDependency on what appears to be an arbitrary field achieves that - I think we'll find that part quite confusing when we look at this code again 5 years from now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to be explicit, can we instead use the attribute that says to keep all fields?
for better linking when AssemblyBuilder is not instantiated.
Contributes to #38692
@eerhardt