diff options
author | David Wrighton <davidwr@microsoft.com> | 2017-10-10 23:14:39 +0300 |
---|---|---|
committer | David Wrighton <davidwr@microsoft.com> | 2017-10-10 23:14:39 +0300 |
commit | 26a5f6dce3d580aedd02be3c71e3ee4a1d92698a (patch) | |
tree | eb135e59c185332e8458218d7f5161224fc98f06 /src/ILCompiler.Compiler | |
parent | 791adf0e1662a79fdfb36c89b92f6b7c90abfbb5 (diff) |
Various dependency analysis fixes
- Add sorting support to SignatureVariable
- Needed to allow all kinds of generic lookups to be sorted
- Fix typo in DictionaryLayoutNode
- only emit the fixed entries when asked to do so
- Adjust dependency handling in NativeLayoutDictionarySignatureNode
- The WriteVertex method always takes a dependency on DictionaryLayoutNode, so explicitly make it a static dependency
[tfs-changeset: 1677801]
Diffstat (limited to 'src/ILCompiler.Compiler')
4 files changed, 35 insertions, 6 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs index e700ab4d6..3838ae189 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs @@ -69,6 +69,15 @@ namespace ILCompiler.DependencyAnalysis } } + /// <summary> + /// Ensure that a generic lookup result can be resolved. Used to add new lookups to a dictionary which HasUnfixedSlots + /// Must not be used after any calls to GetSlotForEntry + /// </summary> + public abstract void EnsureEntry(GenericLookupResult entry); + + /// <summary> + /// Get a slot index for a given entry. Slot indices are never expected to change once given out. + /// </summary> public abstract int GetSlotForEntry(GenericLookupResult entry); /// <summary> @@ -120,7 +129,7 @@ namespace ILCompiler.DependencyAnalysis IEnumerable<GenericLookupResult> entriesToEmit = fixedLayoutOnly ? FixedEntries : Entries; - foreach (GenericLookupResult lookupResult in Entries) + foreach (GenericLookupResult lookupResult in entriesToEmit) { #if DEBUG int offsetBefore = builder.CountBytes; @@ -210,6 +219,17 @@ namespace ILCompiler.DependencyAnalysis _layout = l.ToArray(); } + public override void EnsureEntry(GenericLookupResult entry) + { + int index = Array.IndexOf(_layout, entry); + + if (index == -1) + { + // Using EnsureEntry to add a slot to a PrecomputedDictionaryLayoutNode is not supported + throw new NotSupportedException(); + } + } + public override int GetSlotForEntry(GenericLookupResult entry) { int index = Array.IndexOf(_layout, entry); @@ -247,7 +267,7 @@ namespace ILCompiler.DependencyAnalysis { } - public void EnsureEntry(GenericLookupResult entry) + public override void EnsureEntry(GenericLookupResult entry) { Debug.Assert(_layout == null, "Trying to add entry but layout already computed"); _entries.AddOrGetExisting(entry); diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index ce2d934a6..a74c60242 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -737,11 +737,18 @@ namespace ILCompiler.DependencyAnalysis { if ((ContextKind & GenericContextKind.HasDeclaringType) != 0) { - return new DependencyListEntry[] { new DependencyListEntry(context.NativeLayout.TypeSignatureVertex((TypeDesc)_owningMethodOrType), "DeclaringType signature") }; + return new DependencyListEntry[] + { + new DependencyListEntry(context.NativeLayout.TypeSignatureVertex((TypeDesc)_owningMethodOrType), "DeclaringType signature"), + new DependencyListEntry(context.GenericDictionaryLayout(_owningMethodOrType), "Dictionary Layout") + }; } else { - return Array.Empty<DependencyListEntry>(); + return new DependencyListEntry[] + { + new DependencyListEntry(context.GenericDictionaryLayout(_owningMethodOrType), "Dictionary Layout") + }; } } @@ -752,6 +759,7 @@ namespace ILCompiler.DependencyAnalysis VertexSequence sequence = new VertexSequence(); DictionaryLayoutNode associatedLayout = factory.GenericDictionaryLayout(_owningMethodOrType); + Debug.Assert(associatedLayout.Marked); ICollection<NativeLayoutVertexNode> templateLayout = associatedLayout.GetTemplateEntries(factory); foreach (NativeLayoutVertexNode dictionaryEntry in templateLayout) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs index b60b54691..99e717c40 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs @@ -74,14 +74,14 @@ namespace ILCompiler.DependencyAnalysis { // When the helper call gets marked, ensure the generic layout for the associated dictionaries // includes the signature. - ((LazilyBuiltDictionaryLayoutNode)layout).EnsureEntry(_lookupSignature); + layout.EnsureEntry(_lookupSignature); if ((_id == ReadyToRunHelperId.GetGCStaticBase || _id == ReadyToRunHelperId.GetThreadStaticBase) && factory.TypeSystemContext.HasLazyStaticConstructor((TypeDesc)_target)) { // If the type has a lazy static constructor, we also need the non-GC static base // because that's where the class constructor context is. - ((LazilyBuiltDictionaryLayoutNode)layout).EnsureEntry(factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target)); + layout.EnsureEntry(factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)_target)); } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs index 408ccea42..c5038e064 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs @@ -39,6 +39,7 @@ namespace ILCompiler.DependencyAnalysis } #if CORERT + public override void EnsureEntry(GenericLookupResult lookupResult) => throw new NotImplementedException(); public override int GetSlotForEntry(GenericLookupResult entry) => throw new NotImplementedException(); public override IEnumerable<GenericLookupResult> Entries => throw new NotImplementedException(); public override ICollection<NativeLayoutVertexNode> GetTemplateEntries(NodeFactory factory) => throw new NotImplementedException(); |