From e3de8701a1a65ceaeb386f4b6afc35c91c3e95be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 9 Jan 2024 13:09:34 +0100 Subject: [PATCH] Make it possible for arrays to have default-implemented methods Within the managed type system, the array types are special. When asking question about virtual/interface methods implemented by arrays, one needs to switch from the array type (that doesn't have any virtual methods as far as the type system in concerned) to the `Array` type from corelib (that has the methods). The `GetClosestDefType` API is the API that does this transformation. We were not consistent enough in using it and it didn't work for default methods. In #95830, arrays are going to get a default interface method (the implementation of `IList.System.Collections.Generic.IReadOnlyList.get_Item` which is `virtual final` but still a new slot). --- .../Compiler/DependencyAnalysis/EETypeNode.cs | 2 +- .../Compiler/DependencyAnalysis/SealedVTableNode.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) 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 e136b1057cf15..a47312d706517 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -531,7 +531,7 @@ public sealed override IEnumerable GetConditionalSt if (!isStaticInterfaceMethod && defaultIntfMethod.IsCanonicalMethod(CanonicalFormKind.Any)) { // Canonical instance default methods need to go through a thunk that adds the right generic context - defaultIntfMethod = factory.TypeSystemContext.GetDefaultInterfaceMethodImplementationThunk(defaultIntfMethod, _type.ConvertToCanonForm(CanonicalFormKind.Specific), providingInterfaceDefinitionType); + defaultIntfMethod = factory.TypeSystemContext.GetDefaultInterfaceMethodImplementationThunk(defaultIntfMethod, defType.ConvertToCanonForm(CanonicalFormKind.Specific), providingInterfaceDefinitionType); } result.Add(new CombinedDependencyListEntry(factory.MethodEntrypoint(defaultIntfMethod), factory.VirtualMethodUse(interfaceMethod), "Interface method")); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs index d9b99d08bde3f..d27944d434e81 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs @@ -216,9 +216,11 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly) if (BuildSealedVTableSlots(factory, relocsOnly)) { + DefType defType = _type.GetClosestDefType(); + for (int i = 0; i < _sealedVTableEntries.Count; i++) { - IMethodNode relocTarget = _sealedVTableEntries[i].GetTarget(factory, _type); + IMethodNode relocTarget = _sealedVTableEntries[i].GetTarget(factory, defType); if (factory.Target.SupportsRelativePointers) objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32);