diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs
new file mode 100644
index 00000000000000..02ff300e617e8d
--- /dev/null
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+namespace ILCompiler.Diagnostics
+{
+ public struct AssemblyInfo
+ {
+ public readonly string Name;
+ public readonly Guid Mvid;
+
+ public AssemblyInfo(string name, Guid mvid)
+ {
+ Name = name;
+ Mvid = mvid;
+ }
+ }
+}
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
index 8c9419db564aa9..8fe3bd1982d475 100644
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
@@ -17,4 +17,8 @@
Debug;Release;Checked
+
+
+
+
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs
index 4696bc9e2d18ff..dd494b9fdcf9a8 100644
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PerfMapWriter.cs
@@ -4,11 +4,27 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+
+using Internal.TypeSystem;
namespace ILCompiler.Diagnostics
{
public class PerfMapWriter
{
+ public const int LegacyCrossgen1FormatVersion = 0;
+
+ public const int CurrentFormatVersion = 1;
+
+ public enum PseudoRVA : uint
+ {
+ OutputGuid = 0xFFFFFFFF,
+ TargetOS = 0xFFFFFFFE,
+ TargetArchitecture = 0xFFFFFFFD,
+ FormatVersion = 0xFFFFFFFC,
+ }
+
private TextWriter _writer;
private PerfMapWriter(TextWriter writer)
@@ -16,11 +32,32 @@ private PerfMapWriter(TextWriter writer)
_writer = writer;
}
- public static void Write(string perfMapFileName, IEnumerable methods)
+ public static void Write(string perfMapFileName, int perfMapFormatVersion, IEnumerable methods, IEnumerable inputAssemblies, TargetOS targetOS, TargetArchitecture targetArch)
{
+ if (perfMapFormatVersion > CurrentFormatVersion)
+ {
+ throw new NotSupportedException(perfMapFormatVersion.ToString());
+ }
+
using (TextWriter writer = new StreamWriter(perfMapFileName))
{
+ IEnumerable orderedInputs = inputAssemblies.OrderBy(asm => asm.Name, StringComparer.OrdinalIgnoreCase);
+
PerfMapWriter perfMapWriter = new PerfMapWriter(writer);
+
+ List inputHash = new List();
+ foreach (AssemblyInfo inputAssembly in orderedInputs)
+ {
+ inputHash.AddRange(inputAssembly.Mvid.ToByteArray());
+ }
+ inputHash.Add((byte)targetOS);
+ inputHash.Add((byte)targetArch);
+ Guid outputGuid = new Guid(MD5.HashData(inputHash.ToArray()));
+ perfMapWriter.WriteLine(outputGuid.ToString(), (uint)PseudoRVA.OutputGuid, 0);
+ perfMapWriter.WriteLine(targetOS.ToString(), (uint)PseudoRVA.TargetOS, 0);
+ perfMapWriter.WriteLine(targetArch.ToString(), (uint)PseudoRVA.TargetArchitecture, 0);
+ perfMapWriter.WriteLine(CurrentFormatVersion.ToString(), (uint)PseudoRVA.FormatVersion, 0);
+
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.HotRVA != 0 && methodInfo.HotLength != 0)
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
index 74da51246b620c..6404f77fbac06d 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
@@ -45,6 +45,12 @@ internal class ReadyToRunObjectWriter
///
private readonly EcmaModule _componentModule;
+ ///
+ /// Compilation input files. Input files are emitted as perfmap entries and used
+ /// to calculate the output GUID of the ReadyToRun executable for symbol indexation.
+ ///
+ private readonly IEnumerable _inputFiles;
+
///
/// Nodes to emit into the output executable as collected by the dependency analysis.
///
@@ -101,9 +107,9 @@ internal class ReadyToRunObjectWriter
private string _perfMapPath;
///
- /// MVID of the input managed module to embed in the perfmap file name.
+ /// Requested version of the perfmap file format
///
- private Guid? _perfMapMvid;
+ private int _perfMapFormatVersion;
///
/// If non-zero, the PE file will be laid out such that it can naturally be mapped with a higher alignment than 4KB.
@@ -132,6 +138,7 @@ public NodeInfo(ISymbolNode node, int nodeIndex, int symbolIndex)
public ReadyToRunObjectWriter(
string objectFilePath,
EcmaModule componentModule,
+ IEnumerable inputFiles,
IEnumerable nodes,
NodeFactory factory,
bool generateMapFile,
@@ -140,13 +147,14 @@ public ReadyToRunObjectWriter(
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
- Guid? perfMapMvid,
+ int perfMapFormatVersion,
bool generateProfileFile,
CallChainProfile callChainProfile,
int customPESectionAlignment)
{
_objectFilePath = objectFilePath;
_componentModule = componentModule;
+ _inputFiles = inputFiles;
_nodes = nodes;
_nodeFactory = factory;
_customPESectionAlignment = customPESectionAlignment;
@@ -156,7 +164,7 @@ public ReadyToRunObjectWriter(
_pdbPath = pdbPath;
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
- _perfMapMvid = perfMapMvid;
+ _perfMapFormatVersion = perfMapFormatVersion;
bool generateMap = (generateMapFile || generateMapCsvFile);
bool generateSymbols = (generatePdbFile || generatePerfMapFile);
@@ -329,6 +337,11 @@ public void EmitPortableExecutable()
if (_outputInfoBuilder != null)
{
+ foreach (string inputFile in _inputFiles)
+ {
+ _outputInfoBuilder.AddInputModule(_nodeFactory.TypeSystemContext.GetModuleFromPath(inputFile));
+ }
+
r2rPeBuilder.AddSections(_outputInfoBuilder);
if (_generateMapFile)
@@ -361,7 +374,7 @@ public void EmitPortableExecutable()
{
path = Path.GetDirectoryName(_objectFilePath);
}
- _symbolFileBuilder.SavePerfMap(path, _objectFilePath, _perfMapMvid);
+ _symbolFileBuilder.SavePerfMap(path, _perfMapFormatVersion, _objectFilePath, _nodeFactory.Target.OperatingSystem, _nodeFactory.Target.Architecture);
}
if (_profileFileBuilder != null)
@@ -430,6 +443,7 @@ private void EmitObjectData(R2RPEBuilder r2rPeBuilder, ObjectData data, int node
public static void EmitObject(
string objectFilePath,
EcmaModule componentModule,
+ IEnumerable inputFiles,
IEnumerable nodes,
NodeFactory factory,
bool generateMapFile,
@@ -438,7 +452,7 @@ public static void EmitObject(
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
- Guid? perfMapMvid,
+ int perfMapFormatVersion,
bool generateProfileFile,
CallChainProfile callChainProfile,
int customPESectionAlignment)
@@ -447,6 +461,7 @@ public static void EmitObject(
ReadyToRunObjectWriter objectWriter = new ReadyToRunObjectWriter(
objectFilePath,
componentModule,
+ inputFiles,
nodes,
factory,
generateMapFile: generateMapFile,
@@ -455,7 +470,7 @@ public static void EmitObject(
pdbPath: pdbPath,
generatePerfMapFile: generatePerfMapFile,
perfMapPath: perfMapPath,
- perfMapMvid: perfMapMvid,
+ perfMapFormatVersion: perfMapFormatVersion,
generateProfileFile: generateProfileFile,
callChainProfile,
customPESectionAlignment);
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
index 1dce9f8f67f538..ac7058bf90daec 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
@@ -247,7 +247,7 @@ public sealed class ReadyToRunCodegenCompilation : Compilation
private readonly string _pdbPath;
private readonly bool _generatePerfMapFile;
private readonly string _perfMapPath;
- private readonly Guid? _perfMapMvid;
+ private readonly int _perfMapFormatVersion;
private readonly bool _generateProfileFile;
private readonly Func _printReproInstructions;
@@ -283,7 +283,7 @@ internal ReadyToRunCodegenCompilation(
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
- Guid? perfMapMvid,
+ int perfMapFormatVersion,
bool generateProfileFile,
int parallelism,
ProfileDataManager profileData,
@@ -309,7 +309,7 @@ internal ReadyToRunCodegenCompilation(
_pdbPath = pdbPath;
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
- _perfMapMvid = perfMapMvid;
+ _perfMapFormatVersion = perfMapFormatVersion;
_generateProfileFile = generateProfileFile;
_customPESectionAlignment = customPESectionAlignment;
SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory, verifyTypeAndFieldLayout);
@@ -347,6 +347,7 @@ public override void Compile(string outputFile)
ReadyToRunObjectWriter.EmitObject(
outputFile,
componentModule: null,
+ inputFiles: _inputFiles,
nodes,
NodeFactory,
generateMapFile: _generateMapFile,
@@ -355,7 +356,7 @@ public override void Compile(string outputFile)
pdbPath: _pdbPath,
generatePerfMapFile: _generatePerfMapFile,
perfMapPath: _perfMapPath,
- perfMapMvid: _perfMapMvid,
+ perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: _generateProfileFile,
callChainProfile: _profileData.CallChainProfile,
_customPESectionAlignment);
@@ -427,6 +428,7 @@ private void RewriteComponentFile(string inputFile, string outputFile, string ow
ReadyToRunObjectWriter.EmitObject(
outputFile,
componentModule: inputModule,
+ inputFiles: new string[] { inputFile },
componentGraph.MarkedNodeList,
componentFactory,
generateMapFile: false,
@@ -435,7 +437,7 @@ private void RewriteComponentFile(string inputFile, string outputFile, string ow
pdbPath: null,
generatePerfMapFile: false,
perfMapPath: null,
- perfMapMvid: null,
+ perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: false,
_profileData.CallChainProfile,
customPESectionAlignment: 0);
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
index fa4d3182e9afb6..c1207a4b5b2f00 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
@@ -31,7 +31,7 @@ public sealed class ReadyToRunCodegenCompilationBuilder : CompilationBuilder
private string _pdbPath;
private bool _generatePerfMapFile;
private string _perfMapPath;
- private Guid? _perfMapMvid;
+ private int _perfMapFormatVersion;
private bool _generateProfileFile;
private int _parallelism;
Func _printReproInstructions;
@@ -156,11 +156,11 @@ public ReadyToRunCodegenCompilationBuilder UsePdbFile(bool generatePdbFile, stri
return this;
}
- public ReadyToRunCodegenCompilationBuilder UsePerfMapFile(bool generatePerfMapFile, string perfMapPath, Guid? inputModuleMvid)
+ public ReadyToRunCodegenCompilationBuilder UsePerfMapFile(bool generatePerfMapFile, string perfMapPath, int perfMapFormatVersion)
{
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
- _perfMapMvid = inputModuleMvid;
+ _perfMapFormatVersion = perfMapFormatVersion;
return this;
}
@@ -312,7 +312,7 @@ public override ICompilation ToCompilation()
pdbPath: _pdbPath,
generatePerfMapFile: _generatePerfMapFile,
perfMapPath: _perfMapPath,
- perfMapMvid: _perfMapMvid,
+ perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: _generateProfileFile,
_parallelism,
_profileData,
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs
index 82145e37999dad..ca6efc9edb1116 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/OutputInfoBuilder.cs
@@ -106,6 +106,7 @@ public OutputSymbol(int sectionIndex, int offset, string name)
///
public class OutputInfoBuilder
{
+ private readonly List _inputModules;
private readonly List _nodes;
private readonly List _symbols;
private readonly List _sections;
@@ -117,6 +118,7 @@ public class OutputInfoBuilder
public OutputInfoBuilder()
{
+ _inputModules = new List();
_nodes = new List();
_symbols = new List();
_sections = new List();
@@ -127,6 +129,11 @@ public OutputInfoBuilder()
_relocCounts = new Dictionary();
}
+ public void AddInputModule(EcmaModule module)
+ {
+ _inputModules.Add(module);
+ }
+
public void AddNode(OutputNode node, ISymbolDefinitionNode symbol)
{
_nodes.Add(node);
@@ -197,6 +204,16 @@ public IEnumerable EnumerateMethods()
}
}
+ public IEnumerable EnumerateInputAssemblies()
+ {
+ foreach (EcmaModule inputModule in _inputModules)
+ {
+ yield return new AssemblyInfo(
+ inputModule.Assembly.GetName().Name,
+ inputModule.MetadataReader.GetGuid(inputModule.MetadataReader.GetModuleDefinition().Mvid));
+ }
+ }
+
private string FormatMethodName(MethodDesc method, TypeNameFormatter typeNameFormatter)
{
StringBuilder output = new StringBuilder();
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/SymbolFileBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/SymbolFileBuilder.cs
index 7ec93572f6fc2a..8cd0ad481cc6d2 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/SymbolFileBuilder.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/SymbolFileBuilder.cs
@@ -8,6 +8,7 @@
using System.Text;
using System.Threading.Tasks;
+using Internal.TypeSystem;
using ILCompiler.Diagnostics;
namespace ILCompiler.PEWriter
@@ -28,12 +29,34 @@ public void SavePdb(string pdbPath, string dllFileName)
new PdbWriter(pdbPath, PDBExtraData.None).WritePDBData(dllFileName, _outputInfoBuilder.EnumerateMethods());
}
- public void SavePerfMap(string perfMapPath, string dllFileName, Guid? perfMapMvid)
+ public void SavePerfMap(string perfMapPath, int perfMapFormatVersion, string dllFileName, TargetOS targetOS, TargetArchitecture targetArch)
{
- string mvidComponent = (perfMapMvid.HasValue ? perfMapMvid.Value.ToString() : "composite");
- string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + ".ni.{" + mvidComponent + "}.map");
+ string perfMapExtension;
+ if (perfMapFormatVersion == PerfMapWriter.LegacyCrossgen1FormatVersion)
+ {
+ string mvidComponent = null;
+ foreach (AssemblyInfo inputAssembly in _outputInfoBuilder.EnumerateInputAssemblies())
+ {
+ if (mvidComponent == null)
+ {
+ mvidComponent = inputAssembly.Mvid.ToString();
+ }
+ else
+ {
+ mvidComponent = "composite";
+ break;
+ }
+ }
+ perfMapExtension = ".ni.{" + mvidComponent + "}.map";
+ }
+ else
+ {
+ perfMapExtension = ".ni.r2rmap";
+ }
+
+ string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + perfMapExtension);
Console.WriteLine("Emitting PerfMap file: {0}", perfMapFileName);
- PerfMapWriter.Write(perfMapFileName, _outputInfoBuilder.EnumerateMethods());
+ PerfMapWriter.Write(perfMapFileName, perfMapFormatVersion, _outputInfoBuilder.EnumerateMethods(), _outputInfoBuilder.EnumerateInputAssemblies(), targetOS, targetArch);
}
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj
index 1424375efc4e33..0d332d59f91d08 100644
--- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj
@@ -7,7 +7,7 @@
AnyCPU
Open
true
- netstandard2.0
+ $(NetCoreAppToolCurrent)
false
8002,NU1701
win-x64;win-x86
@@ -27,6 +27,9 @@
-
+
+
+
+
diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
index f727ed872e03f0..821a38f545e200 100644
--- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
+using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
@@ -15,9 +16,9 @@
using Internal.CorConstants;
using Internal.Runtime;
using Internal.ReadyToRunConstants;
+using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
-using System.Linq;
namespace ILCompiler.Reflection.ReadyToRun
{
@@ -79,6 +80,8 @@ public IReadOnlyList Methods
public sealed class ReadyToRunReader
{
+ public const int GuidByteSize = 16;
+
private const string SystemModuleName = "System.Private.CoreLib";
///
@@ -176,6 +179,33 @@ public Machine Machine
}
}
+ ///
+ /// Conversion of the PE machine ID to TargetArchitecture used by TargetDetails.
+ ///
+ public TargetArchitecture TargetArchitecture
+ {
+ get
+ {
+ switch (Machine)
+ {
+ case Machine.I386:
+ return TargetArchitecture.X86;
+
+ case Machine.Amd64:
+ return TargetArchitecture.X64;
+
+ case Machine.ArmThumb2:
+ return TargetArchitecture.ARM;
+
+ case Machine.Arm64:
+ return TargetArchitecture.ARM64;
+
+ default:
+ throw new NotImplementedException(_machine.ToString());
+ }
+ }
+ }
+
///
/// Targeting operating system for the R2R executable
///
@@ -188,6 +218,36 @@ public OperatingSystem OperatingSystem
}
}
+ ///
+ /// Targeting operating system converted to the enumeration used by TargetDetails.
+ ///
+ public TargetOS TargetOperatingSystem
+ {
+ get
+ {
+ switch (OperatingSystem)
+ {
+ case OperatingSystem.Windows:
+ return TargetOS.Windows;
+
+ case OperatingSystem.Linux:
+ return TargetOS.Linux;
+
+ case OperatingSystem.Apple:
+ return TargetOS.OSX;
+
+ case OperatingSystem.FreeBSD:
+ return TargetOS.FreeBSD;
+
+ case OperatingSystem.NetBSD:
+ return TargetOS.FreeBSD;
+
+ default:
+ throw new NotImplementedException(OperatingSystem.ToString());
+ }
+ }
+ }
+
///
/// Targeting processor architecture of the R2R executable
///
@@ -537,6 +597,12 @@ public IAssemblyMetadata GetGlobalMetadata()
return (_composite ? null : _assemblyCache[0]);
}
+ public string GetGlobalAssemblyName()
+ {
+ MetadataReader mdReader = GetGlobalMetadata().MetadataReader;
+ return mdReader.GetString(mdReader.GetAssemblyDefinition().Name);
+ }
+
private unsafe void EnsureHeader()
{
if (_readyToRunHeader != null)
@@ -1087,6 +1153,26 @@ public int GetAssemblyIndex(ReadyToRunSection section)
}
}
+ public Guid GetAssemblyMvid(int assemblyIndex)
+ {
+ EnsureHeader();
+ if (_composite)
+ {
+ if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.ManifestAssemblyMvids, out ReadyToRunSection mvidSection))
+ {
+ return Guid.Empty;
+ }
+ int mvidOffset = GetOffset(mvidSection.RelativeVirtualAddress) + GuidByteSize * assemblyIndex;
+ return new Guid(new ReadOnlySpan(Image, mvidOffset, ReadyToRunReader.GuidByteSize));
+ }
+ else
+ {
+ Debug.Assert(assemblyIndex == 0);
+ MetadataReader mdReader = GetGlobalMetadata().MetadataReader;
+ return mdReader.GetGuid(mdReader.GetModuleDefinition().Mvid);
+ }
+ }
+
///
/// Iterates through a native hashtable to get all RIDs
///
diff --git a/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs b/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
index 573b1eb5cb4975..c91e615eb73a86 100644
--- a/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
+++ b/src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
@@ -12,6 +12,8 @@ namespace ILCompiler
{
internal class CommandLineOptions
{
+ public const int DefaultPerfMapFormatVersion = 0;
+
public bool Help;
public string HelpText;
@@ -56,6 +58,7 @@ internal class CommandLineOptions
public string PdbPath;
public bool PerfMap;
public string PerfMapPath;
+ public int PerfMapFormatVersion;
public int Parallelism;
public int CustomPESectionAlignment;
public string MethodLayout;
@@ -81,6 +84,7 @@ public CommandLineOptions(string[] args)
MibcFilePaths = Array.Empty();
CodegenOptions = Array.Empty();
+ PerfMapFormatVersion = DefaultPerfMapFormatVersion;
Parallelism = Environment.ProcessorCount;
SingleMethodGenericArg = null;
@@ -139,6 +143,7 @@ public CommandLineOptions(string[] args)
syntax.DefineOption("pdb-path", ref PdbPath, SR.PdbFilePathOption);
syntax.DefineOption("perfmap", ref PerfMap, SR.PerfMapFileOption);
syntax.DefineOption("perfmap-path", ref PerfMapPath, SR.PerfMapFilePathOption);
+ syntax.DefineOption("perfmap-format-version", ref PerfMapFormatVersion, SR.PerfMapFormatVersionOption);
syntax.DefineOption("method-layout", ref MethodLayout, SR.MethodLayoutOption);
syntax.DefineOption("file-layout", ref FileLayout, SR.FileLayoutOption);
diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs
index 2f84f6fb5a7e69..aeeb9f57bb3c42 100644
--- a/src/coreclr/tools/aot/crossgen2/Program.cs
+++ b/src/coreclr/tools/aot/crossgen2/Program.cs
@@ -517,7 +517,6 @@ private void RunSingleCompilation(Dictionary inFilePaths, Instru
List inputModules = new List();
List rootingModules = new List();
- Guid? inputModuleMvid = null;
foreach (var inputFile in inFilePaths)
{
@@ -526,10 +525,6 @@ private void RunSingleCompilation(Dictionary inFilePaths, Instru
rootingModules.Add(module);
versionBubbleModulesHash.Add(module);
- if (!_commandLineOptions.Composite && !inputModuleMvid.HasValue)
- {
- inputModuleMvid = module.MetadataReader.GetGuid(module.MetadataReader.GetModuleDefinition().Mvid);
- }
if (!_commandLineOptions.CompositeOrInputBubble)
{
@@ -687,7 +682,7 @@ private void RunSingleCompilation(Dictionary inFilePaths, Instru
.UseMapFile(_commandLineOptions.Map)
.UseMapCsvFile(_commandLineOptions.MapCsv)
.UsePdbFile(_commandLineOptions.Pdb, _commandLineOptions.PdbPath)
- .UsePerfMapFile(_commandLineOptions.PerfMap, _commandLineOptions.PerfMapPath, inputModuleMvid)
+ .UsePerfMapFile(_commandLineOptions.PerfMap, _commandLineOptions.PerfMapPath, _commandLineOptions.PerfMapFormatVersion)
.UseProfileFile(jsonProfile != null)
.UseParallelism(_commandLineOptions.Parallelism)
.UseProfileData(profileDataManager)
diff --git a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
index 084138ebc7c4dd..c031f303e44e03 100644
--- a/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
+++ b/src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
@@ -345,4 +345,7 @@
Explicit specification of the PerfMap file path
-
+
+ Explicitly request a particular PerfMap format version
+
+
\ No newline at end of file
diff --git a/src/coreclr/tools/r2rdump/CommandLineOptions.cs b/src/coreclr/tools/r2rdump/CommandLineOptions.cs
index 8857cdbae87ac7..9a1296bdbd65d6 100644
--- a/src/coreclr/tools/r2rdump/CommandLineOptions.cs
+++ b/src/coreclr/tools/r2rdump/CommandLineOptions.cs
@@ -40,6 +40,7 @@ public static RootCommand RootCommand()
command.AddOption(new Option(new[] { "--pdb-path" }, "PDB output path for --create-pdb"));
command.AddOption(new Option(new[] { "--create-perfmap" }, "Create PerfMap"));
command.AddOption(new Option(new[] { "--perfmap-path" }, "PerfMap output path for --create-perfmap"));
+ command.AddOption(new Option(new[] { "--perfmap-format-version" }, "PerfMap format version for --create-perfmap"));
return command;
}
}
diff --git a/src/coreclr/tools/r2rdump/R2RDump.cs b/src/coreclr/tools/r2rdump/R2RDump.cs
index 8a24273302b567..94d71835966e5a 100644
--- a/src/coreclr/tools/r2rdump/R2RDump.cs
+++ b/src/coreclr/tools/r2rdump/R2RDump.cs
@@ -20,6 +20,7 @@
using ILCompiler.Reflection.ReadyToRun;
using Internal.Runtime;
+using Internal.TypeSystem;
namespace R2RDump
{
@@ -55,6 +56,7 @@ public class DumpOptions : IAssemblyResolver
public bool CreatePerfmap { get; set; }
public string PerfmapPath { get; set; }
+ public int PerfmapFormatVersion { get; set; }
public FileInfo[] Reference { get; set; }
@@ -65,6 +67,11 @@ public class DumpOptions : IAssemblyResolver
private SignatureFormattingOptions signatureFormattingOptions;
+ public DumpOptions()
+ {
+ PerfmapFormatVersion = PerfMapWriter.CurrentFormatVersion;
+ }
+
///
/// Probing extensions to use when looking up assemblies under reference paths.
///
@@ -425,9 +432,9 @@ public void Dump(ReadyToRunReader r2r)
string perfmapPath = _options.PerfmapPath;
if (string.IsNullOrEmpty(perfmapPath))
{
- perfmapPath = Path.ChangeExtension(r2r.Filename, ".map");
- PerfMapWriter.Write(perfmapPath, ProduceDebugInfoMethods(r2r));
+ perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
}
+ PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), r2r.TargetOperatingSystem, r2r.TargetArchitecture);
}
if (standardDump)
@@ -457,6 +464,21 @@ IEnumerable ProduceDebugInfoMethods(ReadyToRunReader r2r)
}
}
+ IEnumerable ProduceDebugInfoAssemblies(ReadyToRunReader r2r)
+ {
+ if (r2r.Composite)
+ {
+ foreach (KeyValuePair kvpRefAssembly in r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase))
+ {
+ yield return new AssemblyInfo(kvpRefAssembly.Key, r2r.GetAssemblyMvid(kvpRefAssembly.Value));
+ }
+ }
+ else
+ {
+ yield return new AssemblyInfo(r2r.GetGlobalAssemblyName(), r2r.GetAssemblyMvid(0));
+ }
+ }
+
///
/// Returns true if the name, signature or id of method matches query
///
diff --git a/src/coreclr/tools/r2rdump/R2RDump.sln b/src/coreclr/tools/r2rdump/R2RDump.sln
index 6596a597f104a5..e8f71beb5a0079 100644
--- a/src/coreclr/tools/r2rdump/R2RDump.sln
+++ b/src/coreclr/tools/r2rdump/R2RDump.sln
@@ -8,38 +8,89 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Reflection.Ready
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Diagnostics", "..\aot\ILCompiler.Diagnostics\ILCompiler.Diagnostics.csproj", "{4E9512BA-F963-472A-B689-37D4D32456F3}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.TypeSystem.ReadyToRun", "..\aot\ILCompiler.TypeSystem.ReadyToRun\ILCompiler.TypeSystem.ReadyToRun.csproj", "{F9CC5645-9E5D-41EE-ACD3-120F661DDA51}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Checked|Any CPU = Checked|Any CPU
+ Checked|x64 = Checked|x64
+ Checked|x86 = Checked|x86
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|Any CPU.ActiveCfg = Release|Any CPU
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|Any CPU.Build.0 = Release|Any CPU
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|x64.ActiveCfg = Release|x64
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|x64.Build.0 = Release|x64
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|x86.ActiveCfg = Debug|x86
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Checked|x86.Build.0 = Debug|x86
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|Any CPU.ActiveCfg = Debug|x64
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|Any CPU.Build.0 = Debug|x64
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|x64.ActiveCfg = Debug|x64
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|x64.Build.0 = Debug|x64
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|x86.ActiveCfg = Debug|x86
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Debug|x86.Build.0 = Debug|x86
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|Any CPU.Build.0 = Release|Any CPU
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|x64.ActiveCfg = Release|x64
{00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|x64.Build.0 = Release|x64
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|x86.ActiveCfg = Release|x86
+ {00CCF6D0-5905-428E-A2A2-2A6D09D8C257}.Release|x86.Build.0 = Release|x86
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|Any CPU.ActiveCfg = Release|Any CPU
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|Any CPU.Build.0 = Release|Any CPU
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|x64.ActiveCfg = Release|x64
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|x64.Build.0 = Release|x64
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|x86.ActiveCfg = Release|Any CPU
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Checked|x86.Build.0 = Release|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|x64.ActiveCfg = Debug|x64
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|x64.Build.0 = Debug|x64
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Debug|x86.Build.0 = Debug|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|Any CPU.Build.0 = Release|Any CPU
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|x64.ActiveCfg = Release|x64
{E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|x64.Build.0 = Release|x64
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|x86.ActiveCfg = Release|Any CPU
+ {E2A577E5-7AF3-49B3-BA78-7071B75ED64B}.Release|x86.Build.0 = Release|Any CPU
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Checked|Any CPU.ActiveCfg = Checked|x86
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Checked|x64.ActiveCfg = Checked|x64
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Checked|x64.Build.0 = Checked|x64
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Checked|x86.ActiveCfg = Checked|x86
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Checked|x86.Build.0 = Checked|x86
{4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|Any CPU.ActiveCfg = Debug|x64
{4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|Any CPU.Build.0 = Debug|x64
{4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|x64.ActiveCfg = Debug|x64
{4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|x64.Build.0 = Debug|x64
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|x86.ActiveCfg = Debug|x86
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Debug|x86.Build.0 = Debug|x86
{4E9512BA-F963-472A-B689-37D4D32456F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E9512BA-F963-472A-B689-37D4D32456F3}.Release|Any CPU.Build.0 = Release|Any CPU
{4E9512BA-F963-472A-B689-37D4D32456F3}.Release|x64.ActiveCfg = Release|Any CPU
{4E9512BA-F963-472A-B689-37D4D32456F3}.Release|x64.Build.0 = Release|Any CPU
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Release|x86.ActiveCfg = Release|x86
+ {4E9512BA-F963-472A-B689-37D4D32456F3}.Release|x86.Build.0 = Release|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Checked|Any CPU.ActiveCfg = Checked|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Checked|x64.ActiveCfg = Checked|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Checked|x64.Build.0 = Checked|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Checked|x86.ActiveCfg = Checked|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Checked|x86.Build.0 = Checked|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Debug|x64.ActiveCfg = Debug|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Debug|x64.Build.0 = Debug|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Debug|x86.ActiveCfg = Debug|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Debug|x86.Build.0 = Debug|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Release|Any CPU.ActiveCfg = Release|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Release|x64.ActiveCfg = Release|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Release|x64.Build.0 = Release|x64
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Release|x86.ActiveCfg = Release|x86
+ {F9CC5645-9E5D-41EE-ACD3-120F661DDA51}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/coreclr/tools/r2rdump/TextDumper.cs b/src/coreclr/tools/r2rdump/TextDumper.cs
index 0e062b88508f93..7ca2b58c77dcdc 100644
--- a/src/coreclr/tools/r2rdump/TextDumper.cs
+++ b/src/coreclr/tools/r2rdump/TextDumper.cs
@@ -7,6 +7,7 @@
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
+using System.Runtime.CompilerServices;
using System.Reflection.PortableExecutable;
using System.Text;
@@ -18,8 +19,6 @@ namespace R2RDump
{
class TextDumper : Dumper
{
- private const int GuidByteSize = 16;
-
public TextDumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
: base(r2r, writer, disassembler, options)
{
@@ -90,14 +89,8 @@ internal override void DumpHeader(bool dumpSections)
int assemblyIndex = 0;
foreach (string assemblyName in _r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
{
- string dividerName = $@"Component Assembly [{assemblyIndex}]: {assemblyName}";
- if (_r2r.ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.ManifestAssemblyMvids, out ReadyToRunSection mvidSection))
- {
- int mvidOffset = _r2r.GetOffset(mvidSection.RelativeVirtualAddress) + GuidByteSize * assemblyIndex;
- Guid mvid = new Guid(new ReadOnlySpan(_r2r.Image, mvidOffset, GuidByteSize));
- dividerName += $@" - MVID {mvid:b}";
- }
- WriteDivider(dividerName);
+ Guid mvid = _r2r.GetAssemblyMvid(assemblyIndex);
+ WriteDivider($@"Component Assembly [{assemblyIndex}]: {assemblyName} - MVID {mvid:b}");
ReadyToRunCoreHeader assemblyHeader = _r2r.ReadyToRunAssemblyHeaders[assemblyIndex];
foreach (ReadyToRunSection section in NormalizedSections(assemblyHeader))
{
@@ -513,12 +506,10 @@ internal override void DumpSectionContents(ReadyToRunSection section)
_writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable.ToEscapedString());
break;
case ReadyToRunSectionType.ManifestAssemblyMvids:
- int mvidOffset = _r2r.GetOffset(section.RelativeVirtualAddress);
- int mvidCount = section.Size / GuidByteSize;
+ int mvidCount = section.Size / ReadyToRunReader.GuidByteSize;
for (int mvidIndex = 0; mvidIndex < mvidCount; mvidIndex++)
{
- Guid mvid = new Guid(new Span(_r2r.Image, mvidOffset + GuidByteSize * mvidIndex, GuidByteSize));
- _writer.WriteLine("MVID[{0}] = {1:b}", mvidIndex, mvid);
+ _writer.WriteLine("MVID[{0}] = {1:b}", mvidIndex, _r2r.GetAssemblyMvid(mvidIndex));
}
break;
default: