| File: Compiler\RootingServiceProvider.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 ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; using Internal.Text; using Internal.TypeSystem; using Debug = System.Diagnostics.Debug; namespace ILCompiler { internal delegate void RootAdder(object o, string reason); internal sealed class RootingServiceProvider : IRootingServiceProvider { private readonly NodeFactory _factory; private readonly RootAdder _rootAdder; public RootingServiceProvider(NodeFactory factory, RootAdder rootAdder) { _factory = factory; _rootAdder = rootAdder; } public void AddCompilationRoot(MethodDesc method, string reason, Utf8String exportName, bool exportHidden = false) { MethodDesc canonMethod = method.GetCanonMethodTarget(CanonicalFormKind.Specific); IMethodNode methodEntryPoint = _factory.MethodEntrypoint(canonMethod); _rootAdder(methodEntryPoint, reason); if (!exportName.IsNull) { exportName = _factory.NameMangler.NodeMangler.ExternMethod(exportName, method); _factory.NodeAliases.Add(methodEntryPoint, (exportName, exportHidden)); } if (canonMethod != method && method.HasInstantiation) _rootAdder(_factory.MethodGenericDictionary(method), reason); } public void AddCompilationRoot(TypeDesc type, string reason) { _rootAdder(_factory.MaximallyConstructableType(type), reason); } public void AddReflectionRoot(TypeDesc type, string reason) { TypeDesc lookedAtType = type; do { _factory.TypeSystemContext.EnsureLoadableType(lookedAtType); lookedAtType = (lookedAtType as MetadataType)?.ContainingType; } while (lookedAtType != null); _rootAdder(_factory.ReflectedType(type), reason); } public void AddReflectionRoot(MethodDesc method, string reason) { if (!_factory.MetadataManager.IsReflectionBlocked(method)) { _factory.TypeSystemContext.EnsureLoadableMethod(method); _rootAdder(_factory.ReflectedMethod(method.GetCanonMethodTarget(CanonicalFormKind.Specific)), reason); } } public void AddReflectionRoot(FieldDesc field, string reason) { if (!_factory.MetadataManager.IsReflectionBlocked(field)) { _factory.TypeSystemContext.EnsureLoadableType(field.OwningType); _factory.TypeSystemContext.EnsureLoadableType(field.FieldType); _rootAdder(_factory.ReflectedField(field), reason); } } public void AddCompilationRoot(object o, string reason) { Debug.Assert(o is IDependencyNode<NodeFactory>); _rootAdder(o, reason); } public void RootThreadStaticBaseForType(TypeDesc type, string reason) { Debug.Assert(!type.IsGenericDefinition); MetadataType metadataType = type as MetadataType; if (metadataType != null && metadataType.ThreadGcStaticFieldSize.AsInt > 0) { _rootAdder(_factory.TypeThreadStaticIndex(metadataType), reason); // Also explicitly root the non-gc base if we have a lazy cctor if (_factory.PreinitializationManager.HasLazyStaticConstructor(type)) _rootAdder(_factory.TypeNonGCStaticsSymbol(metadataType), reason); } } public void RootGCStaticBaseForType(TypeDesc type, string reason) { Debug.Assert(!type.IsGenericDefinition); MetadataType metadataType = type as MetadataType; if (metadataType != null && metadataType.GCStaticFieldSize.AsInt > 0) { _rootAdder(_factory.TypeGCStaticsSymbol(metadataType), reason); // Also explicitly root the non-gc base if we have a lazy cctor if (_factory.PreinitializationManager.HasLazyStaticConstructor(type)) _rootAdder(_factory.TypeNonGCStaticsSymbol(metadataType), reason); } } public void RootNonGCStaticBaseForType(TypeDesc type, string reason) { Debug.Assert(!type.IsGenericDefinition); MetadataType metadataType = type as MetadataType; if (metadataType != null && (metadataType.NonGCStaticFieldSize.AsInt > 0 || _factory.PreinitializationManager.HasLazyStaticConstructor(type))) { _rootAdder(_factory.TypeNonGCStaticsSymbol(metadataType), reason); } } public void RootModuleMetadata(ModuleDesc module, string reason) { // RootModuleMetadata is kind of a hack - this is pretty much only used to force include // type forwarders from assemblies metadata generator would normally not look at. // This will go away when the temporary RD.XML parser goes away. if (_factory.MetadataManager is UsageBasedMetadataManager mdManager) { // If we wouldn't generate metadata for the global module type, don't root the metadata at all. // Global module type always gets metadata and if we're not generating it, this is not the right // compilation unit (we're likely doing multifile). if (mdManager.CanGenerateMetadata(module.GetGlobalModuleType())) { _rootAdder(_factory.ModuleMetadata(module), reason); } } } public void RootReadOnlyDataBlob(byte[] data, int alignment, string reason, Utf8String exportName, bool exportHidden) { var blob = _factory.ReadOnlyDataBlob(Utf8String.Concat("__readonlydata_"u8, exportName.AsSpan()), data, alignment); _rootAdder(blob, reason); exportName = _factory.NameMangler.NodeMangler.ExternVariable(exportName); _factory.NodeAliases.Add(blob, (exportName, exportHidden)); } public void RootDelegateMarshallingData(DefType type, string reason) { _rootAdder(_factory.DelegateMarshallingData(type), reason); } public void RootStructMarshallingData(DefType type, string reason) { _rootAdder(_factory.StructMarshallingData(type), reason); } } }