diff --git a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyAnalyzer.cs b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyAnalyzer.cs index f4adb44450ee85..d64cf3ebd2ccfa 100644 --- a/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyAnalyzer.cs +++ b/src/coreclr/tools/aot/ILCompiler.DependencyAnalysisFramework/DependencyAnalyzer.cs @@ -39,9 +39,57 @@ public sealed class DependencyAnalyzer : De private List _markedNodesWithDynamicDependencies = new List(); private bool _newDynamicDependenciesMayHaveAppeared; - private Dictionary, HashSet.CombinedDependencyListEntry>> _conditional_dependency_store = new Dictionary, HashSet.CombinedDependencyListEntry>>(); + private Dictionary, ConditionalDependencyBucket> _conditionalDependencyStore = + new Dictionary, ConditionalDependencyBucket>(); private bool _markingCompleted; + private sealed class ConditionalDependencyBucket + { + private readonly DependencyNodeCore.CombinedDependencyListEntry _singleDependency; + private HashSet.CombinedDependencyListEntry> _dependencies; + + public ConditionalDependencyBucket(DependencyNodeCore.CombinedDependencyListEntry dependency) + { + _singleDependency = dependency; + } + + public void Add(DependencyNodeCore.CombinedDependencyListEntry dependency) + { + if (_dependencies is null) + { + if (_singleDependency.Equals(dependency)) + { + return; + } + + _dependencies = new HashSet.CombinedDependencyListEntry> + { + _singleDependency, + dependency, + }; + return; + } + + _dependencies.Add(dependency); + } + + public void MarkDependencies( + DependencyAnalyzer analyzer, + DependencyNodeCore condition) + { + if (_dependencies is null) + { + analyzer.AddToMarkStack(_singleDependency.Node, _singleDependency.Reason, _singleDependency.OtherReasonNode, condition); + return; + } + + foreach (DependencyNodeCore.CombinedDependencyListEntry dependency in _dependencies) + { + analyzer.AddToMarkStack(dependency.Node, dependency.Reason, dependency.OtherReasonNode, condition); + } + } + } + private sealed class RandomInsertStack { private List _nodes = new List(); @@ -199,16 +247,19 @@ private void GetStaticDependenciesImpl(DependencyNodeCore } else { - HashSet.CombinedDependencyListEntry> storedDependencySet; - if (!_conditional_dependency_store.TryGetValue(dependency.OtherReasonNode, out storedDependencySet)) - { - storedDependencySet = new HashSet.CombinedDependencyListEntry>(); - _conditional_dependency_store.Add(dependency.OtherReasonNode, storedDependencySet); - } // Swap out other reason node as we're storing that as the dictionary key DependencyNodeCore.CombinedDependencyListEntry conditionalDependencyStoreEntry = new DependencyNodeCore.CombinedDependencyListEntry(dependency.Node, node, dependency.Reason); - storedDependencySet.Add(conditionalDependencyStoreEntry); + ConditionalDependencyBucket storedDependencies; + if (!_conditionalDependencyStore.TryGetValue(dependency.OtherReasonNode, out storedDependencies)) + { + storedDependencies = new ConditionalDependencyBucket(conditionalDependencyStoreEntry); + _conditionalDependencyStore.Add(dependency.OtherReasonNode, storedDependencies); + } + else + { + storedDependencies.Add(conditionalDependencyStoreEntry); + } } } } @@ -266,15 +317,9 @@ private void ProcessMarkStack() // If this new node satisfies any stored conditional dependencies, // add them to the mark stack - HashSet.CombinedDependencyListEntry> storedDependencySet; - if (_conditional_dependency_store.TryGetValue(currentNode, out storedDependencySet)) + if (_conditionalDependencyStore.Remove(currentNode, out ConditionalDependencyBucket storedDependencies)) { - foreach (DependencyNodeCore.CombinedDependencyListEntry newlySatisfiedDependency in storedDependencySet) - { - AddToMarkStack(newlySatisfiedDependency.Node, newlySatisfiedDependency.Reason, newlySatisfiedDependency.OtherReasonNode, currentNode); - } - - _conditional_dependency_store.Remove(currentNode); + storedDependencies.MarkDependencies(this, currentNode); } }