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

Add Link-time framework feature removal spec #42

Closed
wants to merge 1 commit into from
Closed

Add Link-time framework feature removal spec #42

wants to merge 1 commit into from

Conversation

MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Jun 19, 2018

A sample of how this would work is here: MichalStrehovsky/corefx@2a7fa76

If we had a switch like the one in the linked sample usage commit, the People app that ships with Windows would get 1.2 MB smaller on AMD64 with post-NetStandard2.0 .NET Native because we would no longer need to carry the full HTTP/HTTPS/FTP stack just because the People app uses DataContractSerializer.

Other samples:

A sample of how this would work is here: MichalStrehovsky/corefx@2a7fa76

If we had a switch like this, the People app that ships with Windows would get 1.2 MB smaller on AMD64 with post-NetStandard2.0 .NET Native because we would no longer need to carry the full HTTP/HTTPS/FTP stack just because the People app uses `DataContractSerializer`.
@MichalStrehovsky
Copy link
Member Author

@sergiy-k
Copy link

Thanks @MichalStrehovsky! This looks great. The only question I have is what everyone thinks about the names of attributes? After reviewing multiple samples, it seems to me that the 'Removable' name is quite ambiguous and it does not speak clearly for its purpose. Maybe something more concrete like RemovableFeatureRoot attribute or just FeatureRoot attribute would be better? I'm not super good at coming up with good names so please feel to ignore. Thank you.

@MichalStrehovsky
Copy link
Member Author

The only question I have is what everyone thinks about the names of attributes?

I could file an issue over in the CoreFX repo and run the attribute through the API review process. They tend to also comment on names. It's not critical, but maybe having something approved saves us from having to process two attributes (unofficial and official one) in the future.

@marek-safar
Copy link
Contributor

@MichalStrehovsky please run the names via API review. We have more attributes we want to add/import and it might even make a sense to have them in a new namespace.

@MichalStrehovsky
Copy link
Member Author

Filed dotnet/corefx#30643.

@terrajobst
Copy link
Member

terrajobst commented Jul 19, 2018

My primary concern with the feature as proposed is that it's hard to diagnose issues introduced by incorrect attribution if the default behavior is returning zero/null.

I'd rather we FailFast by default. Looking at your example I do however buy the scenario that you want to define query methods for features, which is as easy as doing this:

private static bool SupportsReflectionBasedSerializationFeature
{
    [Removable(ReflectionBasedSerializationFeatureName)]
    get
    {
        return true;
    }
}

My gut feel is -- and that might be wrong -- that the vast majority of attribute applications will be implementations of regular methods. So maybe we should be using two different attributes or just reverse the FailFast property:

private static bool SupportsReflectionBasedSerializationFeature
{
    [Removable(ReflectionBasedSerializationFeatureName, DoNotFail=true)]
    get
    {
        return true;
    }
}

@terrajobst
Copy link
Member

terrajobst commented Jul 19, 2018

Do we provide an accordance where the developer can manually specify the list of features the linker has to keep regardless of reachability? This would allow developers to work around problems with the linker in case a method fails fast by just keeping the feature entirely.

@terrajobst terrajobst requested review from a team and richlander July 19, 2018 21:19
@MichalStrehovsky
Copy link
Member Author

Do we provide an accordance where the developer can manually specify the list of features the linker has to keep regardless of reachability? This would allow developers to work around problems with the linker in case a method fails fast by just keeping the feature entirely.

Feature removal is opt in - the developer has to specify the name of the feature to remove and only then the body replacement happens. If we want the linker not to do that, we would simply not ask it to strip the feature.

