| File: Compiler\RuntimeConstructableTypeDependencies.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.Collections.Generic; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; using Internal.TypeSystem; namespace ILCompiler { internal static class RuntimeConstructableTypeDependencies { public static IEETypeNode GetEffectiveTrimTargetType(NodeFactory factory, TypeDesc trimmingTargetType, bool conditionConstructed) { bool unwrapped = false; // Many parameterized types can be created at runtime using the type loader. // Pointers and byrefs can be made out of thin air since there's no code for them. // Arrays have some rules so we may still be able to condition on the array. while (trimmingTargetType.IsParameterizedType) { if (GenericTypesTemplateMap.IsArrayTypeEligibleForTemplate(trimmingTargetType) // The template shouldn't be __Canon[] && !trimmingTargetType.ConvertToCanonForm(CanonicalFormKind.Specific).GetParameterType().IsCanonicalDefinitionType(CanonicalFormKind.Any)) { // We can condition on this type since we'd either need this type to be // present in the compilation, or template for this type to be present. // // We specifically exclude the `__Canon[]` template because conditioning // on the __Canon[] template would be strictly worse than conditioning on // the element type in a normal app. break; } // The type can be just MakeArrayType/MakePointerType at runtime, so drill into // the element type, we need to condition on that - can't condition on the // constructed type. trimmingTargetType = trimmingTargetType.GetParameterType(); unwrapped = true; } if (!conditionConstructed) return factory.NecessaryTypeSymbol(trimmingTargetType); // If we're conditioning on the type being constructed but we unwrapped element type, // the condition is now only a metadata type symbol. This is because e.g. // `Array.CreateInstance(typeof(Element))` needs only the typeof-level type load // of the element type to create a constructed array type. return unwrapped ? factory.MetadataTypeSymbol(trimmingTargetType) : factory.MaximallyConstructableType(trimmingTargetType); } public static void AddTypeLoaderDependencies( List<DependencyNodeCore<NodeFactory>.CombinedDependencyListEntry> dependencies, NodeFactory factory, IEETypeNode dependencyType, string reason) { TypeDesc type = dependencyType.Type; TypeDesc canonType = type.ConvertToCanonForm(CanonicalFormKind.Specific); if (canonType != type && GenericTypesTemplateMap.IsEligibleToHaveATemplate(canonType)) { dependencies.Add(new DependencyNodeCore<NodeFactory>.CombinedDependencyListEntry( dependencyType, factory.NativeLayout.TemplateTypeLayout(canonType), reason)); } } } }