diff options
author | Tijoy Tom Kalathiparambil <tijoytk@microsoft.com> | 2017-10-24 20:09:23 +0300 |
---|---|---|
committer | Tijoy Tom Kalathiparambil <tijoytk@microsoft.com> | 2017-10-24 20:09:23 +0300 |
commit | dce2dbd1b167199c80fd5d871e0ef8c30972b3ae (patch) | |
tree | d32bae5822601c7ec9bd2724633d19435aee3ae2 /src/ILCompiler.Compiler | |
parent | d9844b8e3ea2f47e527c607acec9bf1fc190dd4c (diff) |
Emit virtual method slot info for projectx , iterate over all constructed EEType and build a blod of virtual method token to slot number.
[tfs-changeset: 1679025]
Diffstat (limited to 'src/ILCompiler.Compiler')
4 files changed, 165 insertions, 9 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.WindowsDebugData.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.WindowsDebugData.cs index 681e19733..19bdb1c94 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.WindowsDebugData.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.WindowsDebugData.cs @@ -43,10 +43,13 @@ namespace ILCompiler.DependencyAnalysis _debugMergedAssembliesSection = new WindowsDebugMergedAssembliesSection(mergedAssemblyRecords); _debugILImagesSection = new WindowsDebugILImagesSection(mergedAssemblyRecords); _debugManagedNativeDictionaryInfoSection = new WindowsDebugManagedNativeDictionaryInfoSection(); + + _debugTypeSignatureMapSection = new WindowsDebugTypeSignatureMapSection(_userDefinedTypeDescriptor); + _debugMethodSignatureMapSection = new WindowsDebugMethodSignatureMapSection(); + _debugVirtualMethodInfoSection = new WindowsDebugMethodInfoSection(mergedAssemblyRecords); } bool is64Bit = _nodeFactory.Target.PointerSize == 8 ? true : false; - if (nonSectionBasedDebugInfoWriter != null) { _userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(nonSectionBasedDebugInfoWriter, is64Bit, _nodeFactory.Target.Abi); @@ -57,12 +60,6 @@ namespace ILCompiler.DependencyAnalysis _userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(_debugTypeRecordsSection, is64Bit, _nodeFactory.Target.Abi); } - if (mergedAssemblyRecords != null) - { - _debugTypeSignatureMapSection = new WindowsDebugTypeSignatureMapSection(_userDefinedTypeDescriptor); - _debugMethodSignatureMapSection = new WindowsDebugMethodSignatureMapSection(); - } - graph.AddRoot(_debugNeedTypeIndicesStore, "Debug Force All EETypes to have type indices"); if (_debugManagedNativeDictionaryInfoSection != null) @@ -79,6 +76,8 @@ namespace ILCompiler.DependencyAnalysis graph.AddRoot(_debugPseudoAssemblySection, "Debug PseudoAssembly"); if (_debugTypeRecordsSection != null) graph.AddRoot(_debugTypeRecordsSection, "Debug Type Records"); + if (_debugVirtualMethodInfoSection != null) + graph.AddRoot(_debugVirtualMethodInfoSection, "Debug Virtual Method map"); } private WindowsDebugILImagesSection _debugILImagesSection; @@ -90,6 +89,7 @@ namespace ILCompiler.DependencyAnalysis private WindowsDebugPseudoAssemblySection _debugPseudoAssemblySection; private UserDefinedTypeDescriptor _userDefinedTypeDescriptor; private WindowsDebugNeedTypeIndicesStoreNode _debugNeedTypeIndicesStore; + private WindowsDebugMethodInfoSection _debugVirtualMethodInfoSection; internal WindowsDebugILImagesSection DebugILImagesSection => _debugILImagesSection; internal WindowsDebugTypeSignatureMapSection DebugTypeSignatureMapSection => _debugTypeSignatureMapSection; @@ -99,6 +99,7 @@ namespace ILCompiler.DependencyAnalysis internal WindowsDebugPseudoAssemblySection DebugPseudoAssemblySection => _debugPseudoAssemblySection; internal WindowsDebugManagedNativeDictionaryInfoSection DebugManagedNativeDictionaryInfoSection => _debugManagedNativeDictionaryInfoSection; internal WindowsDebugNeedTypeIndicesStoreNode DebugNeedTypeIndicesStore => _debugNeedTypeIndicesStore; + internal WindowsDebugMethodInfoSection DebugVirtualMethodInfoSection => _debugVirtualMethodInfoSection; public UserDefinedTypeDescriptor UserDefinedTypeDescriptor => _userDefinedTypeDescriptor; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs new file mode 100644 index 000000000..3a7065c22 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs @@ -0,0 +1,153 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using Internal.TypeSystem.Ecma; +using Internal.Text; +using Internal.TypeSystem; +using Internal.TypeSystem.TypesDebugInfo; + +namespace ILCompiler.DependencyAnalysis +{ + internal class WindowsDebugMethodInfoSection : ObjectNode, ISymbolDefinitionNode + { + private MergedAssemblyRecords _mergedAssemblies; + + public WindowsDebugMethodInfoSection(MergedAssemblyRecords mergedAssemblies) + { + _mergedAssemblies = mergedAssemblies; + } + + private ObjectNodeSection _section = new ObjectNodeSection(".mdinfo", SectionType.ReadOnly); + public override ObjectNodeSection Section => _section; + + public override bool IsShareable => false; + + public override bool StaticDependenciesAreComputed => true; + + public int Offset => 0; + + public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) + { + sb.Append(GetName(null)); + } + + private uint AdjustIndex(uint assemblyIndex, uint corLibIndex) + { + if (assemblyIndex == 0x7FFFFFFF) + return corLibIndex; + if (assemblyIndex < corLibIndex) + return assemblyIndex; + return assemblyIndex + 1; + } + + // + // returns the DebugInfoBlob containing the method token to virtual method slot mapping + + // .mdinfo format + // offset 0, 4 bytes: version number + // offset 4, 4 bytes: count of assemblies + // + // for each assembly + // offset 0, 4 bytes: count of methods with a virtual method slot + // + // for each method + // offset 0, 4 bytes: method def token (as they are in the input assembly) + // offset 4, 2 bytes: length of the per method information [ currently always 4 ] + // offset 6, 4 bytes: virtual slot number + // methods are sorted by their method def token + + internal DebugInfoBlob GetDebugMethodInfoMap(NodeFactory factory) + { + Dictionary<EcmaAssembly, uint> originalAssemblyOrder = new Dictionary<EcmaAssembly, uint>(); + List<SortedDictionary<uint, int>> moduleMethods = new List<SortedDictionary<uint, int>>(); + + // re-construct orginal assembly input order + foreach (MergedAssemblyRecord mergedAssembly in _mergedAssemblies.MergedAssemblies) + { + uint assemblyIndex = AdjustIndex(mergedAssembly.AssemblyIndex, _mergedAssemblies.CorLibIndex); + originalAssemblyOrder.Add(mergedAssembly.Assembly, assemblyIndex); + moduleMethods.Add(new SortedDictionary<uint, int>()); + } + + foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes()) + { + // skip if sealed + if (type.IsSealed()) + continue; + + // no generic support yet + if (type is EcmaType) + { + EcmaType ecmaType = (EcmaType)type; + EcmaAssembly ecmaAssembly = (EcmaAssembly)ecmaType.EcmaModule; + int assemblyIndex = (int)originalAssemblyOrder[ecmaAssembly]; + SortedDictionary<uint, int> methodList = moduleMethods[assemblyIndex]; + foreach (MethodDesc md in type.GetAllMethods()) + { + // skip non-virtual and final methods + if (!md.IsVirtual || md.IsFinal) + continue; + // skip generic + if (md.HasInstantiation) + continue; + // method token. + EntityHandle methodHandle = ((EcmaMethod)md).Handle; + uint methodToken = (uint)MetadataTokens.GetToken(methodHandle); + // find virtual method slot. + MethodDesc declaringMethodForSlot = + MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(md.GetTypicalMethodDefinition()); + int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, declaringMethodForSlot); + if (slot != -1 && !methodList.ContainsKey(methodToken)) + methodList.Add(methodToken, slot); + } + } + } + return ConvertToDebugInfoBlob(moduleMethods); + } + + private DebugInfoBlob ConvertToDebugInfoBlob(List<SortedDictionary<uint, int>> assemblyMethods) + { + DebugInfoBlob debugInfoBlob = new DebugInfoBlob(); + // version + debugInfoBlob.WriteDWORD(0); + // number of assemblies + debugInfoBlob.WriteDWORD((uint)assemblyMethods.Count); + foreach (var methods in assemblyMethods) + { + debugInfoBlob.WriteDWORD((uint)methods.Count); + foreach (var method in methods) + { + // method token + debugInfoBlob.WriteDWORD(method.Key); + // method info length , now it's 4 + debugInfoBlob.WriteWORD(4); + // method slot + debugInfoBlob.WriteDWORD((uint)method.Value); + } + } + return debugInfoBlob; + } + + 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 }); + } + DebugInfoBlob debugData = GetDebugMethodInfoMap(factory); + return new ObjectData(debugData.ToArray(), Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this }); + } + + protected override string GetName(NodeFactory context) + { + return "___DebugMethodInfoSection"; + } + } +} diff --git a/src/ILCompiler.Compiler/src/Compiler/MergedAssemblyRecords.cs b/src/ILCompiler.Compiler/src/Compiler/MergedAssemblyRecords.cs index 8ff3b428c..bfff48ca6 100644 --- a/src/ILCompiler.Compiler/src/Compiler/MergedAssemblyRecords.cs +++ b/src/ILCompiler.Compiler/src/Compiler/MergedAssemblyRecords.cs @@ -85,10 +85,11 @@ namespace ILCompiler public class MergedAssemblyRecords { public IReadOnlyCollection<MergedAssemblyRecord> MergedAssemblies { get; } - - public MergedAssemblyRecords(IReadOnlyCollection<MergedAssemblyRecord> mergedAssemblies) + public uint CorLibIndex { get; } + public MergedAssemblyRecords(IReadOnlyCollection<MergedAssemblyRecord> mergedAssemblies, uint corLibIndex) { MergedAssemblies = mergedAssemblies; + CorLibIndex = corLibIndex; } } } diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index 5df406672..1f95fd8d7 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -107,6 +107,7 @@ <Compile Include="Compiler\DependencyAnalysis\WindowsDebugManagedNativeDictionaryInfoSection.cs" /> <Compile Include="Compiler\DependencyAnalysis\WindowsDebugMergedAssemblyRecordsSection.cs" /> <Compile Include="Compiler\DependencyAnalysis\WindowsDebugMethodMapSection.cs" /> + <Compile Include="Compiler\DependencyAnalysis\WindowsDebugMethodInfoSection.cs" /> <Compile Include="Compiler\DependencyAnalysis\WindowsDebugNeedTypeIndicesStoreNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\WindowsDebugPseudoAssemblySection.cs" /> <Compile Include="Compiler\DependencyAnalysis\WindowsDebugTypeRecordsSection.cs" /> |