Skip to content

Commit 108fa78

Browse files
Only add GVMDependencies for types with used GVMs (#118704)
Ever since GVM support was added to native AOT, we were generating the GVM resolution metadata for every type considered allocated. This included GVMs that were never even called: see `TypeGVMEntriesNode` that simply goes over everything on the type - we were adding a `TypeGVMEntriesNode` for all allocated types that have something to do with GVMs. This PR changes it so that we only generate `TypeGVMEntries` for types that have at least one used GVM. This is a scoped down version of #118632 (that tries to track things per-method) with a lot less risk.
1 parent 7987df4 commit 108fa78

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,7 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
5252

5353
dependencyList.Add(factory.VTable(closestDefType), "VTable");
5454

55-
if (_type.IsCanonicalSubtype(CanonicalFormKind.Any))
56-
{
57-
// Track generic virtual methods that will get added to the GVM tables
58-
if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0)
59-
{
60-
dependencyList.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods"));
61-
}
62-
}
63-
else
55+
if (!_type.IsCanonicalSubtype(CanonicalFormKind.Any))
6456
{
6557
factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type);
6658
}

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,6 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
628628
// Generated type contains generic virtual methods that will get added to the GVM tables
629629
if ((_virtualMethodAnalysisFlags & VirtualMethodAnalysisFlags.NeedsGvmEntries) != 0)
630630
{
631-
dependencies.Add(new DependencyListEntry(factory.TypeGVMEntries(_type.GetTypeDefinition()), "Type with generic virtual methods"));
632-
633631
TypeDesc canonicalType = _type.ConvertToCanonForm(CanonicalFormKind.Specific);
634632
if (canonicalType != _type)
635633
dependencies.Add(factory.ConstructedTypeSymbol(canonicalType), "Type with generic virtual methods");

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GVMDependenciesNode.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ public GVMDependenciesNode(MethodDesc method)
4141
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
4242
{
4343
if (!_method.IsAbstract)
44+
{
4445
yield return new DependencyListEntry(factory.GenericVirtualMethodImpl(_method), "Implementation of the generic virtual method");
46+
}
47+
48+
if (!_method.OwningType.IsInterface)
49+
{
50+
yield return new DependencyListEntry(factory.TypeGVMEntries(_method.OwningType.GetTypeDefinition()), "Resolution metadata");
51+
}
4552
}
4653

4754
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory context) => null;
@@ -95,6 +102,8 @@ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependenci
95102
potentialOverrideType.ConvertToCanonForm(CanonicalFormKind.Specific) != potentialOverrideType)
96103
continue;
97104

105+
bool foundImpl = false;
106+
98107
// If this is an interface gvm, look for types that implement the interface
99108
// and other instantantiations that have the same canonical form.
100109
// This ensure the various slot numbers remain equivalent across all types where there is an equivalence
@@ -150,6 +159,8 @@ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependenci
150159
TypeSystemEntity origin = (implementingMethodInstantiation.OwningType != potentialOverrideType) ? potentialOverrideType : null;
151160
factory.MetadataManager.NoteOverridingMethod(_method, implementingMethodInstantiation, origin);
152161
}
162+
163+
foundImpl = true;
153164
}
154165
}
155166
}
@@ -201,7 +212,20 @@ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependenci
201212
factory.GenericVirtualMethodImpl(instantiatedTargetMethod), null, "DerivedMethodInstantiation"));
202213

203214
factory.MetadataManager.NoteOverridingMethod(_method, instantiatedTargetMethod);
215+
216+
foundImpl = true;
217+
}
218+
}
219+
220+
if (foundImpl)
221+
{
222+
TypeDesc currentType = potentialOverrideType;
223+
do
224+
{
225+
dynamicDependencies.Add(new CombinedDependencyListEntry(factory.TypeGVMEntries(currentType.GetTypeDefinition()), null, "Resolution metadata"));
226+
currentType = currentType.BaseType;
204227
}
228+
while (currentType != null);
205229
}
206230
}
207231

0 commit comments

Comments
 (0)