From d707f6253e178812aec0e51b4196eb004ce1e257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 27 May 2021 16:35:20 +0200 Subject: [PATCH] Small fixes to sealed vtables (#1175) * Avoid double hashtable lookup * Avoid generating empty sealed vtables (basically, emitting a bunch of unreferenced symbol definitions in the object file) --- .../Compiler/DependencyAnalysis/SealedVTableNode.cs | 6 ++++++ .../Compiler/VirtualMethodCallHelper.cs | 12 ++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) 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 2d00ff57c91b..70819511a912 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs @@ -56,6 +56,12 @@ public int NumSealedVTableEntries } } + public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) + { + BuildSealedVTableSlots(factory, relocsOnly: false); + return NumSealedVTableEntries == 0; + } + /// /// Returns the slot of a method in the sealed vtable, or -1 if not found. This API should only be called after /// successfully building the sealed vtable slots. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs index ebaed1e915d5..5bf2d7f07f69 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/VirtualMethodCallHelper.cs @@ -15,10 +15,12 @@ public static int GetDefaultInterfaceMethodSlot(NodeFactory factory, MethodDesc { Debug.Assert(method.GetTypicalMethodDefinition().OwningType == interfaceOnDefinition.GetTypeDefinition()); + SealedVTableNode sealedVTable = factory.SealedVTable(implType); + // Ensure the sealed vtable is built before computing the slot - factory.SealedVTable(implType).BuildSealedVTableSlots(factory, relocsOnly: false /* GetVirtualMethodSlot is called in the final emission phase */); + sealedVTable.BuildSealedVTableSlots(factory, relocsOnly: false /* GetVirtualMethodSlot is called in the final emission phase */); - int sealedVTableSlot = factory.SealedVTable(implType).ComputeDefaultInterfaceMethodSlot(method, interfaceOnDefinition); + int sealedVTableSlot = sealedVTable.ComputeDefaultInterfaceMethodSlot(method, interfaceOnDefinition); if (sealedVTableSlot == -1) return -1; @@ -42,10 +44,12 @@ public static int GetVirtualMethodSlot(NodeFactory factory, MethodDesc method, T // does not get any sealed vtable entries Debug.Assert(!implType.IsArrayTypeWithoutGenericInterfaces()); + SealedVTableNode sealedVTable = factory.SealedVTable(implType); + // Ensure the sealed vtable is built before computing the slot - factory.SealedVTable(implType).BuildSealedVTableSlots(factory, relocsOnly: false /* GetVirtualMethodSlot is called in the final emission phase */); + sealedVTable.BuildSealedVTableSlots(factory, relocsOnly: false /* GetVirtualMethodSlot is called in the final emission phase */); - int sealedVTableSlot = factory.SealedVTable(implType).ComputeSealedVTableSlot(method); + int sealedVTableSlot = sealedVTable.ComputeSealedVTableSlot(method); if (sealedVTableSlot == -1) return -1;