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

Check for marking virtual method due to base only when state changes #3073

Merged
merged 43 commits into from
Oct 27, 2022

Conversation

jtschuster
Copy link
Member

@jtschuster jtschuster commented Oct 18, 2022

Instead of checking every virtual method to see if it should be kept due to a base method every iteration of the MarkStep pipeline, check each method only when its relevant state has changed. These state changes are:

  • The override's declaring type is marked as instantiated
  • The base method is marked
  • The override's declaring type is marked as relevant to variant casting

This required some changes to TypeMapInfo:

  • modify GetBaseMethods to return OverrideInformation's
  • add a new method, GetInterfaceImplementors to get all types that implement a given interface.

I profiled the ASP.Net benchmark's build link time and got the following time in CPU ms:
27325 before the regression related to #3067
87310 in main
32011 after this change

This also changes behavior in a couple places:

  • When a type is marked as instantiated. Previously, we would mark all methods that override a method from a preserved scope, which would mark methods implementing an interface even if the interface implementation isn't kept. Now, the method should only be kept if the interface is marked and the interface implementation is marked.
  • IDynamicInterfaceCastable is special cased to keep the interface implementation on all types that are instantiated or relevant to variant casting, regardless of whether or not IDynamicInterfaceCastable is marked or not.
  • The IDynamicCastable test is updated to use the corelib descriptors to keep the IDynamicCastable interface implementations

Closes #3067
Closes #3069

Instead of checking every virtual method to see if it should be kept due
to a base method every iteration of the MarkStep pipeline, check each
method only when it's relevant state has changed. These state changes
are:
- The override's declaring type is marked as instantiated
- The base method is marked
- The overrides's declaring type is marked as relevant to variant
  casting
@@ -2334,6 +2376,32 @@ void MarkInterfaceImplementations (TypeDefinition type)
if (ShouldMarkInterfaceImplementation (type, iface))
MarkInterfaceImplementation (iface, new MessageOrigin (type));
}

bool ShouldMarkInterfaceImplementation (TypeDefinition type, InterfaceImplementation iface)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is moved to a local method because it assumes that 'type' is marked as instantiated, so we wouldn't want to call it elsewhere.


protected internal virtual void MarkInterfaceImplementation (InterfaceImplementation iface, MessageOrigin? origin = null, DependencyInfo? reason = null)
{
if (Annotations.IsMarked (iface))
return;
Annotations.MarkProcessed (iface, reason ?? new DependencyInfo (DependencyKind.InterfaceImplementationOnType, ScopeStack.CurrentScope.Origin.Provider));
Copy link
Member Author

Choose a reason for hiding this comment

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

Before moving the MarkProcessed call, the linker hit a cycle where marking iface.InterfaceType would call MarkInterfaceImplementation with the same arguments and overflow the stack

@jtschuster jtschuster changed the title Check for marking method for base only when state changes Check for marking virtual method due to base only when state changes Oct 18, 2022
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/SealerStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker/TypeMapInfo.cs Outdated Show resolved Hide resolved
src/linker/Linker/TypeMapInfo.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
jtschuster and others added 6 commits October 25, 2022 12:54
…RC2 SDK (dotnet#3077)

Change analyzer versions such that the repo can be built with .NET 7 RC2 SDK.
- Took the versions from dotnet/runtime.
- Remove CheckAttributeInstantiation method since is no longer necessary
- Remove global attributes since they are no longer necessary
- Workaround the fact that compiler injects System.Runtime.CompilerServices.RefSafetyRulesAttribute into every assembly to describe the language version

Co-authored-by: tlakollo <tlakaelel_axayakatl@outlook.com>
@jtschuster
Copy link
Member Author

I rebased by mistake and the git history got messed up and duplicated a bunch of commits. The only real changes should be from 2bc88c0.

@jtschuster jtschuster requested a review from sbomer October 27, 2022 17:50
Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

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

A few more suggestions, otherwise LGTM. Thanks a lot!

src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
src/linker/Linker.Steps/MarkStep.cs Outdated Show resolved Hide resolved
@jtschuster jtschuster enabled auto-merge (squash) October 27, 2022 22:06
@jtschuster jtschuster merged commit 8306887 into dotnet:main Oct 27, 2022
jtschuster added a commit to jtschuster/linker that referenced this pull request Oct 31, 2022
…otnet#3073)

Instead of checking every virtual method to see if it should be kept due
to a base method every iteration of the MarkStep pipeline, check each
method only when its relevant state has changed.

Co-authored-by: Sven Boemer <sbomer@gmail.com>
tlakollo pushed a commit to dotnet/runtime that referenced this pull request Nov 4, 2022
…otnet/linker#3073)

Instead of checking every virtual method to see if it should be kept due
to a base method every iteration of the MarkStep pipeline, check each
method only when its relevant state has changed. 

Co-authored-by: Sven Boemer <sbomer@gmail.com>

Commit migrated from dotnet/linker@8306887
agocke pushed a commit to dotnet/runtime that referenced this pull request Nov 16, 2022
…otnet/linker#3073)

Instead of checking every virtual method to see if it should be kept due
to a base method every iteration of the MarkStep pipeline, check each
method only when its relevant state has changed. 

Co-authored-by: Sven Boemer <sbomer@gmail.com>

Commit migrated from dotnet/linker@8306887
vitek-karas added a commit to vitek-karas/linker that referenced this pull request Dec 9, 2022
Recurisve generics with interface marking annotation used to cause stackoverflow in the linker.
The test now passes since the problem was fixed in dotnet#3073
vitek-karas added a commit that referenced this pull request Dec 12, 2022
Recurisve generics with interface marking annotation used to cause stackoverflow in the linker.
The test now passes since the problem was fixed in #3073
dotnet-bot pushed a commit to dotnet/dotnet that referenced this pull request Dec 13, 2022
….0 (#3156)

Recurisve generics with interface marking annotation used to cause stackoverflow in the linker.
The test now passes since the problem was fixed in dotnet/linker#3073

Original commit: dotnet/linker@dde6d62

[[ commit created by automation ]]
tlakollo pushed a commit to tlakollo/linker that referenced this pull request Dec 20, 2022
Recurisve generics with interface marking annotation used to cause stackoverflow in the linker.
The test now passes since the problem was fixed in dotnet#3073

Commit migrated from dotnet@dde6d62
tlakollo pushed a commit to tlakollo/runtime that referenced this pull request Dec 22, 2022
Recurisve generics with interface marking annotation used to cause stackoverflow in the linker.
The test now passes since the problem was fixed in dotnet/linker#3073

Commit migrated from dotnet/linker@dde6d62
sbomer added a commit that referenced this pull request Jan 18, 2023
…state changes (#3094)

* Check for marking virtual method due to base only when state changes (#3073)

Instead of checking every virtual method to see if it should be kept due
to a base method every iteration of the MarkStep pipeline, check each
method only when its relevant state has changed.

Co-authored-by: Sven Boemer <sbomer@gmail.com>

* Don't mark override of abstract base if the override's declaring type is not marked (#3098)

* Don't mark an override every time the base is abstract, only if the declaring type is also marked
Adds a condition to ShouldMarkOverrideForBase to exit early if the declaring type of the method is not marked.

* Add test case for #3112 with pseudo-circular reference with ifaces

* Link issue to TODO

* Adds a test for recursive generics on interfaces

This is a copy of the test added in #3156

Co-authored-by: Sven Boemer <sbomer@gmail.com>
Co-authored-by: vitek-karas <10670590+vitek-karas@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants