diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 250b8964a31caa..20a0a0ebd5a3f7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -52,15 +52,7 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact dependencyList.Add(factory.VTable(closestDefType), "VTable"); - if (_type.IsCanonicalSubtype(CanonicalFormKind.Any)) - { - // Track generic virtual methods that will get added to the GVM tables - if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0) - { - dependencyList.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods")); - } - } - else + if (!_type.IsCanonicalSubtype(CanonicalFormKind.Any)) { factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index c1e48b4901b1b6..d6ff866e7d0af5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -628,8 +628,6 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact // Generated type contains generic virtual methods that will get added to the GVM tables if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0) { - dependencies.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods")); - TypeDesc canonicalType = _type.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonicalType != _type) dependencies.Add(factory.ConstructedTypeSymbol(canonicalType), "Type with generic virtual methods"); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs index 66047d79f08228..09ff03cd1d7b07 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs @@ -41,7 +41,12 @@ public GVMDependenciesNode(MethodDesc method) public override IEnumerable GetStaticDependencies(NodeFactory factory) { if (!_method.IsAbstract) + { yield return new DependencyListEntry(factory.GenericVirtualMethodImpl(_method), "Implementation of the generic virtual method"); + + if (!_method.OwningType.IsInterface) + yield return new DependencyListEntry(factory.GVMMetadata(_method.GetTypicalMethodDefinition(), _method.GetTypicalMethodDefinition()), "Implementation of the generic virtual method"); + } } public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; @@ -124,11 +129,12 @@ public override IEnumerable SearchDynamicDependenci MethodDesc slotDecl = interfaceMethod.Signature.IsStatic ? potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodToStaticVirtualMethodOnType(interfaceMethod) : potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodTarget(interfaceMethod); + DefaultInterfaceMethodResolution defaultResolution = DefaultInterfaceMethodResolution.None; if (slotDecl == null) { // The method might be implemented through a default interface method - var result = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethod, out slotDecl); - if (result != DefaultInterfaceMethodResolution.DefaultImplementation) + defaultResolution = potentialOverrideDefinition.InstantiateAsOpen().ResolveInterfaceMethodToDefaultImplementationOnType(interfaceMethod, out slotDecl); + if (defaultResolution != DefaultInterfaceMethodResolution.DefaultImplementation) { slotDecl = null; } @@ -147,6 +153,8 @@ public override IEnumerable SearchDynamicDependenci else dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(implementingMethodInstantiation.GetCanonMethodTarget(CanonicalFormKind.Specific)), null, "ImplementingMethodInstantiation")); + dynamicDependencies.Add(new CombinedDependencyListEntry(factory.InterfaceGVMMetadata(interfaceMethod, slotDecl.GetTypicalMethodDefinition(), potentialOverrideDefinition, defaultResolution), null, "Metadata")); + TypeSystemEntity origin = (implementingMethodInstantiation.OwningType != potentialOverrideType) ? potentialOverrideType : null; factory.MetadataManager.NoteOverridingMethod(_method, implementingMethodInstantiation, origin); } @@ -200,6 +208,9 @@ public override IEnumerable SearchDynamicDependenci dynamicDependencies.Add(new CombinedDependencyListEntry( factory.GenericVirtualMethodImpl(instantiatedTargetMethod), null, "DerivedMethodInstantiation")); + dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMMetadata( + methodToResolve.GetTypicalMethodDefinition(), instantiatedTargetMethod.GetTypicalMethodDefinition()), null, "Metadata")); + factory.MetadataManager.NoteOverridingMethod(_method, instantiatedTargetMethod); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMMetadataNode.cs new file mode 100644 index 00000000000000..09165b950a06c5 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMMetadataNode.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Collections.Generic; + +using ILCompiler.DependencyAnalysisFramework; +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis +{ + internal sealed class GVMMetadataNode : SortableDependencyNode + { + public MethodDesc CallingMethod { get; } + public MethodDesc ImplementationMethod { get; } + public GVMMetadataNode(MethodDesc callingMethod, MethodDesc implementationMethod) + => (CallingMethod, ImplementationMethod) = (callingMethod, implementationMethod); + + protected override string GetName(NodeFactory context) => + $"GVM method: {CallingMethod}: {ImplementationMethod}"; + + public override IEnumerable GetStaticDependencies(NodeFactory factory) + { + var list = new DependencyList(); + GenericVirtualMethodTableNode.GetGenericVirtualMethodImplementationDependencies(ref list, factory, CallingMethod, ImplementationMethod); + return list; + } + + public override int ClassCode => 0x2898423; + + public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) + { + var otherNode = (GVMMetadataNode)other; + + int result = comparer.Compare(CallingMethod, otherNode.CallingMethod); + if (result != 0) + return result; + + return comparer.Compare(ImplementationMethod, otherNode.ImplementationMethod); + } + + public override bool InterestingForDynamicDependencyAnalysis => false; + public override bool HasDynamicDependencies => false; + public override bool HasConditionalStaticDependencies => false; + public override bool StaticDependenciesAreComputed => true; + public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; + public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => null; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs index 3df07d1581bca5..5386c644f1187f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs @@ -80,13 +80,9 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) if (relocsOnly) return new ObjectData(Array.Empty(), Array.Empty(), 1, new ISymbolDefinitionNode[] { this }); - // Build the GVM table entries from the list of interesting GVMTableEntryNodes - foreach (var interestingEntry in factory.MetadataManager.GetTypeGVMEntries()) + foreach (var typeGVMEntryInfo in factory.MetadataManager.GetGVMMetadatas()) { - foreach (var typeGVMEntryInfo in interestingEntry.ScanForGenericVirtualMethodEntries()) - { - AddGenericVirtualMethodImplementation(typeGVMEntryInfo.CallingMethod, typeGVMEntryInfo.ImplementationMethod); - } + AddGenericVirtualMethodImplementation(typeGVMEntryInfo.CallingMethod, typeGVMEntryInfo.ImplementationMethod); } // Ensure the native layout blob has been saved diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGVMMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGVMMetadataNode.cs new file mode 100644 index 00000000000000..7238efce24b9b1 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGVMMetadataNode.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Collections.Generic; + +using ILCompiler.DependencyAnalysisFramework; +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis +{ + internal sealed class InterfaceGVMMetadataNode : SortableDependencyNode + { + public MethodDesc CallingMethod { get; } + public MethodDesc ImplementationMethod { get; } + public TypeDesc ImplementationType { get; } + public DefaultInterfaceMethodResolution DefaultResolution { get; } + + public InterfaceGVMMetadataNode(MethodDesc callingMethod, MethodDesc implementationMethod, + TypeDesc implementationType, DefaultInterfaceMethodResolution defaultResolution) + => (CallingMethod, ImplementationMethod, ImplementationType, DefaultResolution) + = (callingMethod, implementationMethod, implementationType, defaultResolution); + + protected override string GetName(NodeFactory context) => + $"GVM interface method: {CallingMethod} on {ImplementationType}: {ImplementationMethod}, {DefaultResolution}"; + + public override IEnumerable GetStaticDependencies(NodeFactory factory) + { + var list = new DependencyList(); + InterfaceGenericVirtualMethodTableNode.GetGenericVirtualMethodImplementationDependencies(ref list, factory, CallingMethod, ImplementationType, ImplementationMethod); + return list; + } + + public override int ClassCode => 0x48bcaa1; + + public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) + { + var otherNode = (InterfaceGVMMetadataNode)other; + + int result = comparer.Compare(ImplementationType, otherNode.ImplementationType); + if (result != 0) + return result; + + DefType[] interfaceList = ImplementationType.RuntimeInterfaces; + int thisIndex = Array.IndexOf(interfaceList, CallingMethod.OwningType); + int thatIndex = Array.IndexOf(interfaceList, otherNode.CallingMethod.OwningType); + + Debug.Assert(thisIndex >= 0 && thatIndex >= 0); + + result = Comparer.Default.Compare(thisIndex, thatIndex); + if (result != 0) + return result; + + return comparer.Compare(ImplementationMethod, otherNode.ImplementationMethod); + } + + public override bool InterestingForDynamicDependencyAnalysis => false; + public override bool HasDynamicDependencies => false; + public override bool HasConditionalStaticDependencies => false; + public override bool StaticDependenciesAreComputed => true; + public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; + public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => null; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs index e1f432af8ff3c6..e994224d38bea2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs @@ -125,13 +125,9 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) if (relocsOnly) return new ObjectData(Array.Empty(), Array.Empty(), 1, new ISymbolDefinitionNode[] { this }); - // Build the GVM table entries from the list of interesting GVMTableEntryNodes - foreach (var interestingEntry in factory.MetadataManager.GetTypeGVMEntries()) + foreach (var typeGVMEntryInfo in factory.MetadataManager.GetInterfaceGVMMetadatas()) { - foreach (var typeGVMEntryInfo in interestingEntry.ScanForInterfaceGenericVirtualMethodEntries()) - { - AddGenericVirtualMethodImplementation(typeGVMEntryInfo.CallingMethod, typeGVMEntryInfo.ImplementationType, typeGVMEntryInfo.ImplementationMethod, typeGVMEntryInfo.DefaultResolution); - } + AddGenericVirtualMethodImplementation(typeGVMEntryInfo.CallingMethod, typeGVMEntryInfo.ImplementationType, typeGVMEntryInfo.ImplementationMethod, typeGVMEntryInfo.DefaultResolution); } // Ensure the native layout blob has been saved 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 ef6a4fed1c1949..9528f9dc29a810 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -339,9 +339,14 @@ private void CreateNodeCaches() return new ExactMethodInstantiationsEntryNode(method); }); - _gvmTableEntries = new NodeCache(type => + _gvmMetadatas = new NodeCache(key => { - return new TypeGVMEntriesNode(type); + return new GVMMetadataNode(key.CallingMethod, key.ImplementationMethod); + }); + + _interfaceGvmMetadatas = new NodeCache(key => + { + return new InterfaceGVMMetadataNode(key.CallingMethod, key.ImplementationMethod, key.ImplementationType, key.DefaultResolution); }); _addressTakenMethods = new NodeCache(method => @@ -1165,10 +1170,16 @@ public ExactMethodInstantiationsEntryNode ExactMethodInstantiationsHashtableEntr return _exactMethodEntries.GetOrAdd(method); } - private NodeCache _gvmTableEntries; - internal TypeGVMEntriesNode TypeGVMEntries(TypeDesc type) + private NodeCache _gvmMetadatas; + internal GVMMetadataNode GVMMetadata(MethodDesc callingMethod, MethodDesc implementationMethod) + { + return _gvmMetadatas.GetOrAdd(new GVMMetadataKey(callingMethod, implementationMethod)); + } + + private NodeCache _interfaceGvmMetadatas; + internal InterfaceGVMMetadataNode InterfaceGVMMetadata(MethodDesc callingMethod, MethodDesc implementationMethod, TypeDesc implementationType, DefaultInterfaceMethodResolution defaultResolution) { - return _gvmTableEntries.GetOrAdd(type); + return _interfaceGvmMetadatas.GetOrAdd(new InterfaceGVMMetadataKey(callingMethod, implementationMethod, implementationType, defaultResolution)); } private NodeCache _addressTakenMethods; @@ -1739,5 +1750,33 @@ private struct MethodILKey : IEquatable public override int GetHashCode() => MethodIL.OwningMethod.GetHashCode(); } + + private struct GVMMetadataKey : IEquatable + { + public readonly MethodDesc CallingMethod; + public readonly MethodDesc ImplementationMethod; + + public GVMMetadataKey(MethodDesc callingMethod, MethodDesc implementationMethod) + => (CallingMethod, ImplementationMethod) = (callingMethod, implementationMethod); + + public override bool Equals(object obj) => obj is GVMMetadataKey other && Equals(other); + public bool Equals(GVMMetadataKey other) => CallingMethod == other.CallingMethod && ImplementationMethod == other.ImplementationMethod; + public override int GetHashCode() => HashCode.Combine(CallingMethod, ImplementationMethod); + } + + private struct InterfaceGVMMetadataKey : IEquatable + { + public readonly MethodDesc CallingMethod; + public readonly MethodDesc ImplementationMethod; + public readonly TypeDesc ImplementationType; + public readonly DefaultInterfaceMethodResolution DefaultResolution; + + public InterfaceGVMMetadataKey(MethodDesc callingMethod, MethodDesc implementationMethod, TypeDesc implementationType, DefaultInterfaceMethodResolution resolution) + => (CallingMethod, ImplementationMethod, ImplementationType, DefaultResolution) = (callingMethod, implementationMethod, implementationType, resolution); + + public override bool Equals(object obj) => obj is InterfaceGVMMetadataKey other && Equals(other); + public bool Equals(InterfaceGVMMetadataKey other) => CallingMethod == other.CallingMethod && ImplementationType == other.ImplementationType; + public override int GetHashCode() => HashCode.Combine(CallingMethod, ImplementationType); + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs deleted file mode 100644 index e3a0b4d38ab17e..00000000000000 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeGVMEntriesNode.cs +++ /dev/null @@ -1,122 +0,0 @@ -// 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 System.Diagnostics; - -using Internal.TypeSystem; -using ILCompiler.DependencyAnalysisFramework; - -namespace ILCompiler.DependencyAnalysis -{ - /// - /// This node is used for GVM dependency analysis and GVM tables building. Given an input - /// type, this node can scan the type for a list of GVM table entries, and compute their dependencies. - /// - internal sealed class TypeGVMEntriesNode : DependencyNodeCore - { - internal class TypeGVMEntryInfo - { - public TypeGVMEntryInfo(MethodDesc callingMethod, MethodDesc implementationMethod) - { - CallingMethod = callingMethod; - ImplementationMethod = implementationMethod; - } - public MethodDesc CallingMethod { get; } - public MethodDesc ImplementationMethod { get; } - } - - internal sealed class InterfaceGVMEntryInfo : TypeGVMEntryInfo - { - public InterfaceGVMEntryInfo(MethodDesc callingMethod, MethodDesc implementationMethod, - TypeDesc implementationType, DefaultInterfaceMethodResolution defaultResolution) - : base(callingMethod, implementationMethod) - { - ImplementationType = implementationType; - DefaultResolution = defaultResolution; - } - - public TypeDesc ImplementationType { get; } - public DefaultInterfaceMethodResolution DefaultResolution { get; } - } - - private readonly TypeDesc _associatedType; - private DependencyList _staticDependencies; - - public TypeGVMEntriesNode(TypeDesc associatedType) - { - Debug.Assert(associatedType.IsTypeDefinition); - _associatedType = associatedType; - } - - public TypeDesc AssociatedType => _associatedType; - - public override bool HasConditionalStaticDependencies => false; - public override bool HasDynamicDependencies => false; - public override bool InterestingForDynamicDependencyAnalysis => false; - public override bool StaticDependenciesAreComputed => true; - protected override string GetName(NodeFactory factory) => "__TypeGVMEntriesNode_" + factory.NameMangler.GetMangledTypeName(_associatedType); - public override IEnumerable GetConditionalStaticDependencies(NodeFactory context) => null; - public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory context) => null; - - public override IEnumerable GetStaticDependencies(NodeFactory context) - { - if (_staticDependencies == null) - { - _staticDependencies = new DependencyList(); - - foreach (var entry in ScanForGenericVirtualMethodEntries()) - GenericVirtualMethodTableNode.GetGenericVirtualMethodImplementationDependencies(ref _staticDependencies, context, entry.CallingMethod, entry.ImplementationMethod); - - foreach (var entry in ScanForInterfaceGenericVirtualMethodEntries()) - InterfaceGenericVirtualMethodTableNode.GetGenericVirtualMethodImplementationDependencies(ref _staticDependencies, context, entry.CallingMethod, entry.ImplementationType, entry.ImplementationMethod); - } - - return _staticDependencies; - } - - public IEnumerable ScanForGenericVirtualMethodEntries() - { - foreach (MethodDesc decl in _associatedType.EnumAllVirtualSlots()) - { - // Non-Generic virtual methods are tracked by an orthogonal mechanism. - if (!decl.HasInstantiation) - continue; - - MethodDesc impl = _associatedType.FindVirtualFunctionTargetMethodOnObjectType(decl); - - if (impl.OwningType == _associatedType) - yield return new TypeGVMEntryInfo(decl, impl); - } - } - - public IEnumerable ScanForInterfaceGenericVirtualMethodEntries() - { - foreach (var iface in _associatedType.RuntimeInterfaces) - { - foreach (var method in iface.GetVirtualMethods()) - { - if (!method.HasInstantiation) - continue; - - DefaultInterfaceMethodResolution resolution = DefaultInterfaceMethodResolution.None; - MethodDesc slotDecl = method.Signature.IsStatic ? - _associatedType.ResolveInterfaceMethodToStaticVirtualMethodOnType(method) : _associatedType.ResolveInterfaceMethodTarget(method); - if (slotDecl == null) - { - resolution = _associatedType.ResolveInterfaceMethodToDefaultImplementationOnType(method, out slotDecl); - if (resolution != DefaultInterfaceMethodResolution.DefaultImplementation) - slotDecl = null; - } - - if (slotDecl != null - || resolution == DefaultInterfaceMethodResolution.Diamond - || resolution == DefaultInterfaceMethodResolution.Reabstraction) - { - yield return new InterfaceGVMEntryInfo(method, slotDecl, _associatedType, resolution); - } - } - } - } - } -} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index 93a2e79d9df627..49eedb3b20a4c5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -72,8 +72,8 @@ public abstract class MetadataManager : ICompilationRootProvider private readonly SortedSet _genericDictionariesGenerated = new SortedSet(CompilerComparer.Instance); private readonly SortedSet _methodBodiesGenerated = new SortedSet(CompilerComparer.Instance); private readonly SortedSet _frozenObjects = new SortedSet(CompilerComparer.Instance); - private readonly SortedSet _typeGVMEntries - = new SortedSet(Comparer.Create((a, b) => TypeSystemComparer.Instance.Compare(a.AssociatedType, b.AssociatedType))); + private readonly SortedSet _gvmMetadatas = new SortedSet(CompilerComparer.Instance); + private readonly SortedSet _interfaceGvmMetadatas = new SortedSet(CompilerComparer.Instance); private readonly SortedSet _typesWithDelegateMarshalling = new SortedSet(TypeSystemComparer.Instance); private readonly SortedSet _typesWithStructMarshalling = new SortedSet(TypeSystemComparer.Instance); private HashSet _templateMethodEntries = new HashSet(); @@ -286,10 +286,14 @@ protected virtual void Graph_NewMarkedNode(DependencyNodeCore obj) _typesWithThreadStaticsGenerated.Add(threadStaticsNode.Type); } - var gvmEntryNode = obj as TypeGVMEntriesNode; - if (gvmEntryNode != null) + if (obj is GVMMetadataNode gvmMetadataNode) { - _typeGVMEntries.Add(gvmEntryNode); + _gvmMetadatas.Add(gvmMetadataNode); + } + + if (obj is InterfaceGVMMetadataNode interfaceGvmMetadataNode) + { + _interfaceGvmMetadatas.Add(interfaceGvmMetadataNode); } var dictionaryNode = obj as GenericDictionaryNode; @@ -1024,9 +1028,14 @@ internal IEnumerable GetTypesWithStaticBases() internal bool HasThreadStaticBase(MetadataType type) => _typesWithThreadStaticsGenerated.Contains(type); internal bool HasConstructedEEType(TypeDesc type) => _typesWithConstructedEETypesGenerated.Contains(type); - internal IEnumerable GetTypeGVMEntries() + internal IEnumerable GetGVMMetadatas() + { + return _gvmMetadatas; + } + + internal IEnumerable GetInterfaceGVMMetadatas() { - return _typeGVMEntries; + return _interfaceGvmMetadatas; } internal IReadOnlyCollection GetCompiledGenericDictionaries() diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 3ac5cfb27289d4..82997a013ba6cc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -502,9 +502,10 @@ + - +