Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2017-06-12 21:47:56 +0300
committerGitHub <noreply@github.com>2017-06-12 21:47:56 +0300
commit717b4dbf806252d1847b5fdfed86859af15e2894 (patch)
treea8f3604d4680302818862e954d8c396918067e78
parent566051d731c0191eed1c674fecd5fbbe9823738d (diff)
Allow an external optimizer to specify VTable layout (#3854)
Adds an extensibility point to the `CompilationBuilder` that allows specifying how vtables should be built. We currently have two strategies: eagerly built VTables (where we just put all the virtual methods that the type specifies in the metadata into the VTable), and lazily built vtables (where we track virtual method usage during the compilation and only generate vtable slots for methods that were actually used). The advantage of the former is that we know the slot assignment very early on and can inline it into the codegen. The advantage of the latter is natural reduction of the amount of code we compile. I'm adding an option to specify optional optimization data that can be used instead of the lazily built strategy and making it possible for the IL scanner to generate this data. This way we can have an option where we both have the natural reduction in the amount of generated code, and also the inlining of slot numbers in codegen (that part depends on #3773 to light up.
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs6
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs6
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs5
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VTableSliceNode.cs106
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/ILScanner.cs29
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/VTableSliceProvider.cs28
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj1
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs2
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs5
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs2
16 files changed, 134 insertions, 73 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
index 838606a9d..6a8df8d8f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
@@ -24,6 +24,7 @@ namespace ILCompiler
protected OptimizationMode _optimizationMode = OptimizationMode.None;
protected bool _generateDebugInfo = false;
protected MetadataManager _metadataManager;
+ protected VTableSliceProvider _vtableSliceProvider = new LazyVTableSliceProvider();
public CompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup compilationGroup, NameMangler nameMangler)
{
@@ -63,6 +64,12 @@ namespace ILCompiler
return this;
}
+ public CompilationBuilder UseVTableSliceProvider(VTableSliceProvider provider)
+ {
+ _vtableSliceProvider = provider;
+ return this;
+ }
+
public CompilationBuilder UseDebugInfo(bool generateDebugInfo)
{
_generateDebugInfo = generateDebugInfo;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
index 3d1378efe..ad73f0a6f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
@@ -48,7 +48,7 @@ namespace ILCompiler.DependencyAnalysis
if (_type.RuntimeInterfaces.Length > 0)
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Canonical interface dispatch map");
- dependencyList.Add(factory.VTable(_type), "VTable");
+ dependencyList.Add(factory.VTable(closestDefType), "VTable");
if (_type.IsCanonicalSubtype(CanonicalFormKind.Universal))
dependencyList.Add(factory.NativeLayout.TemplateTypeLayout(_type), "Universal generic types always have template layout");
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
index e7889f2aa..1106bea0b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
@@ -66,7 +66,7 @@ namespace ILCompiler.DependencyAnalysis
}
}
- dependencyList.Add(factory.VTable(_type), "VTable");
+ dependencyList.Add(factory.VTable(closestDefType), "VTable");
if (closestDefType.HasInstantiation)
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
index 979868dd2..e88e44806 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -231,10 +231,10 @@ namespace ILCompiler.DependencyAnalysis
private void AddVirtualMethodUseDependencies(DependencyList dependencyList, NodeFactory factory)
{
- if (_type.RuntimeInterfaces.Length > 0 && !factory.VTable(_type).HasFixedSlots)
- {
- DefType closestDefType = _type.GetClosestDefType();
+ DefType closestDefType = _type.GetClosestDefType();
+ if (_type.RuntimeInterfaces.Length > 0 && !factory.VTable(closestDefType).HasFixedSlots)
+ {
foreach (var implementedInterface in _type.RuntimeInterfaces)
{
// If the type implements ICastable, the methods are implicitly necessary
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
index a920c6732..67c91ccab 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
@@ -16,7 +16,7 @@ namespace ILCompiler.DependencyAnalysis
public sealed class ILScanNodeFactory : NodeFactory
{
public ILScanNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler)
- : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy())
+ : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy(), new LazyVTableSliceProvider())
{
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
index 1f1b76c3c..c264ad2de 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -23,14 +23,16 @@ namespace ILCompiler.DependencyAnalysis
private TargetDetails _target;
private CompilerTypeSystemContext _context;
private CompilationModuleGroup _compilationModuleGroup;
+ private VTableSliceProvider _vtableSliceProvider;
private bool _markingComplete;
public NodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup,
- MetadataManager metadataManager, NameMangler nameMangler, LazyGenericsPolicy lazyGenericsPolicy)
+ MetadataManager metadataManager, NameMangler nameMangler, LazyGenericsPolicy lazyGenericsPolicy, VTableSliceProvider vtableSliceProvider)
{
_target = context.Target;
_context = context;
_compilationModuleGroup = compilationModuleGroup;
+ _vtableSliceProvider = vtableSliceProvider;
NameMangler = nameMangler;
InteropStubManager = new InteropStubManager(compilationModuleGroup, context, new InteropStateManager(compilationModuleGroup.GeneratedAssembly));
CreateNodeCaches();
@@ -407,7 +409,7 @@ namespace ILCompiler.DependencyAnalysis
if (CompilationModuleGroup.ShouldProduceFullVTable(type))
return new EagerlyBuiltVTableSliceNode(type);
else
- return new LazilyBuiltVTableSliceNode(type);
+ return _vtableSliceProvider.GetSlice(type);
});
_methodGenericDictionaries = new NodeCache<MethodDesc, ISymbolNode>(method =>
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
index 6e22b73da..243f509a0 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
@@ -12,8 +12,9 @@ namespace ILCompiler.DependencyAnalysis
{
public sealed class RyuJitNodeFactory : NodeFactory
{
- public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler)
- : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy())
+ public RyuJitNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager,
+ NameMangler nameMangler, VTableSliceProvider vtableSliceProvider)
+ : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy(), vtableSliceProvider)
{
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
index 5b099551c..2d1e3861f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
@@ -71,7 +71,7 @@ namespace ILCompiler
}
public UtcNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, IEnumerable<ModuleDesc> inputModules, string metadataFile, string outputFile, UTCNameMangler nameMangler, bool buildMRT)
- : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), nameMangler, new AttributeDrivenLazyGenericsPolicy())
+ : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), nameMangler, new AttributeDrivenLazyGenericsPolicy(), null)
{
CreateHostedNodeCaches();
CompilationUnitPrefix = nameMangler.CompilationUnitPrefix;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VTableSliceNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VTableSliceNode.cs
index f01fbf406..59777bae9 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VTableSliceNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/VTableSliceNode.cs
@@ -21,6 +21,7 @@ namespace ILCompiler.DependencyAnalysis
public VTableSliceNode(TypeDesc type)
{
+ Debug.Assert(!type.IsArray, "Wanted to call GetClosestDefType?");
_type = type;
}
@@ -29,6 +30,8 @@ namespace ILCompiler.DependencyAnalysis
get;
}
+ public TypeDesc Type => _type;
+
/// <summary>
/// Gets a value indicating whether the slots are assigned at the beginning of the compilation.
/// </summary>
@@ -41,6 +44,16 @@ namespace ILCompiler.DependencyAnalysis
public override bool StaticDependenciesAreComputed => true;
+ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
+ {
+ if (_type.HasBaseType)
+ {
+ return new[] { new DependencyListEntry(factory.VTable(_type.BaseType), "Base type VTable") };
+ }
+
+ return null;
+ }
+
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
@@ -48,9 +61,9 @@ namespace ILCompiler.DependencyAnalysis
public override bool HasDynamicDependencies => false;
public override bool HasConditionalStaticDependencies => false;
- protected IEnumerable<MethodDesc> GetAllVirtualMethods()
+ protected static IEnumerable<MethodDesc> GetAllVirtualMethods(TypeDesc type)
{
- foreach (MethodDesc method in _type.GetAllMethods())
+ foreach (MethodDesc method in type.GetAllMethods())
{
if (method.IsVirtual)
yield return method;
@@ -59,23 +72,55 @@ namespace ILCompiler.DependencyAnalysis
}
/// <summary>
+ /// Represents a VTable slice with fixed slots whose assignment was determined at the time the slice was allocated.
+ /// </summary>
+ internal class PrecomputedVTableSliceNode : VTableSliceNode
+ {
+ private readonly IReadOnlyList<MethodDesc> _slots;
+
+ public PrecomputedVTableSliceNode(TypeDesc type, IReadOnlyList<MethodDesc> slots)
+ : base(type)
+ {
+ _slots = slots;
+ }
+
+ public override IReadOnlyList<MethodDesc> Slots
+ {
+ get
+ {
+ return _slots;
+ }
+ }
+
+ public override bool HasFixedSlots
+ {
+ get
+ {
+ return true;
+ }
+ }
+ }
+
+ /// <summary>
/// Represents a VTable slice for a complete type - a type with all virtual method slots generated,
/// irrespective of whether they are used.
/// </summary>
- internal sealed class EagerlyBuiltVTableSliceNode : VTableSliceNode
+ internal sealed class EagerlyBuiltVTableSliceNode : PrecomputedVTableSliceNode
{
- private MethodDesc[] _slots;
-
public EagerlyBuiltVTableSliceNode(TypeDesc type)
- : base(type)
+ : base(type, ComputeSlots(type))
+ {
+ }
+
+ private static IReadOnlyList<MethodDesc> ComputeSlots(TypeDesc type)
{
var slots = new ArrayBuilder<MethodDesc>();
bool isObjectType = type.IsObject;
- DefType defType = _type.GetClosestDefType();
+ DefType defType = type.GetClosestDefType();
- IEnumerable<MethodDesc> allSlots = _type.IsInterface ?
- GetAllVirtualMethods() : defType.EnumAllVirtualSlots();
+ IEnumerable<MethodDesc> allSlots = type.IsInterface ?
+ GetAllVirtualMethods(type) : defType.EnumAllVirtualSlots();
foreach (var method in allSlots)
{
@@ -94,36 +139,7 @@ namespace ILCompiler.DependencyAnalysis
slots.Add(method);
}
- _slots = slots.ToArray();
- }
-
- public override IReadOnlyList<MethodDesc> Slots
- {
- get
- {
- return _slots;
- }
- }
-
- public override bool HasFixedSlots
- {
- get
- {
- return true;
- }
- }
-
- public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
- {
- if (_type.HasBaseType)
- {
- return new DependencyListEntry[]
- {
- new DependencyListEntry(factory.VTable(_type.BaseType), "Base type VTable")
- };
- }
-
- return null;
+ return slots.ToArray();
}
}
@@ -187,16 +203,6 @@ namespace ILCompiler.DependencyAnalysis
_usedMethods.Add(virtualMethod);
}
- public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
- {
- if (_type.HasBaseType)
- {
- return new[] { new DependencyListEntry(factory.VTable(_type.BaseType), "Base type VTable") };
- }
-
- return null;
- }
-
public override bool HasConditionalStaticDependencies
{
get
@@ -212,7 +218,7 @@ namespace ILCompiler.DependencyAnalysis
DefType defType = _type.GetClosestDefType();
IEnumerable<MethodDesc> allSlots = _type.IsInterface ?
- GetAllVirtualMethods() : defType.EnumAllVirtualSlots();
+ GetAllVirtualMethods(_type) : defType.EnumAllVirtualSlots();
foreach (var method in allSlots)
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs b/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs
index d93aba60c..67c0a8532 100644
--- a/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs
@@ -74,8 +74,9 @@ namespace ILCompiler
}
}
- public ILScanResults Scan()
+ ILScanResults IILScanner.Scan()
{
+ _nodeFactory.NameMangler.CompilationUnitPrefix = "";
return new ILScanResults(_dependencyGraph.MarkedNodeList);
}
}
@@ -94,17 +95,31 @@ namespace ILCompiler
_markedNodes = markedNodes;
}
- public IEnumerable<MethodDesc> CompiledMethods
+ public VTableSliceProvider GetVTableLayoutInfo()
{
- get
+ return new ScannedVTableProvider(_markedNodes);
+ }
+
+ private class ScannedVTableProvider : VTableSliceProvider
+ {
+ private Dictionary<TypeDesc, IReadOnlyList<MethodDesc>> _vtableSlices = new Dictionary<TypeDesc, IReadOnlyList<MethodDesc>>();
+
+ public ScannedVTableProvider(ImmutableArray<DependencyNodeCore<NodeFactory>> markedNodes)
{
- foreach (var node in _markedNodes)
+ foreach (var node in markedNodes)
{
- var methodNode = node as ScannedMethodNode;
- if (methodNode != null)
- yield return methodNode.Method;
+ var vtableSliceNode = node as VTableSliceNode;
+ if (vtableSliceNode != null)
+ {
+ _vtableSlices.Add(vtableSliceNode.Type, vtableSliceNode.Slots);
+ }
}
}
+
+ internal override VTableSliceNode GetSlice(TypeDesc type)
+ {
+ return new PrecomputedVTableSliceNode(type, _vtableSlices[type]);
+ }
}
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
index 3de4197dc..27240e366 100644
--- a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
@@ -85,7 +85,7 @@ namespace ILCompiler
jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD);
}
- var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _nameMangler);
+ var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _nameMangler, _vtableSliceProvider);
var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
diff --git a/src/ILCompiler.Compiler/src/Compiler/VTableSliceProvider.cs b/src/ILCompiler.Compiler/src/Compiler/VTableSliceProvider.cs
new file mode 100644
index 000000000..18455f2b4
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/VTableSliceProvider.cs
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.TypeSystem;
+using ILCompiler.DependencyAnalysis;
+
+namespace ILCompiler
+{
+ /// <summary>
+ /// Provides VTable information for a specific type.
+ /// </summary>
+ public abstract class VTableSliceProvider
+ {
+ internal abstract VTableSliceNode GetSlice(TypeDesc type);
+ }
+
+ /// <summary>
+ /// Provides VTable information that collects data during the compilation to build a VTable for a type.
+ /// </summary>
+ public sealed class LazyVTableSliceProvider : VTableSliceProvider
+ {
+ internal override VTableSliceNode GetSlice(TypeDesc type)
+ {
+ return new LazilyBuiltVTableSliceNode(type);
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index 475866398..8c38efba6 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -304,6 +304,7 @@
<Compile Include="Compiler\SimdHelper.cs" />
<Compile Include="Compiler\VectorOfTFieldLayoutAlgorithm.cs" />
<Compile Include="Compiler\VirtualMethodCallHelper.cs" />
+ <Compile Include="Compiler\VTableSliceProvider.cs" />
<Compile Include="Compiler\WindowsNodeMangler.cs" />
<Compile Include="IL\ILImporter.Scanner.cs" />
<Compile Include="IL\Stubs\PInvokeILProvider.cs" />
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs b/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
index 7ea68e212..3f56e757c 100644
--- a/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
@@ -29,7 +29,7 @@ namespace ILCompiler
public override ICompilation ToCompilation()
{
- CppCodegenNodeFactory factory = new CppCodegenNodeFactory(_context, _compilationGroup, _metadataManager, _nameMangler);
+ CppCodegenNodeFactory factory = new CppCodegenNodeFactory(_context, _compilationGroup, _metadataManager, _nameMangler, _vtableSliceProvider);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
return new CppCodegenCompilation(graph, factory, _compilationRoots, _logger, _config);
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
index 3eaf2ae2a..2a0e66acb 100644
--- a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
@@ -10,8 +10,9 @@ namespace ILCompiler.DependencyAnalysis
{
public sealed class CppCodegenNodeFactory : NodeFactory
{
- public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager, NameMangler nameMangler)
- : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy())
+ public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, MetadataManager metadataManager,
+ NameMangler nameMangler, VTableSliceProvider vtableSliceProvider)
+ : base(context, compilationModuleGroup, metadataManager, nameMangler, new LazyGenericsDisabledPolicy(), vtableSliceProvider)
{
}
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
index 53e9e892d..5e5069a63 100644
--- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
+++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
@@ -1109,7 +1109,7 @@ namespace ILCompiler.CppCodeGen
{
OutputTypeFields(typeDefinitions, nodeType);
- IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(nodeType).Slots;
+ IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(nodeType.GetClosestDefType()).Slots;
int baseSlots = 0;
var baseType = nodeType.BaseType;