diff options
author | Fadi Hanna <fadim@microsoft.com> | 2017-01-13 00:13:43 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-13 00:13:43 +0300 |
commit | 2492dc8132ad0ef9ca273151564694c571cd431b (patch) | |
tree | 0b80f703eb357548a35f514be7f322ebf8d8c971 | |
parent | 59133e10e2e13df6943b837f6cc813429e326f6b (diff) | |
parent | aff69f3d1bf73b0a1857e7eecf1522262b215993 (diff) |
Merge pull request #2440 from fadimounir/runtimemethodhandle
Adding support for RuntimeMethodHandle nodes.
6 files changed, 157 insertions, 2 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs new file mode 100644 index 000000000..b9fbce4cd --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +using Internal.Text; + +namespace ILCompiler.DependencyAnalysis +{ + /// <summary> + /// Represents a native layout signature. A signature is a pair where the first item is a pointer + /// to the TypeManager that contains the native layout info blob of interest, and the second item + /// is an offset into that native layout info blob + /// </summary> + class NativeLayoutSignatureNode : ObjectNode, ISymbolNode + { + private static int s_counter = 0; + + private int _id; + private NativeLayoutSavedVertexNode _nativeSignature; + + public NativeLayoutSignatureNode(NativeLayoutSavedVertexNode nativeSignature) + { + _nativeSignature = nativeSignature; + _id = s_counter++; + } + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(nameMangler.CompilationUnitPrefix).Append("__NativeLayoutSignature_" + _id); + } + public int Offset => 0; + protected override string GetName() => this.GetMangledName(); + public override ObjectNodeSection Section => ObjectNodeSection.ReadOnlyDataSection; + public override bool IsShareable => false; + public override bool StaticDependenciesAreComputed => true; + + protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) + { + DependencyList dependencies = new DependencyList(); + dependencies.Add(new DependencyListEntry(_nativeSignature, "NativeLayoutSignatureNode target vertex")); + return dependencies; + } + + 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 ISymbolNode[] { this }); + + // Ensure native layout is saved to get valid Vertex offsets + factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); + + ObjectDataBuilder objData = new ObjectDataBuilder(factory); + + objData.Alignment = objData.TargetPointerSize; + objData.DefinedSymbols.Add(this); + + objData.EmitPointerReloc(factory.TypeManagerIndirection); + objData.EmitNaturalInt(_nativeSignature.SavedVertex.VertexOffset); + + return objData.ToObjectData(); + } + } +}
\ No newline at end of file diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs index 132984561..fd5a394d2 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutVertexNode.cs @@ -56,6 +56,22 @@ namespace ILCompiler.DependencyAnalysis } } + /// <summary> + /// Any NativeLayoutVertexNode that needs to expose the native layout Vertex after it has been saved + /// needs to derive from this NativeLayoutSavedVertexNode class. + /// + /// A nativelayout Vertex should typically only be exposed for Vertex offset fetching purposes, after the native + /// writer is saved (Vertex offsets get generated when the native writer gets saved). + /// + /// It is important for whoever derives from this class to produce unified Vertices. Calling the WriteVertex method + /// multiple times should always produce the same exact unified Vertex each time (hence the assert in SetSavedVertex). + /// All nativewriter.Getxyz methods return unified Vertices. + /// + /// When exposing a saved Vertex that is a result of a section placement operation (Section.Place(...)), always make + /// sure a unified Vertex is being placed in the section (Section.Place creates a PlacedVertex structure that wraps the + /// Vertex to be placed, so if the Vertex to be placed is unified, there will only be a single unified PlacedVertex + /// structure created for that placed Vertex). + /// </summary> internal abstract class NativeLayoutSavedVertexNode : NativeLayoutVertexNode { public Vertex SavedVertex { get; private set; } @@ -67,7 +83,7 @@ namespace ILCompiler.DependencyAnalysis } } - internal sealed class NativeLayoutMethodLdTokenVertexNode : NativeLayoutVertexNode + internal sealed class NativeLayoutMethodLdTokenVertexNode : NativeLayoutSavedVertexNode { private MethodDesc _method; private NativeLayoutTypeSignatureVertexNode _containingTypeSig; @@ -120,7 +136,7 @@ namespace ILCompiler.DependencyAnalysis } Vertex signature = GetNativeWriter(factory).GetMethodSignature((uint)flags, 0, containingType, methodNameAndSig, args); - return factory.MetadataManager.NativeLayoutInfo.LdTokenInfoSection.Place(signature); + return SetSavedVertex(factory.MetadataManager.NativeLayoutInfo.LdTokenInfoSection.Place(signature)); } } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs index 8b9cff2d2..0cc8c7102 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.NativeLayout.cs @@ -48,6 +48,11 @@ namespace ILCompiler.DependencyAnalysis { return new NativeLayoutMethodLdTokenVertexNode(_factory, method); }); + + _nativeLayoutSignatureNodes = new NodeCache<NativeLayoutSavedVertexNode, NativeLayoutSignatureNode>(signature => + { + return new NativeLayoutSignatureNode(signature); + }); } private NodeCache<TypeDesc, NativeLayoutTypeSignatureVertexNode> _typeSignatures; @@ -80,6 +85,11 @@ namespace ILCompiler.DependencyAnalysis return _methodLdTokenSignatures.GetOrAdd(method); } + private NodeCache<NativeLayoutSavedVertexNode, NativeLayoutSignatureNode> _nativeLayoutSignatureNodes; + internal NativeLayoutSignatureNode NativeLayoutSignature(NativeLayoutSavedVertexNode signature) + { + return _nativeLayoutSignatureNodes.GetOrAdd(signature); + } } public NativeLayoutHelper NativeLayout; diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs index 97bc9cc5d..86491b464 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs @@ -13,6 +13,7 @@ using Internal.Text; using Internal.TypeSystem; using Internal.Runtime; using Internal.IL; +using Internal.NativeFormat; namespace ILCompiler.DependencyAnalysis { @@ -235,6 +236,11 @@ namespace ILCompiler.DependencyAnalysis return new InterfaceDispatchMapNode(type); }); + _runtimeMethodHandles = new NodeCache<MethodDesc, RuntimeMethodHandleNode>((MethodDesc method) => + { + return new RuntimeMethodHandleNode(this, method); + }); + _interfaceDispatchMapIndirectionNodes = new NodeCache<TypeDesc, EmbeddedObjectNode>((TypeDesc type) => { var dispatchMap = InterfaceDispatchMap(type); @@ -370,6 +376,13 @@ namespace ILCompiler.DependencyAnalysis return _interfaceDispatchCells.GetOrAdd(method); } + private NodeCache<MethodDesc, RuntimeMethodHandleNode> _runtimeMethodHandles; + + internal RuntimeMethodHandleNode RuntimeMethodHandle(MethodDesc method) + { + return _runtimeMethodHandles.GetOrAdd(method); + } + private class BlobTupleEqualityComparer : IEqualityComparer<Tuple<Utf8String, byte[], int>> { bool IEqualityComparer<Tuple<Utf8String, byte[], int>>.Equals(Tuple<Utf8String, byte[], int> x, Tuple<Utf8String, byte[], int> y) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs new file mode 100644 index 000000000..ef95dfa27 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; + +using Internal.Text; +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis +{ + class RuntimeMethodHandleNode : ObjectNode, ISymbolNode + { + MethodDesc _targetMethod; + + public RuntimeMethodHandleNode(NodeFactory factory, MethodDesc targetMethod) + { + Debug.Assert(!targetMethod.IsSharedByGenericInstantiations); + _targetMethod = targetMethod; + } + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(nameMangler.CompilationUnitPrefix) + .Append("__RuntimeMethodHandle_") + .Append(NodeFactory.NameMangler.GetMangledMethodName(_targetMethod)); + } + public int Offset => 0; + protected override string GetName() => this.GetMangledName(); + public override ObjectNodeSection Section => ObjectNodeSection.ReadOnlyDataSection; + public override bool IsShareable => false; + public override bool StaticDependenciesAreComputed => true; + + public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) + { + ObjectDataBuilder objData = new ObjectDataBuilder(factory); + + objData.Alignment = objData.TargetPointerSize; + objData.DefinedSymbols.Add(this); + + NativeLayoutMethodLdTokenVertexNode ldtokenSigNode = factory.NativeLayout.MethodLdTokenVertex(_targetMethod); + objData.EmitPointerReloc(factory.NativeLayout.NativeLayoutSignature(ldtokenSigNode)); + + return objData.ToObjectData(); + } + } +} diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index c0c1e599a..10c68b333 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -106,6 +106,8 @@ <Compile Include="Compiler\DependencyAnalysis\NativeLayoutVertexNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\GenericsHashtableNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ExactMethodInstantiationsNode.cs" /> + <Compile Include="Compiler\DependencyAnalysis\RuntimeMethodHandleNode.cs" /> + <Compile Include="Compiler\DependencyAnalysis\NativeLayoutSignatureNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ReadyToRunGenericHelperNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ArrayOfFrozenObjectsNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ClassConstructorContextMap.cs" /> |