| File: Compiler\DependencyAnalysis\TentativeInstanceMethodNode.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 Internal.TypeSystem; using Debug = System.Diagnostics.Debug; namespace ILCompiler.DependencyAnalysis { /// <summary> /// Represents a stand-in for a real method body that can turn into the real method /// body at object emission phase if the real method body was marked. /// It the real method body wasn't marked, this stub will tail-call into a throw helper. /// This node conditionally depends on the real method body - the real method body /// will be brough into compilation if the owning type was marked. /// This operates under the assumption that instance methods don't get called with /// a null `this`. While it's possible to call instance methods with a null `this`, /// there are many reasons why it's a bad idea (C# language assumes `this` can never be null; /// generically shared native code generated by this compiler assumes `this` is not null and /// we can get the generic dictionary out of it, etc.). public class TentativeInstanceMethodNode : TentativeMethodNode { public TentativeInstanceMethodNode(IMethodBodyNode methodNode) : base(methodNode) { Debug.Assert(!methodNode.Method.Signature.IsStatic); Debug.Assert(!methodNode.Method.OwningType.IsValueType); } public override bool HasConditionalStaticDependencies => true; protected override ISymbolNode GetTarget(NodeFactory factory) { // If the class library doesn't provide this helper, the optimization is disabled. MethodDesc helper = factory.InstanceMethodRemovedHelper; return helper == null ? RealBody: factory.MethodEntrypoint(helper); } public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) { // Convert methods on Array<T> into T[] TypeDesc owningType = Method.OwningType; if (owningType.HasSameTypeDefinition(factory.ArrayOfTClass)) { owningType = owningType.Instantiation[0].MakeArrayType(); } // If a constructed symbol for the owning type was included in the compilation, // include the real method body. return new CombinedDependencyListEntry[] { new CombinedDependencyListEntry( RealBody, factory.ConstructedTypeSymbol(owningType), "Instance method on a constructed type"), }; } protected override string GetName(NodeFactory factory) { return "Tentative instance method: " + RealBody.GetMangledName(factory.NameMangler); } public override int ClassCode => 0x8905207; public override string ToString() => Method.ToString(); } }