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
path: root/src
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2018-03-06 13:22:46 +0300
committerGitHub <noreply@github.com>2018-03-06 13:22:46 +0300
commit40b2afa6ba669c28aeffdd5a8d544220b2312232 (patch)
tree3388f945b3b12e05a3fc3229a9bba2fcfee9b19d /src
parent09337f8a49db26a1bff97f9fc000878771e02032 (diff)
parent98ea3d1bfe098afef650226108b5a9052888844c (diff)
Merge pull request #5505 from dotnet/nmirror
Merge nmirror to master
Diffstat (limited to 'src')
-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.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs45
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs2
5 files changed, 48 insertions, 5 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
index 807f620b9..6e3bc9f58 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
@@ -46,7 +46,7 @@ namespace ILCompiler.DependencyAnalysis
DefType closestDefType = _type.GetClosestDefType();
- if (_type.RuntimeInterfaces.Length > 0 && !_type.IsArrayTypeWithoutGenericInterfaces())
+ if (InterfaceDispatchMapNode.MightHaveInterfaceDispatchMap(_type, factory))
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Canonical interface dispatch map");
dependencyList.Add(factory.VTable(closestDefType), "VTable");
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
index 4dc900b3e..0dee4d7cb 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
@@ -80,7 +80,7 @@ namespace ILCompiler.DependencyAnalysis
DefType closestDefType = _type.GetClosestDefType();
- if (_type.RuntimeInterfaces.Length > 0 && !_type.IsArrayTypeWithoutGenericInterfaces())
+ if (InterfaceDispatchMapNode.MightHaveInterfaceDispatchMap(_type, factory))
{
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
index dfe887c46..8df68bd1d 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -867,7 +867,7 @@ namespace ILCompiler.DependencyAnalysis
/// </summary>
protected internal virtual void ComputeOptionalEETypeFields(NodeFactory factory, bool relocsOnly)
{
- if (!relocsOnly && _type.RuntimeInterfaces.Length > 0 && !_type.IsArrayTypeWithoutGenericInterfaces() && factory.InterfaceDispatchMap(_type).Marked)
+ if (!relocsOnly && EmitVirtualSlotsAndInterfaces && InterfaceDispatchMapNode.MightHaveInterfaceDispatchMap(_type, factory))
{
_optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.DispatchMap, checked((uint)factory.InterfaceDispatchMapIndirection(Type).IndexFromBeginningOfArray));
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
index 71966e20f..b631efaff 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
@@ -15,12 +15,13 @@ namespace ILCompiler.DependencyAnalysis
{
TypeDesc _type;
- public InterfaceDispatchMapNode(TypeDesc type)
+ public InterfaceDispatchMapNode(NodeFactory factory, TypeDesc type)
{
// Multidimensional arrays should not get a sealed vtable or a dispatch map. Runtime should use the
// sealed vtable and dispatch map of the System.Array basetype instead.
// Pointer arrays also follow the same path
Debug.Assert(!type.IsArrayTypeWithoutGenericInterfaces());
+ Debug.Assert(MightHaveInterfaceDispatchMap(type, factory));
_type = type;
}
@@ -62,6 +63,48 @@ namespace ILCompiler.DependencyAnalysis
return result;
}
+ /// <summary>
+ /// Gets a value indicating whether '<paramref name="type"/>' might have a non-empty dispatch map.
+ /// Note that this is only an approximation because we might not be able to take into account
+ /// whether the interface methods are actually used.
+ /// </summary>
+ public static bool MightHaveInterfaceDispatchMap(TypeDesc type, NodeFactory factory)
+ {
+ if (type.IsArrayTypeWithoutGenericInterfaces())
+ return false;
+
+ if (!type.IsArray && !type.IsDefType)
+ return false;
+
+ DefType defType = type.GetClosestDefType();
+
+ foreach (DefType interfaceType in defType.RuntimeInterfaces)
+ {
+ IEnumerable<MethodDesc> slots;
+
+ // If the vtable has fixed slots, we can query it directly.
+ // If it's a lazily built vtable, we might not be able to query slots
+ // just yet, so approximate by looking at all methods.
+ VTableSliceNode vtableSlice = factory.VTable(interfaceType);
+ if (vtableSlice.HasFixedSlots)
+ slots = vtableSlice.Slots;
+ else
+ slots = interfaceType.GetAllMethods();
+
+ foreach (MethodDesc declMethod in slots)
+ {
+ if (declMethod.Signature.IsStatic)
+ continue;
+
+ var implMethod = defType.ResolveInterfaceMethodToVirtualMethodOnType(declMethod);
+ if (implMethod != null)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory)
{
var entryCountReservation = builder.ReserveInt();
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
index 597b2d55a..35795ed02 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -379,7 +379,7 @@ namespace ILCompiler.DependencyAnalysis
_interfaceDispatchMaps = new NodeCache<TypeDesc, InterfaceDispatchMapNode>((TypeDesc type) =>
{
- return new InterfaceDispatchMapNode(type);
+ return new InterfaceDispatchMapNode(this, type);
});
_sealedVtableNodes = new NodeCache<TypeDesc, SealedVTableNode>((TypeDesc type) =>