| File: Compiler\DependencyAnalysis\ReadyToRun\EnclosingTypeMapNode.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.ReadyToRun\ILCompiler.ReadyToRun.csproj (ILCompiler.ReadyToRun) |
// 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 Internal.Text; using Internal.TypeSystem.Ecma; using System.Diagnostics; using System.Reflection; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using Internal.ReadyToRunConstants; namespace ILCompiler.DependencyAnalysis.ReadyToRun { public class EnclosingTypeMapNode : ModuleSpecificHeaderTableNode { private MetadataReader _metadata; public EnclosingTypeMapNode(EcmaModule module) : base(module) { _metadata = module.MetadataReader; // This map is only valid for assemblies with <= ReadyToRunEnclosingTypeMap.MaxTypeCount types defined within if (!IsSupported(_metadata)) throw new InternalCompilerErrorException($"EnclosingTypeMap made for assembly with more than 0x{(uint)ReadyToRunEnclosingTypeMap.MaxTypeCount:x} types"); } public static bool IsSupported(MetadataReader metadata) { // This map is only valid for assemblies with <= ReadyToRunEnclosingTypeMap.MaxTypeCount types defined within // and really shouldn't be generated for tiny assemblies, as the map provides very little to no value // in those situations int typeDefinitionCount = metadata.TypeDefinitions.Count; return ((typeDefinitionCount > 10) && (typeDefinitionCount <= (int)ReadyToRunEnclosingTypeMap.MaxTypeCount)); } public override int ClassCode => 990540812; protected override string ModuleSpecificName => "__EnclosingTypeMap__"; public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) return new ObjectData(Array.Empty<byte>(), Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this }); ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly); builder.AddSymbol(this); // This map is only valid for assemblies with <= ReadyToRunEnclosingTypeMap.MaxTypeCount types defined within Debug.Assert(_metadata.TypeDefinitions.Count <= (int)ReadyToRunEnclosingTypeMap.MaxTypeCount); builder.EmitUShort(checked((ushort)_metadata.TypeDefinitions.Count)); foreach (var typeDefinitionHandle in _metadata.TypeDefinitions) { var typeDefinition = _metadata.GetTypeDefinition(typeDefinitionHandle); if (!typeDefinition.IsNested) { builder.EmitUShort(0); } else { builder.EmitUShort(checked((ushort)MetadataTokens.GetRowNumber(typeDefinition.GetDeclaringType()))); } } return builder.ToObjectData(); } } }