diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/CompilerComparer.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/CompilerComparer.cs index 632d8f55ff2b4..46f9e704a848b 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/CompilerComparer.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/CompilerComparer.cs @@ -11,6 +11,8 @@ namespace ILCompiler.DependencyAnalysis { public class CompilerComparer : TypeSystemComparer, IComparer { + public static new CompilerComparer Instance { get; } = new CompilerComparer(); + public int Compare(ISortableNode x, ISortableNode y) { if (x == y) diff --git a/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs b/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs index f648411312cf6..add498968abb1 100644 --- a/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs +++ b/src/coreclr/tools/Common/TypeSystem/Sorting/TypeSystemComparer.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; + using Debug = System.Diagnostics.Debug; namespace Internal.TypeSystem @@ -23,8 +25,10 @@ namespace Internal.TypeSystem // to sort itself with respect to other instances of the same type. // Comparisons between different categories of types are centralized to a single location that // can provide rules to sort them. - public class TypeSystemComparer + public class TypeSystemComparer : IComparer, IComparer, IComparer, IComparer { + public static TypeSystemComparer Instance { get; } = new TypeSystemComparer(); + public int Compare(TypeDesc x, TypeDesc y) { if (x == y) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs index 9653f64718c74..26ddc6da9a13b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs @@ -277,7 +277,7 @@ private void ComputeLayout() layout[index++] = entry; } - var comparer = new GenericLookupResult.Comparer(new TypeSystemComparer()); + var comparer = new GenericLookupResult.Comparer(TypeSystemComparer.Instance); Array.Sort(layout, comparer.Compare); // Only publish after the full layout is computed. Races are fine. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs index 87be95102005d..334b73adbddf3 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs @@ -55,12 +55,9 @@ public int GetIdForMethod(MethodDesc dynamicInvokeMethod, NodeFactory factory) private void BuildMethodToIdMap(NodeFactory factory) { + // Get a sorted list of generated stubs List methods = new List(factory.MetadataManager.GetDynamicInvokeTemplateMethods()); - // Sort the stubs - var typeSystemComparer = new TypeSystemComparer(); - methods.Sort((first, second) => typeSystemComparer.Compare(first, second)); - // Assign each stub an ID var methodToTemplateIndex = new Dictionary(); foreach (MethodDesc method in methods) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellSectionNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellSectionNode.cs index da79598e1c6c2..13cdd42590982 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellSectionNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellSectionNode.cs @@ -93,7 +93,7 @@ protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, No private class DispatchCellComparer : IComparer { private readonly NodeFactory _factory; - private readonly TypeSystemComparer _comparer = new TypeSystemComparer(); + private readonly TypeSystemComparer _comparer = TypeSystemComparer.Instance; public DispatchCellComparer(NodeFactory factory) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index 9fef80ff6ce47..6597476d51cab 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -1089,12 +1089,12 @@ public string GetSymbolAlternateName(ISymbolNode node) public ArrayOfEmbeddedPointersNode GCStaticsRegion = new ArrayOfEmbeddedPointersNode( "__GCStaticRegionStart", "__GCStaticRegionEnd", - new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer())); + new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance)); public ArrayOfEmbeddedDataNode ThreadStaticsRegion = new ArrayOfEmbeddedDataNode( "__ThreadStaticRegionStart", "__ThreadStaticRegionEnd", - new SortableDependencyNode.EmbeddedObjectNodeComparer(new CompilerComparer())); + new SortableDependencyNode.EmbeddedObjectNodeComparer(CompilerComparer.Instance)); public ArrayOfEmbeddedPointersNode EagerCctorTable = new ArrayOfEmbeddedPointersNode( "__EagerCctorStart", @@ -1104,12 +1104,12 @@ public string GetSymbolAlternateName(ISymbolNode node) public ArrayOfEmbeddedPointersNode DispatchMapTable = new ArrayOfEmbeddedPointersNode( "__DispatchMapTableStart", "__DispatchMapTableEnd", - new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer())); + new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance)); public ArrayOfEmbeddedDataNode FrozenSegmentRegion = new ArrayOfFrozenObjectsNode( "__FrozenSegmentRegionStart", "__FrozenSegmentRegionEnd", - new SortableDependencyNode.EmbeddedObjectNodeComparer(new CompilerComparer())); + new SortableDependencyNode.EmbeddedObjectNodeComparer(CompilerComparer.Instance)); internal ModuleInitializerListNode ModuleInitializerList = new ModuleInitializerListNode(); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs index fe9d0cd8b8927..12472274c917a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs @@ -51,6 +51,8 @@ public TypeGVMEntriesNode(TypeDesc associatedType) _associatedType = associatedType; } + public TypeDesc AssociatedType => _associatedType; + public override bool HasConditionalStaticDependencies => false; public override bool HasDynamicDependencies => false; public override bool InterestingForDynamicDependencyAnalysis => false; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index e655b209a7ac8..a8b7f04e7886a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -47,17 +47,18 @@ public abstract class MetadataManager : ICompilationRootProvider protected readonly ManifestResourceBlockingPolicy _resourceBlockingPolicy; protected readonly DynamicInvokeThunkGenerationPolicy _dynamicInvokeThunkGenerationPolicy; - private List _cctorContextsGenerated = new List(); - private readonly HashSet _typesWithEETypesGenerated = new HashSet(); - private readonly HashSet _typesWithConstructedEETypesGenerated = new HashSet(); - private HashSet _methodsGenerated = new HashSet(); - private HashSet _reflectableMethods = new HashSet(); - private HashSet _genericDictionariesGenerated = new HashSet(); - private HashSet _methodBodiesGenerated = new HashSet(); - private List _typeGVMEntries = new List(); - private HashSet _typesWithDelegateMarshalling = new HashSet(); - private HashSet _typesWithStructMarshalling = new HashSet(); - private HashSet _dynamicInvokeTemplates = new HashSet(); + private readonly SortedSet _cctorContextsGenerated = new SortedSet(CompilerComparer.Instance); + private readonly SortedSet _typesWithEETypesGenerated = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _typesWithConstructedEETypesGenerated = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _methodsGenerated = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _reflectableMethods = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _genericDictionariesGenerated = new SortedSet(CompilerComparer.Instance); + private readonly SortedSet _methodBodiesGenerated = new SortedSet(CompilerComparer.Instance); + private readonly SortedSet _typeGVMEntries + = new SortedSet(Comparer.Create((a, b) => TypeSystemComparer.Instance.Compare(a.AssociatedType, b.AssociatedType))); + private readonly SortedSet _typesWithDelegateMarshalling = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _typesWithStructMarshalling = new SortedSet(TypeSystemComparer.Instance); + private readonly SortedSet _dynamicInvokeTemplates = new SortedSet(TypeSystemComparer.Instance); private HashSet _templateMethodEntries = new HashSet(); internal NativeLayoutInfoNode NativeLayoutInfo { get; private set; } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs index e81024fc92daa..a9a414ac1e864 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/GCRefMapNode.cs @@ -59,7 +59,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) definedSymbols: new ISymbolDefinitionNode[] { this }); } - _methods.MergeSort(new CompilerComparer()); + _methods.MergeSort(CompilerComparer.Instance); GCRefMapBuilder builder = new GCRefMapBuilder(factory.Target, relocsOnly); builder.Builder.RequireInitialAlignment(4); builder.Builder.AddSymbol(this); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs index 4cdb5ca96e43e..2b4925de70874 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionNode.cs @@ -12,7 +12,7 @@ public class ImportSectionNode : EmbeddedObjectNode { private class ImportTable : ArrayOfEmbeddedDataNode { - public ImportTable(string startSymbol, string endSymbol) : base(startSymbol, endSymbol, nodeSorter: new EmbeddedObjectNodeComparer(new CompilerComparer())) {} + public ImportTable(string startSymbol, string endSymbol) : base(startSymbol, endSymbol, nodeSorter: new EmbeddedObjectNodeComparer(CompilerComparer.Instance)) {} public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => false; @@ -45,7 +45,7 @@ public ImportSectionNode(string name, CorCompileImportType importType, CorCompil _emitGCRefMap = emitGCRefMap; _imports = new ImportTable(_name + "_ImportBegin", _name + "_ImportEnd"); - _signatures = new ArrayOfEmbeddedPointersNode(_name + "_SigBegin", _name + "_SigEnd", new EmbeddedObjectNodeComparer(new CompilerComparer())); + _signatures = new ArrayOfEmbeddedPointersNode(_name + "_SigBegin", _name + "_SigEnd", new EmbeddedObjectNodeComparer(CompilerComparer.Instance)); _signatureList = new List(); _gcRefMap = _emitGCRefMap ? new GCRefMapNode(this) : null; } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionsTableNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionsTableNode.cs index 1635b502ef2c1..61b5e394030dc 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionsTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportSectionsTableNode.cs @@ -12,7 +12,7 @@ public class ImportSectionsTableNode : ArrayOfEmbeddedDataNode { public ProfileDataSectionNode() - : base("ProfileDataSectionNode_Begin", "ProfileDataSectionNode_End", new EmbeddedObjectNodeComparer(new CompilerComparer())) + : base("ProfileDataSectionNode_Begin", "ProfileDataSectionNode_End", new EmbeddedObjectNodeComparer(CompilerComparer.Instance)) { } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/RuntimeFunctionsGCInfoNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/RuntimeFunctionsGCInfoNode.cs index e9971dd828fde..e6c437efc04a8 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/RuntimeFunctionsGCInfoNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/RuntimeFunctionsGCInfoNode.cs @@ -8,7 +8,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun public class RuntimeFunctionsGCInfoNode : ArrayOfEmbeddedDataNode { public RuntimeFunctionsGCInfoNode() - : base("RuntimeFunctionsGCInfo_Begin", "RuntimeFunctionsGCInfo_End", new EmbeddedObjectNodeComparer(new CompilerComparer())) + : base("RuntimeFunctionsGCInfo_Begin", "RuntimeFunctionsGCInfo_End", new EmbeddedObjectNodeComparer(CompilerComparer.Instance)) { } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index 4fd1f958d9c3b..59fc8e723eeca 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -727,7 +727,7 @@ public void AttachToDependencyGraph(DependencyAnalyzerBase graph) if (methodsToInsertInstrumentationDataFor.Count != 0) { MethodDesc[] methodsToInsert = methodsToInsertInstrumentationDataFor.ToArray(); - methodsToInsert.MergeSort(new TypeSystemComparer().Compare); + methodsToInsert.MergeSort(TypeSystemComparer.Instance.Compare); InstrumentationDataTable = new InstrumentationDataTableNode(this, methodsToInsert, ProfileDataManager); Header.Add(Internal.Runtime.ReadyToRunSectionType.PgoInstrumentationData, InstrumentationDataTable, InstrumentationDataTable); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index ad6f407ff7d80..3c2bb4655273d 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -413,7 +413,7 @@ private void RewriteComponentFile(string inputFile, string outputFile, string ow win32Resources: new Win32Resources.ResourceData(inputModule), flags); - IComparer> comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()); + IComparer> comparer = new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance); DependencyAnalyzerBase componentGraph = new DependencyAnalyzer, NodeFactory>(componentFactory, comparer); componentGraph.AddRoot(componentFactory.Header, "Component module R2R header"); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index 46ed11d236a95..3ab06566cd443 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -244,7 +244,7 @@ public override ICompilation ToCompilation() factory.CompositeImageSettings = _compositeImageSettings; - IComparer> comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()); + IComparer> comparer = new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance); DependencyAnalyzerBase graph = CreateDependencyGraph(factory, comparer); List corJitFlags = new List { CorJitFlag.CORJIT_FLAG_DEBUG_INFO }; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunFileLayoutOptimizer.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunFileLayoutOptimizer.cs index 4ef5443e4f547..553a71907bad4 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunFileLayoutOptimizer.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunFileLayoutOptimizer.cs @@ -92,7 +92,7 @@ public ImmutableArray> ApplyProfilerGuidedMethod } var newNodesArray = nodes.ToArray(); - newNodesArray.MergeSortAllowDuplicates(new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer())); + newNodesArray.MergeSortAllowDuplicates(new SortableDependencyNode.ObjectNodeComparer(CompilerComparer.Instance)); return newNodesArray.ToImmutableArray(); void ApplySortToDependencies(DependencyNodeCore node, int depth) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs index e8b8f0ab0b5e5..550de8c4a39fa 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunTableManager.cs @@ -101,7 +101,7 @@ public IEnumerable GetCompiledMethods(EcmaModule moduleToEnumerate, { if (!_sortedMethods) { - CompilerComparer comparer = new CompilerComparer(); + CompilerComparer comparer = CompilerComparer.Instance; SortableDependencyNode.ObjectNodeComparer objectNodeComparer = new SortableDependencyNode.ObjectNodeComparer(comparer); Comparison sortHelper = (x, y) => { diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index 9f6f6eb400e33..a9997a0b04736 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -129,7 +129,7 @@ public override ICompilation ToCompilation() var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, GetPreinitializationManager()); JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions, _jitPath); - DependencyAnalyzerBase graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer())); + DependencyAnalyzerBase graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(CompilerComparer.Instance)); return new RyuJitCompilation(graph, factory, _compilationRoots, _ilProvider, _debugInformationProvider, _logger, _devirtualizationManager, _inliningPolicy ?? _compilationGroup, _instructionSetSupport, _profileDataManager, _methodImportationErrorProvider, options, _parallelism); } }