diff options
author | Fadi Hanna <fadim@microsoft.com> | 2018-05-31 01:24:25 +0300 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2018-05-31 01:24:25 +0300 |
commit | 92893399cf56dec646f1cc2047e308865569a959 (patch) | |
tree | d2057a74dce89463e5183942d1329aad4dfd6c6c /src/ILCompiler.Compiler | |
parent | 8197c0bebc6e8aba733578f8f20075ad087c6bf1 (diff) |
Fixing the cases of missing default constructor. This fix makes the default constructor of all constructed types show up in the map. This fix is a bit on the conservative side, and avoids more complex detection logic to only include default ctor entries for types that will really need them (detection with generics might be complex to implement, and might still have holes at the end), but that's acceptable given that the size on disk impact is negligible (less than 0.3% on average).
[tfs-changeset: 1702272]
Diffstat (limited to 'src/ILCompiler.Compiler')
3 files changed, 34 insertions, 6 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index 6e3bc9f58..07efe41dd 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -62,6 +62,15 @@ namespace ILCompiler.DependencyAnalysis AddDependenciesForUniversalGVMSupport(factory, _type, ref dependencyList); } + // Keep track of the default constructor map dependency for this type if it has a default constructor + MethodDesc defaultCtor = closestDefType.GetDefaultConstructor(); + if (defaultCtor != null) + { + dependencyList.Add(new DependencyListEntry( + factory.MethodEntrypoint(defaultCtor, closestDefType.IsValueType), + "DefaultConstructorNode")); + } + return dependencyList; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 46a30653c..6f9d6016a 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -151,6 +151,15 @@ namespace ILCompiler.DependencyAnalysis factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type); + // Keep track of the default constructor map dependency for this type if it has a default constructor + MethodDesc defaultCtor = closestDefType.GetDefaultConstructor(); + if (defaultCtor != null) + { + dependencyList.Add(new DependencyListEntry( + factory.MethodEntrypoint(defaultCtor.GetCanonMethodTarget(CanonicalFormKind.Specific), closestDefType.IsValueType), + "DefaultConstructorNode")); + } + return dependencyList; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs index 9f6735b88..9570f7208 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Collections.Generic; +using System.Linq; using Internal.Text; using Internal.TypeSystem; @@ -15,7 +16,7 @@ using ILCompiler.DependencyAnalysisFramework; namespace ILCompiler.DependencyAnalysis { /// <summary> - /// Dependency analysis node used to keep track of types needing an entry in the default + /// Dependency analysis node used to keep track of types used by lazy generics, needing an entry in the default /// constructor map hashtable /// </summary> internal sealed class DefaultConstructorFromLazyNode : DependencyNodeCore<NodeFactory> @@ -96,19 +97,22 @@ namespace ILCompiler.DependencyAnalysis Section defaultConstructorHashtableSection = writer.NewSection(); defaultConstructorHashtableSection.Place(defaultConstructorHashtable); - foreach (var ctorNeeded in factory.MetadataManager.GetDefaultConstructorsNeeded()) + foreach (var type in factory.MetadataManager.GetTypesWithConstructedEETypes().Union(GetTypesNeedingDefaultConstructors(factory))) { - MethodDesc defaultCtor = ctorNeeded.TypeNeedingDefaultCtor.GetDefaultConstructor(); - Debug.Assert(defaultCtor != null); + MethodDesc defaultCtor = type.GetDefaultConstructor(); + if (defaultCtor == null) + continue; + + defaultCtor = defaultCtor.GetCanonMethodTarget(CanonicalFormKind.Specific); - ISymbolNode typeNode = factory.NecessaryTypeSymbol(ctorNeeded.TypeNeedingDefaultCtor); + ISymbolNode typeNode = factory.NecessaryTypeSymbol(type); ISymbolNode defaultCtorNode = factory.MethodEntrypoint(defaultCtor, false); Vertex vertex = writer.GetTuple( writer.GetUnsignedConstant(_externalReferences.GetIndex(typeNode)), writer.GetUnsignedConstant(_externalReferences.GetIndex(defaultCtorNode))); - int hashCode = ctorNeeded.TypeNeedingDefaultCtor.GetHashCode(); + int hashCode = type.GetHashCode(); defaultConstructorHashtable.Append((uint)hashCode, defaultConstructorHashtableSection.Place(vertex)); } @@ -118,5 +122,11 @@ namespace ILCompiler.DependencyAnalysis return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol }); } + + private IEnumerable<TypeDesc> GetTypesNeedingDefaultConstructors(NodeFactory factory) + { + foreach (var ctorNeeded in factory.MetadataManager.GetDefaultConstructorsNeeded()) + yield return ctorNeeded.TypeNeedingDefaultCtor; + } } } |