Skip to content

Commit

Permalink
Call CheckProcessed before enqueuing to MarkStep._methods (dotnet#3139)
Browse files Browse the repository at this point in the history
* Call CheckProcessed before enqueuing to MarkStep._methods to avoid redundantly adding methods

Commit migrated from dotnet@261e911
  • Loading branch information
jtschuster authored and dotnet-bot committed Dec 20, 2022
1 parent eb2043f commit baf9403
Showing 1 changed file with 27 additions and 23 deletions.
50 changes: 27 additions & 23 deletions src/tools/illink/src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2929,12 +2929,38 @@ protected internal void MarkIndirectlyCalledMethod (MethodDefinition method, in
if (Annotations.GetAction (method) == MethodAction.Nothing)
Annotations.SetAction (method, MethodAction.Parse);

EnqueueMethod (method, reason, origin);

// Use the original reason as it's important to correctly generate warnings
// the updated reason is only useful for better tracking of dependencies.
ProcessAnalysisAnnotationsForMethod (method, originalReasonKind, origin);

// Record the reason for marking a method on each call.
switch (reason.Kind) {
case DependencyKind.AlreadyMarked:
Debug.Assert (Annotations.IsMarked (method));
break;
default:
Annotations.Mark (method, reason, origin);
break;
}

bool markedForCall =
reason.Kind == DependencyKind.DirectCall ||
reason.Kind == DependencyKind.VirtualCall ||
reason.Kind == DependencyKind.Newobj;
if (markedForCall) {
// Record declaring type of a called method up-front as a special case so that we may
// track at least some method calls that trigger a cctor.
// Temporarily switch to the original source for marking this method
// this is for the same reason as for tracking, but this time so that we report potential
// warnings from a better place.
MarkType (method.DeclaringType, new DependencyInfo (DependencyKind.DeclaringTypeOfCalledMethod, method), new MessageOrigin (reason.Source as IMemberDefinition ?? method));
}

// We will only enqueue a method to be processed if it hasn't been processed yet.
if (!CheckProcessed (method))
EnqueueMethod (method, reason, origin);

return method;
}

Expand Down Expand Up @@ -3113,32 +3139,10 @@ protected virtual void ProcessMethod (MethodDefinition method, in DependencyInfo
using var parentScope = ScopeStack.PushScope (new MarkScopeStack.Scope (origin));
using var methodScope = ScopeStack.PushScope (new MessageOrigin (method));

// Record the reason for marking a method on each call. The logic under CheckProcessed happens
// only once per method.
switch (reason.Kind) {
case DependencyKind.AlreadyMarked:
Debug.Assert (Annotations.IsMarked (method));
break;
default:
Annotations.Mark (method, reason, ScopeStack.CurrentScope.Origin);
break;
}

bool markedForCall =
reason.Kind == DependencyKind.DirectCall ||
reason.Kind == DependencyKind.VirtualCall ||
reason.Kind == DependencyKind.Newobj;
if (markedForCall) {
// Record declaring type of a called method up-front as a special case so that we may
// track at least some method calls that trigger a cctor.
// Temporarily switch to the original source for marking this method
// this is for the same reason as for tracking, but this time so that we report potential
// warnings from a better place.
MarkType (method.DeclaringType, new DependencyInfo (DependencyKind.DeclaringTypeOfCalledMethod, method), new MessageOrigin (reason.Source as IMemberDefinition ?? method));
}

if (CheckProcessed (method))
return;

foreach (Action<MethodDefinition> handleMarkMethod in MarkContext.MarkMethodActions)
handleMarkMethod (method);
Expand Down

0 comments on commit baf9403

Please sign in to comment.