| File: Compiler\DependencyAnalysis\ProxyTypeMapNode.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Text; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; using Internal.NativeFormat; using Internal.TypeSystem; namespace ILCompiler.DependencyAnalysis { internal sealed class ProxyTypeMapNode : SortableDependencyNode, IProxyTypeMapNode { private readonly IEnumerable<KeyValuePair<TypeDesc, TypeDesc>> _mapEntries; public ProxyTypeMapNode(TypeDesc typeMapGroup, IEnumerable<KeyValuePair<TypeDesc, TypeDesc>> mapEntries) { _mapEntries = mapEntries; TypeMapGroup = typeMapGroup; } public TypeDesc TypeMapGroup { get; } public IEnumerable<KeyValuePair<TypeDesc, TypeDesc>> MapEntries => _mapEntries; public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; public override bool HasConditionalStaticDependencies => true; public override bool StaticDependenciesAreComputed => true; public override int ClassCode => 779513676; public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) => comparer.Compare(TypeMapGroup, ((ProxyTypeMapNode)other).TypeMapGroup); public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory context) { foreach (var (key, value) in _mapEntries) { yield return new CombinedDependencyListEntry( context.MetadataTypeSymbol(value), context.MaximallyConstructableType(key), "Proxy type map entry"); // If the key type has a canonical form, it could be created at runtime by the type loader. // If there is a type loader template for it, create the generic type instantiation eagerly. TypeDesc canonKey = key.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonKey != key && GenericTypesTemplateMap.IsEligibleToHaveATemplate(canonKey)) { yield return new CombinedDependencyListEntry( context.MaximallyConstructableType(key), context.NativeLayout.TemplateTypeLayout(canonKey), "Proxy map entry that could be loaded at runtime"); } } } public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory context) => Array.Empty<DependencyListEntry>(); public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory context) => Array.Empty<CombinedDependencyListEntry>(); protected override string GetName(NodeFactory context) => $"Proxy type map: {TypeMapGroup}"; private IEnumerable<(IEETypeNode key, IEETypeNode value)> GetMarkedEntries(NodeFactory factory) { foreach (var (key, value) in MapEntries) { IEETypeNode keyNode = factory.MaximallyConstructableType(key); if (keyNode.Marked) { IEETypeNode valueNode = factory.MetadataTypeSymbol(value); Debug.Assert(valueNode.Marked); yield return (keyNode, valueNode); } } } public Vertex CreateTypeMap(NodeFactory factory, NativeWriter writer, Section section, INativeFormatTypeReferenceProvider externalReferences) { VertexHashtable typeMapHashTable = new VertexHashtable(); foreach ((IEETypeNode keyNode, IEETypeNode valueNode) in GetMarkedEntries(factory)) { Vertex keyVertex = externalReferences.EncodeReferenceToType(writer, keyNode.Type); Vertex valueVertex = externalReferences.EncodeReferenceToType(writer, valueNode.Type); Vertex entry = writer.GetTuple(keyVertex, valueVertex); typeMapHashTable.Append((uint)keyNode.Type.GetHashCode(), section.Place(entry)); } Vertex typeMapStateVertex = writer.GetUnsignedConstant(1); // Valid type map state Vertex typeMapGroupVertex = externalReferences.EncodeReferenceToType(writer, TypeMapGroup); Vertex tuple = writer.GetTuple(typeMapGroupVertex, typeMapStateVertex, typeMapHashTable); return section.Place(tuple); } public IProxyTypeMapNode ToAnalysisBasedNode(NodeFactory factory) => new AnalyzedProxyTypeMapNode( TypeMapGroup, GetMarkedEntries(factory) .ToImmutableDictionary(p => p.key.Type, p => p.value.Type)); } }