diff options
author | David Wrighton <davidwr@microsoft.com> | 2017-10-11 23:41:56 +0300 |
---|---|---|
committer | David Wrighton <davidwr@microsoft.com> | 2017-10-11 23:41:56 +0300 |
commit | f686aea070a295e7b66bc978420b83e280521467 (patch) | |
tree | 35c97bc8ff35db84140ec9e11917eecabc7bd353 /src/ILCompiler.Compiler | |
parent | 51a3447a25bbd3e0945e55cfb6f05de4e2e41dc3 (diff) |
Allow Span<UniversalCanon> to exist as a template
- Remove requirement that all universal canon instantiations have vtables. (In particular, remove vtable handling from the template in the presence of ByRefLike structures
- Use necessary type for template of canonical byreflike types
[tfs-changeset: 1677901]
Diffstat (limited to 'src/ILCompiler.Compiler')
4 files changed, 61 insertions, 33 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index b1474e316..cd5b438ad 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -27,6 +27,7 @@ namespace ILCompiler.DependencyAnalysis Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific)); Debug.Assert(!type.IsMdArray); + Debug.Assert(!type.IsByRefLike); } public override bool StaticDependenciesAreComputed => true; diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 1edae9492..350214ec6 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -178,7 +178,7 @@ namespace ILCompiler.DependencyAnalysis return false; // Byref-like types have interior pointers and cannot be heap allocated. - if (type.IsValueType && ((DefType)type).IsByRefLike) + if (type.IsByRefLike) return false; // The global "<Module>" type can never be allocated. diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs index 61ee1e52c..8ccbd0c08 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; using Internal.Text; +using ILCompiler.DependencyAnalysisFramework; using Internal.TypeSystem; using Internal.NativeFormat; @@ -57,11 +58,17 @@ namespace ILCompiler.DependencyAnalysis if (!IsEligibleToHaveATemplate(type)) continue; - if (factory.Target.Abi == TargetAbi.ProjectN) + if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { - // If the type does not have fully constructed type, don't emit it. + // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. - if (!factory.ConstructedTypeSymbol(type).Marked) + IDependencyNode node; + if (ConstructedEETypeNode.CreationAllowed(type)) + node = factory.ConstructedTypeSymbol(type); + else + node = factory.NecessaryTypeSymbol(type); + + if (!node.Marked) continue; } @@ -100,11 +107,17 @@ namespace ILCompiler.DependencyAnalysis if (!IsEligibleToHaveATemplate(templateType)) return; - if (factory.Target.Abi == TargetAbi.ProjectN) + if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. - if (!factory.ConstructedTypeSymbol(templateType).Marked) + IDependencyNode node; + if (ConstructedEETypeNode.CreationAllowed(templateType)) + node = factory.ConstructedTypeSymbol(templateType); + else + node = factory.NecessaryTypeSymbol(templateType); + + if (!node.Marked) return; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index a74c60242..48bbeb575 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -915,7 +915,13 @@ namespace ILCompiler.DependencyAnalysis public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory context) { - yield return new DependencyListEntry(context.ConstructedTypeSymbol(_type.ConvertToCanonForm(CanonicalFormKind.Specific)), "Template EEType"); + ISymbolNode typeNode; + if (!ConstructedEETypeNode.CreationAllowed(_type)) + typeNode = context.NecessaryTypeSymbol(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); + else + typeNode = context.ConstructedTypeSymbol(_type.ConvertToCanonForm(CanonicalFormKind.Specific)); + + yield return new DependencyListEntry(typeNode, "Template EEType"); yield return new DependencyListEntry(context.GenericDictionaryLayout(_type.ConvertToCanonForm(CanonicalFormKind.Specific).GetClosestDefType()), "Dictionary layout"); @@ -1344,36 +1350,44 @@ namespace ILCompiler.DependencyAnalysis IEnumerable<MethodDesc> vtableEntriesToProcess; - switch (whichEntries) + if (ConstructedEETypeNode.CreationAllowed(declType)) { - case VTableEntriesToProcess.AllInVTable: - vtableEntriesToProcess = factory.VTable(declType).Slots; - break; - - case VTableEntriesToProcess.AllOnTypesThatShouldProduceFullVTables: - if (factory.VTable(declType).HasFixedSlots) - { + switch (whichEntries) + { + case VTableEntriesToProcess.AllInVTable: vtableEntriesToProcess = factory.VTable(declType).Slots; - } - else - { - vtableEntriesToProcess = Array.Empty<MethodDesc>(); - } - break; + break; - case VTableEntriesToProcess.AllOnTypesThatProducePartialVTables: - if (factory.VTable(declType).HasFixedSlots) - { - vtableEntriesToProcess = Array.Empty<MethodDesc>(); - } - else - { - vtableEntriesToProcess = EnumVirtualSlotsDeclaredOnType(declType); - } - break; + case VTableEntriesToProcess.AllOnTypesThatShouldProduceFullVTables: + if (factory.VTable(declType).HasFixedSlots) + { + vtableEntriesToProcess = factory.VTable(declType).Slots; + } + else + { + vtableEntriesToProcess = Array.Empty<MethodDesc>(); + } + break; - default: - throw new Exception(); + case VTableEntriesToProcess.AllOnTypesThatProducePartialVTables: + if (factory.VTable(declType).HasFixedSlots) + { + vtableEntriesToProcess = Array.Empty<MethodDesc>(); + } + else + { + vtableEntriesToProcess = EnumVirtualSlotsDeclaredOnType(declType); + } + break; + + default: + throw new Exception(); + } + } + else + { + // If allocating an object of the EEType isn't permitted, don't process any vtable entries. + vtableEntriesToProcess = Array.Empty<MethodDesc>(); } // Dictionary slot |