diff options
author | David Wrighton <davidwr@microsoft.com> | 2017-10-07 03:28:13 +0300 |
---|---|---|
committer | David Wrighton <davidwr@microsoft.com> | 2017-10-07 03:28:13 +0300 |
commit | 814a48da9b896bb0021160aa1d62daf02d99cfeb (patch) | |
tree | fd6aebd7fa558228385f30ee910fd5a7f08e34df /src/ILCompiler.Compiler | |
parent | 94cb735024ea103e54ad3385d2002b6b8759723d (diff) |
Generic Dictionary Layout refactorings
- Make it possible to define a DictionaryLayoutProvider outside of ILCompiler.Compiler dll (visibility changes to public on various types/methods)
- Add a concept of fixed layout regions of dictionaries and non-fixed regions (So that dictionary layouts that are partially fixed could be supported)
- Add IntegerLookupResult and PointerToSlotLookupResult classes to the set of GenericLookupResults. (Now, all things that may be in a generic dictionary can be represented as GenericLookupResults)
- They are handled as singletons to reduce the need to shuffle NodeFactories to inconvenient locations
[tfs-changeset: 1677562]
Diffstat (limited to 'src/ILCompiler.Compiler')
10 files changed, 221 insertions, 39 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs index 892c2f05a..19fde9b0b 100644 --- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs +++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs @@ -270,18 +270,21 @@ namespace ILCompiler int pointerSize = _nodeFactory.Target.PointerSize; GenericLookupResult lookup = ReadyToRunGenericHelperNode.GetLookupSignature(_nodeFactory, lookupKind, targetOfLookup); - int dictionarySlot = dictionaryLayout.GetSlotForEntry(lookup); - int dictionaryOffset = dictionarySlot * pointerSize; - - if (contextSource == GenericContextSource.MethodParameter) - { - return GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset); - } - else + int dictionarySlot = dictionaryLayout.GetSlotForFixedEntry(lookup); + if (dictionarySlot != -1) { - int vtableSlot = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType); - int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize; - return GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset); + int dictionaryOffset = dictionarySlot * pointerSize; + + if (contextSource == GenericContextSource.MethodParameter) + { + return GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset); + } + else + { + int vtableSlot = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType); + int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize; + return GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset); + } } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs index 990baccfc..e700ab4d6 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DictionaryLayoutNode.cs @@ -70,12 +70,24 @@ namespace ILCompiler.DependencyAnalysis } public abstract int GetSlotForEntry(GenericLookupResult entry); + + /// <summary> + /// Get the slot for an entry which is fixed already. Otherwise return -1 + /// </summary> + /// <param name="entry"></param> + /// <returns></returns> + public virtual int GetSlotForFixedEntry(GenericLookupResult entry) + { + return GetSlotForEntry(entry); + } public abstract IEnumerable<GenericLookupResult> Entries { get; } + public virtual IEnumerable<GenericLookupResult> FixedEntries => Entries; + public TypeSystemEntity OwningMethodOrType => _owningMethodOrType; /// <summary> @@ -86,6 +98,11 @@ namespace ILCompiler.DependencyAnalysis get; } + /// <summary> + /// Gets a value indicating if this dictionary may have non fixed slots + /// </summary> + public virtual bool HasUnfixedSlots => !HasFixedSlots; + public virtual ICollection<NativeLayoutVertexNode> GetTemplateEntries(NodeFactory factory) { ArrayBuilder<NativeLayoutVertexNode> templateEntries = new ArrayBuilder<NativeLayoutVertexNode>(); @@ -97,17 +114,19 @@ namespace ILCompiler.DependencyAnalysis return templateEntries.ToArray(); } - public virtual void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary) + public virtual void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary, bool fixedLayoutOnly) { var context = new GenericLookupResultContext(dictionary.OwningEntity, dictionary.TypeInstantiation, dictionary.MethodInstantiation); + IEnumerable<GenericLookupResult> entriesToEmit = fixedLayoutOnly ? FixedEntries : Entries; + foreach (GenericLookupResult lookupResult in Entries) { #if DEBUG int offsetBefore = builder.CountBytes; #endif - lookupResult.EmitDictionaryEntry(ref builder, factory, context); + lookupResult.EmitDictionaryEntry(ref builder, factory, context, dictionary); #if DEBUG Debug.Assert(builder.CountBytes - offsetBefore == factory.Target.PointerSize); @@ -129,7 +148,7 @@ namespace ILCompiler.DependencyAnalysis if (HasFixedSlots) { - foreach (GenericLookupResult lookupResult in Entries) + foreach (GenericLookupResult lookupResult in FixedEntries) { foreach (DependencyNodeCore<NodeFactory> dependency in lookupResult.NonRelocDependenciesFromUsage(factory)) { @@ -155,7 +174,7 @@ namespace ILCompiler.DependencyAnalysis List<CombinedDependencyListEntry> conditionalDependencies = new List<CombinedDependencyListEntry>(); - foreach (var lookupSignature in Entries) + foreach (var lookupSignature in FixedEntries) { conditionalDependencies.Add(new CombinedDependencyListEntry(lookupSignature.TemplateDictionaryNode(factory), templateLayout, diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs index b4524fa2d..6c1f68d4a 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs @@ -69,16 +69,16 @@ namespace ILCompiler.DependencyAnalysis if (layout.HasFixedSlots || !relocsOnly) { // TODO: pass the layout we already have to EmitDataInternal - EmitDataInternal(ref builder, factory); + EmitDataInternal(ref builder, factory, relocsOnly); } return builder.ToObjectData(); } - protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory) + protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory, bool fixedLayoutOnly) { DictionaryLayoutNode layout = GetDictionaryLayout(factory); - layout.EmitDictionaryData(ref builder, factory, this); + layout.EmitDictionaryData(ref builder, factory, this, fixedLayoutOnly: fixedLayoutOnly); } protected sealed override string GetName(NodeFactory factory) @@ -219,7 +219,7 @@ namespace ILCompiler.DependencyAnalysis return factory.GenericDictionaryLayout(_owningMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)); } - protected override void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory) + protected override void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory, bool fixedLayoutOnly) { // Method generic dictionaries get prefixed by the hash code of the owning method // to allow quick lookups of additional details by the type loader. @@ -235,7 +235,7 @@ namespace ILCompiler.DependencyAnalysis if (factory.LazyGenericsPolicy.UsesLazyGenerics(OwningMethod)) return; - base.EmitDataInternal(ref builder, factory); + base.EmitDataInternal(ref builder, factory, fixedLayoutOnly); } public MethodGenericDictionaryNode(MethodDesc owningMethod, NodeFactory factory) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs index 3fcd00b16..7c20b2cf8 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericLookupResult.cs @@ -61,6 +61,7 @@ namespace ILCompiler.DependencyAnalysis public interface IGenericLookupResultTocWriter { void WriteData(GenericLookupResultReferenceType referenceType, LookupResultType slotType, TypeSystemEntity context); + void WriteIntegerSlot(int value); } public struct GenericLookupResultContext @@ -83,7 +84,7 @@ namespace ILCompiler.DependencyAnalysis return owningTypeDefinition.MakeInstantiatedType(TypeInstantiation); } - + Debug.Assert(_canonicalOwner is MethodDesc); MethodDesc owningMethodDefinition = ((MethodDesc)_canonicalOwner).GetTypicalMethodDefinition(); Debug.Assert(owningMethodDefinition.Instantiation.Length == MethodInstantiation.Length); @@ -144,7 +145,7 @@ namespace ILCompiler.DependencyAnalysis return ClassCode * 31 + GetHashCodeImpl(); } - public virtual void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary) + public virtual void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) { ISymbolNode target = GetTarget(factory, dictionary); if (LookupResultReferenceType(factory) == GenericLookupResultReferenceType.ConditionalIndirect) @@ -172,7 +173,7 @@ namespace ILCompiler.DependencyAnalysis return Array.Empty<DependencyNodeCore<NodeFactory>>(); } - public class Comparer + public class Comparer : IComparer<GenericLookupResult> { private TypeSystemComparer _comparer; @@ -375,7 +376,7 @@ namespace ILCompiler.DependencyAnalysis return null; } - public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary) + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) { FieldDesc instantiatedField = _field.GetNonRuntimeDeterminedFieldFromRuntimeDeterminedFieldViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); int offset = instantiatedField.Offset.AsInt; @@ -438,7 +439,7 @@ namespace ILCompiler.DependencyAnalysis return null; } - public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary) + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) { Debug.Assert(false, "VTableOffset contents should only be generated into generic dictionaries at runtime"); builder.EmitNaturalInt(0); @@ -717,7 +718,7 @@ namespace ILCompiler.DependencyAnalysis bool getUnboxingStubNode = _isUnboxingThunk && !canonMethod.IsCanonicalMethod(CanonicalFormKind.Universal); return factory.NativeLayout.MethodEntrypointDictionarySlot( - _method, + _method, _isUnboxingThunk, factory.MethodEntrypoint(canonMethod, getUnboxingStubNode)); } @@ -1174,7 +1175,7 @@ namespace ILCompiler.DependencyAnalysis return ((CastClassGenericLookupResult)obj)._type == _type; } } - + /// <summary> /// Generic lookup result that points to an isInst helper. /// </summary> @@ -1376,7 +1377,7 @@ namespace ILCompiler.DependencyAnalysis { // If there isn't a default constructor, use the fallback one. MetadataType missingCtorType = factory.TypeSystemContext.SystemModule.GetKnownType("System", "Activator"); - missingCtorType = missingCtorType.GetKnownNestedType("ClassWithMissingConstructor"); + missingCtorType = missingCtorType.GetKnownNestedType("ClassWithMissingConstructor"); defaultCtor = missingCtorType.GetParameterlessConstructor(); } else @@ -1439,7 +1440,7 @@ namespace ILCompiler.DependencyAnalysis return null; } - public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary) + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) { Debug.Assert(false, "CallingConventionConverterLookupResult contents should only be generated into generic dictionaries at runtime"); builder.EmitNaturalInt(0); @@ -1502,7 +1503,7 @@ namespace ILCompiler.DependencyAnalysis return null; } - public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary) + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) { TypeDesc instantiatedType = _type.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(dictionary.TypeInstantiation, dictionary.MethodInstantiation); int typeSize; @@ -1641,4 +1642,133 @@ namespace ILCompiler.DependencyAnalysis _directCall == other._directCall; } } + + public sealed class IntegerLookupResult : GenericLookupResult + { + int _integerValue; + + public IntegerLookupResult(int integer) + { + _integerValue = integer; + } + + public int IntegerValue => _integerValue; + + protected override int ClassCode => 385752509; + + public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultContext dictionary) + { + return null; + } + + public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append("IntegerLookupResult_").Append(_integerValue.ToString("x")); + } + + public override string ToString() + { + return "IntegerLookupResult_" + _integerValue.ToString("x"); + } + + protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer) + { + IntegerLookupResult lookupResultOther = (IntegerLookupResult)other; + if (lookupResultOther._integerValue == _integerValue) + return 0; + + return _integerValue > lookupResultOther._integerValue ? 1 : -1; + } + + protected override bool EqualsImpl(GenericLookupResult other) + { + IntegerLookupResult lookupResultOther = (IntegerLookupResult)other; + return lookupResultOther._integerValue == _integerValue; + } + + protected override int GetHashCodeImpl() + { + return _integerValue; + } + + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) + { + builder.EmitNaturalInt(_integerValue); + } + + public override NativeLayoutVertexNode TemplateDictionaryNode(NodeFactory factory) + { + return factory.NativeLayout.IntegerSlot(_integerValue); + } + + public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer) + { + writer.WriteIntegerSlot(_integerValue); + } + } + + public sealed class PointerToSlotLookupResult : GenericLookupResult + { + int _slotIndex; + + public PointerToSlotLookupResult(int slotIndex) + { + _slotIndex = slotIndex; + } + + public int SlotIndex => _slotIndex; + + protected override int ClassCode => 551050755; + + public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultContext dictionary) + { + return null; + } + + public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append("PointerToSlotLookupResult_").Append(_slotIndex.ToString("x")); + } + + public override string ToString() + { + return "PointerToSlotLookupResult_" + _slotIndex.ToString("x"); + } + + protected override int CompareToImpl(GenericLookupResult other, TypeSystemComparer comparer) + { + PointerToSlotLookupResult pointerToSlotResultOther = (PointerToSlotLookupResult)other; + if (pointerToSlotResultOther._slotIndex == _slotIndex) + return 0; + + return _slotIndex > pointerToSlotResultOther._slotIndex ? 1 : -1; + } + + protected override bool EqualsImpl(GenericLookupResult other) + { + PointerToSlotLookupResult pointerToSlotResultOther = (PointerToSlotLookupResult)other; + return pointerToSlotResultOther._slotIndex == _slotIndex; + } + + protected override int GetHashCodeImpl() + { + return _slotIndex; + } + + public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, GenericLookupResultContext dictionary, GenericDictionaryNode dictionaryNode) + { + builder.EmitPointerReloc(dictionaryNode, _slotIndex * factory.Target.PointerSize); + } + + public override NativeLayoutVertexNode TemplateDictionaryNode(NodeFactory factory) + { + return factory.NativeLayout.PointerToOtherSlot(_slotIndex); + } + + public override void WriteDictionaryTocData(NodeFactory factory, IGenericLookupResultTocWriter writer) + { + // Under no circumstance should we attempt to write out a pointer to slot result + throw new InvalidProgramException(); + } + } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs index bf8e8174d..8d0d3a0e1 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.GenericLookups.cs @@ -132,6 +132,16 @@ namespace ILCompiler.DependencyAnalysis { return new ConstrainedMethodUseLookupResult(constrainedMethodUse.ConstrainedMethod, constrainedMethodUse.ConstraintType, constrainedMethodUse.DirectCall); }); + + _integers = new NodeCache<int, GenericLookupResult>(integer => + { + return new IntegerLookupResult(integer); + }); + + _pointersToSlots = new NodeCache<int, GenericLookupResult>(slotIndex => + { + return new PointerToSlotLookupResult(slotIndex); + }); } private NodeCache<TypeDesc, GenericLookupResult> _typeSymbols; @@ -297,6 +307,26 @@ namespace ILCompiler.DependencyAnalysis { return _constrainedMethodUses.GetOrAdd(new ConstrainedMethodUseKey(constrainedMethod, constraintType, directCall)); } + + private static NodeCache<int, GenericLookupResult> _integers = new NodeCache<int, GenericLookupResult>(slotIndex => + { + return new PointerToSlotLookupResult(slotIndex); + }); + + public static GenericLookupResult Integer(int integer) + { + return _integers.GetOrAdd(integer); + } + + private static NodeCache<int, GenericLookupResult> _pointersToSlots = new NodeCache<int, GenericLookupResult>(slotIndex => + { + return new PointerToSlotLookupResult(slotIndex); + }); + + public static GenericLookupResult PointerToSlot(int slotIndex) + { + return _pointersToSlots.GetOrAdd(slotIndex); + } } public GenericLookupResults GenericLookup = new GenericLookupResults(); diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs index b85027a02..b60b54691 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs @@ -70,7 +70,7 @@ namespace ILCompiler.DependencyAnalysis { DictionaryLayoutNode layout = factory.GenericDictionaryLayout(_dictionaryOwner); - if (!layout.HasFixedSlots) + if (layout.HasUnfixedSlots) { // When the helper call gets marked, ensure the generic layout for the associated dictionaries // includes the signature. diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs index d1c45adbe..408ccea42 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcDictionaryLayoutNode.cs @@ -42,7 +42,7 @@ namespace ILCompiler.DependencyAnalysis 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(); - public override void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary) => throw new NotImplementedException(); + public override void EmitDictionaryData(ref ObjectDataBuilder builder, NodeFactory factory, GenericDictionaryNode dictionary, bool fixedLayoutOnly) => throw new NotImplementedException(); #endif } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs index c8e7fb773..5c085d192 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs @@ -76,8 +76,8 @@ namespace ILCompiler return new EmptyInteropStubManager(compilationModuleGroup, context, null); } - public UtcNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, IEnumerable<ModuleDesc> inputModules, string metadataFile, string outputFile, UTCNameMangler nameMangler, bool buildMRT) - : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), NewEmptyInteropStubManager(context, compilationModuleGroup), nameMangler, new AttributeDrivenLazyGenericsPolicy(), null, new UtcDictionaryLayoutProvider()) + public UtcNodeFactory(CompilerTypeSystemContext context, CompilationModuleGroup compilationModuleGroup, IEnumerable<ModuleDesc> inputModules, string metadataFile, string outputFile, UTCNameMangler nameMangler, bool buildMRT, DictionaryLayoutProvider dictionaryLayoutProvider) + : base(context, compilationModuleGroup, PickMetadataManager(context, compilationModuleGroup, inputModules, metadataFile), NewEmptyInteropStubManager(context, compilationModuleGroup), nameMangler, new AttributeDrivenLazyGenericsPolicy(), null, dictionaryLayoutProvider) { CreateHostedNodeCaches(); CompilationUnitPrefix = nameMangler.CompilationUnitPrefix; @@ -324,9 +324,9 @@ namespace ILCompiler return _standaloneGCStaticDescs.GetOrAdd(staticDesc); } - private class UtcDictionaryLayoutProvider : DictionaryLayoutProvider + public class UtcDictionaryLayoutProvider : DictionaryLayoutProvider { - internal override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) + public override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) { return new UtcDictionaryLayoutNode(methodOrType); } diff --git a/src/ILCompiler.Compiler/src/Compiler/DictionaryLayoutProvider.cs b/src/ILCompiler.Compiler/src/Compiler/DictionaryLayoutProvider.cs index 6982e9ea6..193fffb44 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DictionaryLayoutProvider.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DictionaryLayoutProvider.cs @@ -12,7 +12,7 @@ namespace ILCompiler /// </summary> public abstract class DictionaryLayoutProvider { - internal abstract DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType); + public abstract DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType); } /// <summary> @@ -21,7 +21,7 @@ namespace ILCompiler /// </summary> public sealed class LazyDictionaryLayoutProvider : DictionaryLayoutProvider { - internal override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) + public override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) { return new LazilyBuiltDictionaryLayoutNode(methodOrType); } diff --git a/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs b/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs index 38df4dae1..9b50db7db 100644 --- a/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs +++ b/src/ILCompiler.Compiler/src/Compiler/ILScanner.cs @@ -150,7 +150,7 @@ namespace ILCompiler } } - internal override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) + public override DictionaryLayoutNode GetLayout(TypeSystemEntity methodOrType) { if (methodOrType is TypeDesc type) { |