| File: Compiler\DependencyAnalysis\AddressTakenMethodNode.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 System.Diagnostics; using ILCompiler.DependencyAnalysisFramework; using Internal.Text; using Internal.TypeSystem; namespace ILCompiler.DependencyAnalysis { /// <summary> /// Represents a method with address taken. Under normal circumstances, this node is not emitted /// into the object file and instead references to it are replaced to refer to the underlying method body. /// This is achieved through <see cref="ShouldSkipEmittingObjectNode(NodeFactory)"/> and <see cref="NodeForLinkage(NodeFactory)"/>. /// However, if the underlying method body got folded together with another method due to identical method body folding /// optimization, this node is not skipped and instead emits a jump stub. The purpose of the jump stub is to provide a /// unique code address for the address taken method. /// </summary> internal sealed class AddressTakenMethodNode : JumpStubNode, IMethodNode, ISymbolNodeWithLinkage { private readonly IMethodNode _methodNode; public IMethodNode RealBody => _methodNode; public AddressTakenMethodNode(IMethodNode methodNode) : base(methodNode) { _methodNode = methodNode; } public MethodDesc Method => _methodNode.Method; protected override string GetName(NodeFactory factory) { return "Address taken method: " + _methodNode.GetMangledName(factory.NameMangler); } public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) { return factory.ObjectInterner.GetDeduplicatedSymbol(factory, RealBody) == RealBody; } public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory context) => null; public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; public override bool HasConditionalStaticDependencies => false; public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { // We use the same mangled name as the underlying real method body. // This is okay since this node will go out of the way if the real body is marked // and part of the graph. _methodNode.AppendMangledName(nameMangler, sb); } public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { return comparer.Compare(_methodNode, ((AddressTakenMethodNode)other)._methodNode); } public ISymbolNode NodeForLinkage(NodeFactory factory) { // If someone refers to this node but the target method still has a unique body, // refer to the target method. return factory.ObjectInterner.GetDeduplicatedSymbol(factory, RealBody) == RealBody ? RealBody : this; } public override bool RepresentsIndirectionCell { get { Debug.Assert(!_methodNode.RepresentsIndirectionCell); return false; } } public override int ClassCode => 0xfab0355; public override bool IsShareable => ((ObjectNode)_methodNode).IsShareable; } }