Or are you asking for this attribute to serve a double purpose (acting like a conditional [Preserve] attribute?). Do you have a scenario where this would be useful? The motivation behind the proposed feature is to allow treeshaking in places that are reachable in the static call graph (the fact that we're keeping the methods is the problem; the problem is not their unintended removal) - I don't see a scenario where this would be beneficial.

MichalStrehovsky added a commit to MichalStrehovsky/corefx that referenced this pull request Jul 31, 2018
This adds [removable feature annotation](dotnet/designs#42) to `XmlDownloadManager`.

If the user specifies that they would like to remove support for this at publish/native compilation time, the linker/compiler is going to replace the method body of `CreateWebRequestOrThrowIfRemoved` with a throwing method body. The exception message is going to inform the user that the feature has been removed because they opted into the removal.

Contributes to #30597. Saves 1.2 MB of the size of the Windows UWP People app. This is a size on disk regression that came with NetStandard 2.0.
MichalStrehovsky added a commit to dotnet/corefx that referenced this pull request Jul 31, 2018
This adds [removable feature annotation](dotnet/designs#42) to `XmlDownloadManager`.

If the user specifies that they would like to remove support for this at publish/native compilation time, the linker/compiler is going to replace the method body of `CreateWebRequestOrThrowIfRemoved` with a throwing method body. The exception message is going to inform the user that the feature has been removed because they opted into the removal.

Contributes to #30597. Saves 1.2 MB of the size of the Windows UWP People app. This is a size on disk regression that came with NetStandard 2.0.
MichalStrehovsky added a commit to MichalStrehovsky/corefx that referenced this pull request Aug 1, 2018
This adds [removable feature annotation](dotnet/designs#42) to data
contract serialization.

If the user specifies that they would like to remove support for this
at publish/native compilation time, the linker/compiler is going to
replace the annotated method bodies with a throwing method body.
The exception message is going to inform the user that the feature
has been removed because they opted into the removal. The throwing
method body is significantly smaller than the transitive closure
of code reachable from the original method body.

Contributes to #30597. Turning this feature off in the UWP People app
saves 4% of size. This is a size on disk regression that came with
the new version of CoreFX and blocks the Windows team in picking up
the latest framework. There is a zero size growth goal.
MichalStrehovsky added a commit to dotnet/corefx that referenced this pull request Aug 10, 2018
This adds [removable feature annotation](dotnet/designs#42) to data
contract serialization.

If the user specifies that they would like to remove support for this
at publish/native compilation time, the linker/compiler is going to
replace the annotated method bodies with a throwing method body.
The exception message is going to inform the user that the feature
has been removed because they opted into the removal. The throwing
method body is significantly smaller than the transitive closure
of code reachable from the original method body.

Contributes to #30597. Turning this feature off in the UWP People app
saves 4% of size. This is a size on disk regression that came with
the new version of CoreFX and blocks the Windows team in picking up
the latest framework. There is a zero size growth goal.
MichalStrehovsky added a commit to MichalStrehovsky/corefx that referenced this pull request Aug 10, 2018
This adds [removable feature annotation](dotnet/designs#42) to `XmlDownloadManager`.

If the user specifies that they would like to remove support for this at publish/native compilation time, the linker/compiler is going to replace the method body of `CreateWebRequestOrThrowIfRemoved` with a throwing method body. The exception message is going to inform the user that the feature has been removed because they opted into the removal.

Contributes to #30597. Saves 1.2 MB of the size of the Windows UWP People app. This is a size on disk regression that came with NetStandard 2.0.
MichalStrehovsky added a commit to MichalStrehovsky/corefx that referenced this pull request Aug 10, 2018
…t#31533)

This adds [removable feature annotation](dotnet/designs#42) to data
contract serialization.

If the user specifies that they would like to remove support for this
at publish/native compilation time, the linker/compiler is going to
replace the annotated method bodies with a throwing method body.
The exception message is going to inform the user that the feature
has been removed because they opted into the removal. The throwing
method body is significantly smaller than the transitive closure
of code reachable from the original method body.

Contributes to #30597. Turning this feature off in the UWP People app
saves 4% of size. This is a size on disk regression that came with
the new version of CoreFX and blocks the Windows team in picking up
the latest framework. There is a zero size growth goal.
zacharycmontoya pushed a commit to dotnet/corefx that referenced this pull request Aug 17, 2018
* Fix RD.XML for System.Private.Xml (#31125)

This corrects the size on disk regression caused by #19912. After that pull request, all of the schema validation stuff would always be included for any app that depends on System.Private.Xml because during initial analysis we consider a lot of things in S.P.Xml necessary as a precaution for SG generating references to it. The RD.XML in S.P.Xml then roots things forever.

I spent some time getting a repro of the original failure and convinced myself this is not a scenario that would require RD.XML in the S.P.Xml assembly.

Here's the facts:
* This test uses a test hook to explicitly disable pregenerated serialization code for `XmlSchema`. (https://github.com/dotnet/corefx/blob/1afc5360013bedc4099875c836342f493b083e5f/src/System.Private.Xml/src/System/Xml/Schema/XmlSchema.cs#L175 that is on stack at the time of failure is an analysis slam dunk, so we do have pregenerated code, we just don't use it because of the hook)
* The test is then testing the reflection fallback path to serialize `XmlSchema`. This doesn't work. Reflection fallback path won't in general work for _any framework provided type_ because there's no RD.XML to root it. Reflection fallback really only works for user types because of our default RD.XML that roots all user types (we also use that for the CoreFX tests, which is why the other reflection fallback tests don't hit issues).

* Add RemovableFeatureAttribute

* Make non-file URL support optional in XmlUrlResolver

This adds [removable feature annotation](dotnet/designs#42) to `XmlDownloadManager`.

If the user specifies that they would like to remove support for this at publish/native compilation time, the linker/compiler is going to replace the method body of `CreateWebRequestOrThrowIfRemoved` with a throwing method body. The exception message is going to inform the user that the feature has been removed because they opted into the removal.

Contributes to #30597. Saves 1.2 MB of the size of the Windows UWP People app. This is a size on disk regression that came with NetStandard 2.0.

* Annotate reflection fallback for S.P.DataContractSerialization (#31533)

This adds [removable feature annotation](dotnet/designs#42) to data
contract serialization.

If the user specifies that they would like to remove support for this
at publish/native compilation time, the linker/compiler is going to
replace the annotated method bodies with a throwing method body.
The exception message is going to inform the user that the feature
has been removed because they opted into the removal. The throwing
method body is significantly smaller than the transitive closure
of code reachable from the original method body.

Contributes to #30597. Turning this feature off in the UWP People app
saves 4% of size. This is a size on disk regression that came with
the new version of CoreFX and blocks the Windows team in picking up
the latest framework. There is a zero size growth goal.

* Sync SR class with the CoreRT copy

This ports over the change from
dotnet/corert@0ac83cb.

When UsingResourceKeys is true and we stripped the resources, the
existing code would have returned null.
Copy link
Member

@danmoseley danmoseley left a comment

Choose a reason for hiding this comment

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

What's the status of this ?

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
This adds [removable feature annotation](dotnet/designs#42) to `XmlDownloadManager`.

If the user specifies that they would like to remove support for this at publish/native compilation time, the linker/compiler is going to replace the method body of `CreateWebRequestOrThrowIfRemoved` with a throwing method body. The exception message is going to inform the user that the feature has been removed because they opted into the removal.

Contributes to dotnet/corefx#30597. Saves 1.2 MB of the size of the Windows UWP People app. This is a size on disk regression that came with NetStandard 2.0.


Commit migrated from dotnet/corefx@5898cdd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants