Skip to content

Commit f8903fe

Browse files
authored
Only add interface methods to _virtual_methods cache (#101139)
We only ever do operations on interface methods, so we can only keep interface methods rather than all virtual methods
1 parent f191f5f commit f8903fe

File tree

1 file changed

+30
-26
lines changed

1 file changed

+30
-26
lines changed

src/tools/illink/src/linker/Linker.Steps/MarkStep.cs

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ protected LinkContext Context {
6060
}
6161

6262
protected Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> _methods;
63-
protected Dictionary<MethodDefinition, MarkScopeStack.Scope> _virtual_methods;
63+
protected Dictionary<MethodDefinition, MarkScopeStack.Scope> _interface_methods;
6464
protected Queue<AttributeProviderPair> _assemblyLevelAttributes;
6565
protected Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> _lateMarkedAttributes;
6666
protected List<(TypeDefinition, MarkScopeStack.Scope)> _typesWithInterfaces;
@@ -219,7 +219,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
219219
public MarkStep ()
220220
{
221221
_methods = new Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> ();
222-
_virtual_methods = new Dictionary<MethodDefinition, MarkScopeStack.Scope> ();
222+
_interface_methods = new Dictionary<MethodDefinition, MarkScopeStack.Scope> ();
223223
_assemblyLevelAttributes = new Queue<AttributeProviderPair> ();
224224
_lateMarkedAttributes = new Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> ();
225225
_typesWithInterfaces = new List<(TypeDefinition, MarkScopeStack.Scope)> ();
@@ -437,7 +437,7 @@ bool ProcessPrimaryQueue ()
437437

438438
while (!QueueIsEmpty ()) {
439439
ProcessQueue ();
440-
ProcessVirtualMethods ();
440+
ProcessInterfaceMethods ();
441441
ProcessMarkedTypesWithInterfaces ();
442442
ProcessDynamicCastableImplementationInterfaces ();
443443
ProcessPendingBodies ();
@@ -530,11 +530,11 @@ protected virtual void EnqueueMethod (MethodDefinition method, in DependencyInfo
530530
_methods.Enqueue ((method, reason, origin));
531531
}
532532

533-
void ProcessVirtualMethods ()
533+
void ProcessInterfaceMethods ()
534534
{
535-
foreach ((var method, var scope) in _virtual_methods) {
535+
foreach ((var method, var scope) in _interface_methods) {
536536
using (ScopeStack.PushLocalScope (scope)) {
537-
ProcessVirtualMethod (method);
537+
ProcessInterfaceMethod (method);
538538
}
539539
}
540540
}
@@ -568,7 +568,7 @@ void ProcessMarkedTypesWithInterfaces ()
568568
continue;
569569
foreach (var ov in baseMethods) {
570570
if (ov.Base.DeclaringType is not null && ov.Base.DeclaringType.IsInterface && IgnoreScope (ov.Base.DeclaringType.Scope)) {
571-
_virtual_methods.TryAdd (ov.Base, ScopeStack.CurrentScope);
571+
MarkMethodAsVirtual (ov.Base, ScopeStack.CurrentScope);
572572
}
573573
}
574574
}
@@ -651,28 +651,32 @@ void ProcessPendingBodies ()
651651
}
652652
}
653653
}
654-
655-
void ProcessVirtualMethod (MethodDefinition method)
654+
void MarkMethodAsVirtual (MethodDefinition method, MarkScopeStack.Scope scope)
656655
{
657656
Annotations.EnqueueVirtualMethod (method);
658-
659657
if (method.DeclaringType.IsInterface) {
660-
var defaultImplementations = Annotations.GetDefaultInterfaceImplementations (method);
661-
if (defaultImplementations is not null) {
662-
foreach (var dimInfo in defaultImplementations) {
663-
ProcessDefaultImplementation (dimInfo);
658+
_interface_methods.TryAdd (method, scope);
659+
}
660+
}
664661

665-
if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (dimInfo))
666-
MarkMethod (dimInfo.Override, new DependencyInfo (DependencyKind.Override, dimInfo.Base), ScopeStack.CurrentScope.Origin);
667-
}
662+
void ProcessInterfaceMethod (MethodDefinition method)
663+
{
664+
Debug.Assert (method.DeclaringType.IsInterface);
665+
var defaultImplementations = Annotations.GetDefaultInterfaceImplementations (method);
666+
if (defaultImplementations is not null) {
667+
foreach (var dimInfo in defaultImplementations) {
668+
ProcessDefaultImplementation (dimInfo);
669+
670+
if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (dimInfo))
671+
MarkMethod (dimInfo.Override, new DependencyInfo (DependencyKind.Override, dimInfo.Base), ScopeStack.CurrentScope.Origin);
668672
}
669-
List<OverrideInformation>? overridingMethods = (List<OverrideInformation>?)Annotations.GetOverrides (method);
670-
if (overridingMethods is not null) {
671-
for (int i = 0; i < overridingMethods.Count; i++) {
672-
OverrideInformation ov = overridingMethods[i];
673-
if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (ov))
674-
MarkMethod (ov.Override, new DependencyInfo (DependencyKind.Override, ov.Base), ScopeStack.CurrentScope.Origin);
675-
}
673+
}
674+
List<OverrideInformation>? overridingMethods = (List<OverrideInformation>?)Annotations.GetOverrides (method);
675+
if (overridingMethods is not null) {
676+
for (int i = 0; i < overridingMethods.Count; i++) {
677+
OverrideInformation ov = overridingMethods[i];
678+
if (IsInterfaceImplementationMethodNeededByTypeDueToInterface (ov))
679+
MarkMethod (ov.Override, new DependencyInfo (DependencyKind.Override, ov.Base), ScopeStack.CurrentScope.Origin);
676680
}
677681
}
678682
}
@@ -3227,7 +3231,7 @@ protected virtual void ProcessMethod (MethodDefinition method, in DependencyInfo
32273231
MarkMethodSpecialCustomAttributes (method);
32283232

32293233
if (method.IsVirtual)
3230-
_virtual_methods.TryAdd (method, ScopeStack.CurrentScope);
3234+
MarkMethodAsVirtual (method, ScopeStack.CurrentScope);
32313235

32323236
MarkNewCodeDependencies (method);
32333237

@@ -3435,7 +3439,7 @@ void MarkBaseMethods (MethodDefinition method)
34353439
// This will produce warnings for all interface methods and virtual methods regardless of whether the interface, interface implementation, or interface method is kept or not.
34363440
if (ov.Base.DeclaringType.IsInterface && !method.DeclaringType.IsInterface) {
34373441
// These are all virtual, no need to check IsVirtual before adding to list
3438-
_virtual_methods.TryAdd (ov.Base, ScopeStack.CurrentScope);
3442+
MarkMethodAsVirtual (ov.Base, ScopeStack.CurrentScope);
34393443
continue;
34403444
}
34413445

0 commit comments

Comments
 (0)