| File: Compiler\DependencyAnalysis\MetadataEETypeNode.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.Diagnostics; using Internal.Runtime; using Internal.TypeSystem; namespace ILCompiler.DependencyAnalysis { public sealed class MetadataEETypeNode : EETypeNode { public MetadataEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type) { Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any)); } protected override bool IsReflectionVisible => true; protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler) + " with metadata"; public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) { // If there is a constructed version of this node in the graph, emit that instead if (ConstructedEETypeNode.CreationAllowed(_type)) return factory.ConstructedTypeSymbol(_type).Marked; return false; } protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); // Ensure that we track the necessary type symbol if we are working with a metadata type symbol. // The emitter will ensure we don't emit both, but this allows us assert that we only generate // relocs to nodes we emit. dependencyList.Add(factory.NecessaryTypeSymbol(_type), "NecessaryType for metadata type"); if (_type is MetadataType mdType) ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencyList, factory, mdType.Module); // Ask the metadata manager if we have any dependencies due to the presence of the EEType. factory.MetadataManager.GetDependenciesDueToEETypePresence(ref dependencyList, factory, _type); // Reflection-visible valuetypes are considered constructed due to APIs like RuntimeHelpers.Box, // or Enum.ToObject. if (_type.IsValueType) dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible valuetype"); // Delegates can be constructed through runtime magic APIs so consider constructed. if (_type.IsDelegate) dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible delegate"); // Arrays can be constructed through Array.CreateInstanceFromArrayType so consider constructed. if (_type.IsArray) dependencyList.Add(factory.MaximallyConstructableType(_type), "Reflection visible array"); // TODO-SIZE: We need to separate tracking the use of static and instance virtual methods // Unconstructed MethodTables only need to track the static virtuals. // For now, conservatively upgrade to constructed types when static virtuals are present bool hasStaticVirtuals = false; foreach (MetadataType intface in _type.RuntimeInterfaces) { foreach (MethodDesc intfaceMethod in intface.GetAllVirtualMethods()) { if (intfaceMethod.Signature.IsStatic) { hasStaticVirtuals = true; break; } } } if (hasStaticVirtuals) dependencyList.Add(factory.MaximallyConstructableType(_type), "Has static virtual methods"); return dependencyList; } protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) { return _type.BaseType != null ? factory.MetadataTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; } protected override FrozenRuntimeTypeNode GetFrozenRuntimeTypeNode(NodeFactory factory) { return factory.SerializedMetadataRuntimeTypeObject(_type); } protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) { return factory.MetadataTypeSymbol(((ArrayType)_type).ElementType); } protected override IEETypeNode GetInterfaceTypeNode(NodeFactory factory, TypeDesc interfaceType) { return factory.MetadataTypeSymbol(interfaceType); } public override int ClassCode => 99298112; } }