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>2018-03-06 11:14:16 +0300
committerGitHub <noreply@github.com>2018-03-06 11:14:16 +0300
commitbce98342633901dc6202f23597598526380af010 (patch)
treed7a97341b9861d7353daac8dcc8487ca344d691a /src/ILCompiler.CppCodeGen
parent4b9c387857d9dbc9f1fe0bdb046b57c3a4499be6 (diff)
Progress towards sealed vtable support in CppCodegen (#5495)
I wanted to get rid of the CppCodegen special casing around sealed vtables that was added last week; this became kind of tricky and I ran out of time I allocated myself for it. It seems like interface dispatch is kind of broken in general for CppCodeGen. This has a couple changes towards the goal: * Add TargetArchitecture.Cpp64 for CppCodegen so that we can distinguish it from x64 * This forced me to fix the misuse of x64 assembly unboxing helpers because there's no CPU emitter for Cpp64. * Remove duplication of vtable slot calculation. The logic is different when sealed virtuals are in play. We should just use the common helper. * Devirtualize calls to final methods. These could be in the sealed vtable which makes the dispatch tricky; just don't use the vtable.
Diffstat (limited to 'src/ILCompiler.CppCodeGen')
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs3
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppUnboxingStubNode.cs68
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs34
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs2
-rw-r--r--src/ILCompiler.CppCodeGen/src/ILCompiler.CppCodeGen.csproj1
5 files changed, 84 insertions, 24 deletions
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
index baf0339aa..d282e1f27 100644
--- a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppCodegenNodeFactory.cs
@@ -40,8 +40,7 @@ namespace ILCompiler.DependencyAnalysis
protected override IMethodNode CreateUnboxingStubNode(MethodDesc method)
{
- // TODO: this is wrong: this returns an assembly stub node
- return new UnboxingStubNode(method, Target);
+ return new CppUnboxingStubNode(method);
}
protected override ISymbolNode CreateReadyToRunHelperNode(ReadyToRunHelperKey helperCall)
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppUnboxingStubNode.cs b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppUnboxingStubNode.cs
new file mode 100644
index 000000000..916c94d9e
--- /dev/null
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppUnboxingStubNode.cs
@@ -0,0 +1,68 @@
+// 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 System.Collections.Generic;
+using System.Diagnostics;
+
+using ILCompiler.DependencyAnalysisFramework;
+
+using Internal.Text;
+using Internal.TypeSystem;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ internal class CppUnboxingStubNode : DependencyNodeCore<NodeFactory>, IMethodNode
+ {
+ public CppUnboxingStubNode(MethodDesc method)
+ {
+ Debug.Assert(method.OwningType.IsValueType && !method.Signature.IsStatic);
+ Method = method;
+ }
+
+ public MethodDesc Method { get; }
+
+ public int ClassCode => 17864523;
+
+ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ {
+ sb.Append("unbox_").Append(nameMangler.GetMangledMethodName(Method));
+ }
+
+ public int CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(this.Method, ((CppUnboxingStubNode)other).Method);
+ }
+
+ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
+ {
+ return new DependencyListEntry[] {
+ new DependencyListEntry(factory.MethodEntrypoint(Method), "Target of unboxing") };
+ }
+
+ protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ public static string GetMangledName(NameMangler nameMangler, MethodDesc method)
+ {
+ return "unbox_" + nameMangler.GetMangledMethodName(method);
+ }
+
+ public override bool StaticDependenciesAreComputed => true;
+ public override bool HasDynamicDependencies => false;
+ public override bool InterestingForDynamicDependencyAnalysis => false;
+ public override bool HasConditionalStaticDependencies => false;
+
+ public int Offset => throw new System.NotImplementedException();
+
+ public bool RepresentsIndirectionCell => throw new System.NotImplementedException();
+
+ public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory context)
+ {
+ return null;
+ }
+ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory context)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
index ef08550b7..fb2130704 100644
--- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
+++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
@@ -894,12 +894,12 @@ namespace ILCompiler.CppCodeGen
{
relocCode.Append("dispatchMapModule");
}
- else if(reloc.Target is UnboxingStubNode)
+ else if(reloc.Target is CppUnboxingStubNode)
{
- var method = reloc.Target as UnboxingStubNode;
+ var method = reloc.Target as CppUnboxingStubNode;
relocCode.Append("(void*)&");
- relocCode.Append(GetCppMethodDeclarationName(method.Method.OwningType, UnboxingStubNode.GetMangledName(factory.NameMangler, method.Method), false));
+ relocCode.Append(GetCppMethodDeclarationName(method.Method.OwningType, method.GetMangledName(factory.NameMangler), false));
}
else
{
@@ -1202,23 +1202,15 @@ namespace ILCompiler.CppCodeGen
if (typeNode is ConstructedEETypeNode)
{
- IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(nodeType.GetClosestDefType()).Slots;
+ DefType closestDefType = nodeType.GetClosestDefType();
- int baseSlots = 0;
- var baseType = nodeType.BaseType;
- while (baseType != null)
- {
- IReadOnlyList<MethodDesc> baseVirtualSlots = _compilation.NodeFactory.VTable(baseType).Slots;
- if (baseVirtualSlots != null)
- baseSlots += baseVirtualSlots.Count;
- baseType = baseType.BaseType;
- }
+ IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(closestDefType).Slots;
- for (int slot = 0; slot < virtualSlots.Count; slot++)
+ foreach (MethodDesc slot in virtualSlots)
{
- MethodDesc virtualMethod = virtualSlots[slot];
typeDefinitions.AppendLine();
- typeDefinitions.Append(GetCodeForVirtualMethod(virtualMethod, baseSlots + slot));
+ int slotNumber = VirtualMethodSlotHelper.GetVirtualMethodSlot(_compilation.NodeFactory, slot, closestDefType);
+ typeDefinitions.Append(GetCodeForVirtualMethod(slot, slotNumber));
}
if (nodeType.IsDelegate)
@@ -1242,7 +1234,7 @@ namespace ILCompiler.CppCodeGen
typeDefinitions.AppendLine();
AppendCppMethodDeclaration(typeDefinitions, m, false);
typeDefinitions.AppendLine();
- AppendCppMethodDeclaration(typeDefinitions, m, false, null, null, UnboxingStubNode.GetMangledName(factory.NameMangler, m));
+ AppendCppMethodDeclaration(typeDefinitions, m, false, null, null, CppUnboxingStubNode.GetMangledName(factory.NameMangler, m));
}
}
@@ -1342,13 +1334,13 @@ namespace ILCompiler.CppCodeGen
/// </summary>
/// <param name="unboxingStubNode">The unboxing stub node to be output</param>
/// <param name="methodImplementations">The buffer in which to write out the C++ code</param>
- private void OutputUnboxingStubNode(UnboxingStubNode unboxingStubNode)
+ private void OutputUnboxingStubNode(CppUnboxingStubNode unboxingStubNode)
{
Out.WriteLine();
CppGenerationBuffer sb = new CppGenerationBuffer();
sb.AppendLine();
- AppendCppMethodDeclaration(sb, unboxingStubNode.Method, true, null, null, UnboxingStubNode.GetMangledName(_compilation.NameMangler, unboxingStubNode.Method));
+ AppendCppMethodDeclaration(sb, unboxingStubNode.Method, true, null, null, unboxingStubNode.GetMangledName(_compilation.NameMangler));
sb.AppendLine();
sb.Append("{");
sb.Indent();
@@ -1405,8 +1397,8 @@ namespace ILCompiler.CppCodeGen
{
if (node is CppMethodCodeNode)
OutputMethodNode(node as CppMethodCodeNode);
- else if (node is UnboxingStubNode)
- OutputUnboxingStubNode(node as UnboxingStubNode);
+ else if (node is CppUnboxingStubNode)
+ OutputUnboxingStubNode(node as CppUnboxingStubNode);
}
Out.Dispose();
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
index ae062dad6..560820ad2 100644
--- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
+++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
@@ -1151,7 +1151,7 @@ namespace Internal.IL
{
// TODO: Null checks
- if (method.IsVirtual)
+ if (method.IsVirtual && !method.IsFinal && !method.OwningType.IsSealed())
{
// TODO: Full resolution of virtual methods
if (!method.IsNewSlot)
diff --git a/src/ILCompiler.CppCodeGen/src/ILCompiler.CppCodeGen.csproj b/src/ILCompiler.CppCodeGen/src/ILCompiler.CppCodeGen.csproj
index 1ef83f8bd..80a2a51f2 100644
--- a/src/ILCompiler.CppCodeGen/src/ILCompiler.CppCodeGen.csproj
+++ b/src/ILCompiler.CppCodeGen/src/ILCompiler.CppCodeGen.csproj
@@ -32,6 +32,7 @@
<Compile Include="Compiler\CppNodeMangler.cs" />
<Compile Include="Compiler\CppCodegenCompilation.cs" />
<Compile Include="Compiler\CppCodegenCompilationBuilder.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\CppUnboxingStubNode.cs" />
<Compile Include="CppCodeGen\DependencyNodeIterator.cs" />
<Compile Include="CppCodeGen\EvaluationStack.cs" />
<Compile Include="CppCodeGen\CppGenerationBuffer.cs" />