Skip to content

Commit

Permalink
Add support for new option --perfmap-format-version
Browse files Browse the repository at this point in the history
Today, two PerfMap formats exist:

(0) Legacy format produced by Crossgen1 with {MVID} in the file name.
(1) New format produced by Crossgen2 / R2RDump without the {MVID}
and with r2rmap extension.

I haven't conditioned production of the new metadata, it gets
produced even for format version 0 (legacy). I believe this is more
useful for starting work on adapting perfmap consumers to use the
new metadata.

As next step I'll work on SDK and Arcade fixes for support of the
new PerfMap format. Once all these changes land in the runtime
repo, we can bump up the default format produced by Crossgen2 to 1.

Thanks

Tomas
  • Loading branch information
trylek committed Jul 1, 2021
1 parent db9d4e5 commit 8571140
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace ILCompiler.Diagnostics
{
public class PerfMapWriter
{
public const int LegacyCrossgen1FormatVersion = 0;

public const int CurrentFormatVersion = 1;

public enum PseudoRVA : uint
Expand All @@ -30,8 +32,13 @@ private PerfMapWriter(TextWriter writer)
_writer = writer;
}

public static void Write(string perfMapFileName, IEnumerable<MethodInfo> methods, IEnumerable<AssemblyInfo> inputAssemblies, TargetOS targetOS, TargetArchitecture targetArch)
public static void Write(string perfMapFileName, int perfMapFormatVersion, IEnumerable<MethodInfo> methods, IEnumerable<AssemblyInfo> inputAssemblies, TargetOS targetOS, TargetArchitecture targetArch)
{
if (perfMapFormatVersion > CurrentFormatVersion)
{
throw new NotSupportedException(perfMapFormatVersion.ToString());
}

using (TextWriter writer = new StreamWriter(perfMapFileName))
{
IEnumerable<AssemblyInfo> orderedInputs = inputAssemblies.OrderBy(asm => asm.Name, StringComparer.OrdinalIgnoreCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ internal class ReadyToRunObjectWriter
/// </summary>
private string _perfMapPath;

/// <summary>
/// Requested version of the perfmap file format
/// </summary>
private int _perfMapFormatVersion;

/// <summary>
/// If non-zero, the PE file will be laid out such that it can naturally be mapped with a higher alignment than 4KB.
/// This is used to support loading via large pages on Linux.
Expand Down Expand Up @@ -142,6 +147,7 @@ public NodeInfo(ISymbolNode node, int nodeIndex, int symbolIndex)
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
int perfMapFormatVersion,
bool generateProfileFile,
CallChainProfile callChainProfile,
int customPESectionAlignment)
Expand All @@ -158,6 +164,7 @@ public NodeInfo(ISymbolNode node, int nodeIndex, int symbolIndex)
_pdbPath = pdbPath;
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
_perfMapFormatVersion = perfMapFormatVersion;

bool generateMap = (generateMapFile || generateMapCsvFile);
bool generateSymbols = (generatePdbFile || generatePerfMapFile);
Expand Down Expand Up @@ -367,7 +374,7 @@ public void EmitPortableExecutable()
{
path = Path.GetDirectoryName(_objectFilePath);
}
_symbolFileBuilder.SavePerfMap(path, _objectFilePath, _nodeFactory.Target.OperatingSystem, _nodeFactory.Target.Architecture);
_symbolFileBuilder.SavePerfMap(path, _perfMapFormatVersion, _objectFilePath, _nodeFactory.Target.OperatingSystem, _nodeFactory.Target.Architecture);
}

if (_profileFileBuilder != null)
Expand Down Expand Up @@ -445,6 +452,7 @@ private void EmitObjectData(R2RPEBuilder r2rPeBuilder, ObjectData data, int node
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
int perfMapFormatVersion,
bool generateProfileFile,
CallChainProfile callChainProfile,
int customPESectionAlignment)
Expand All @@ -462,6 +470,7 @@ private void EmitObjectData(R2RPEBuilder r2rPeBuilder, ObjectData data, int node
pdbPath: pdbPath,
generatePerfMapFile: generatePerfMapFile,
perfMapPath: perfMapPath,
perfMapFormatVersion: perfMapFormatVersion,
generateProfileFile: generateProfileFile,
callChainProfile,
customPESectionAlignment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ public sealed class ReadyToRunCodegenCompilation : Compilation
private readonly string _pdbPath;
private readonly bool _generatePerfMapFile;
private readonly string _perfMapPath;
private readonly int _perfMapFormatVersion;
private readonly bool _generateProfileFile;
private readonly Func<MethodDesc, string> _printReproInstructions;

Expand Down Expand Up @@ -282,6 +283,7 @@ public sealed class ReadyToRunCodegenCompilation : Compilation
string pdbPath,
bool generatePerfMapFile,
string perfMapPath,
int perfMapFormatVersion,
bool generateProfileFile,
int parallelism,
ProfileDataManager profileData,
Expand All @@ -307,6 +309,7 @@ public sealed class ReadyToRunCodegenCompilation : Compilation
_pdbPath = pdbPath;
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
_perfMapFormatVersion = perfMapFormatVersion;
_generateProfileFile = generateProfileFile;
_customPESectionAlignment = customPESectionAlignment;
SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory, verifyTypeAndFieldLayout);
Expand Down Expand Up @@ -353,6 +356,7 @@ public override void Compile(string outputFile)
pdbPath: _pdbPath,
generatePerfMapFile: _generatePerfMapFile,
perfMapPath: _perfMapPath,
perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: _generateProfileFile,
callChainProfile: _profileData.CallChainProfile,
_customPESectionAlignment);
Expand Down Expand Up @@ -433,6 +437,7 @@ private void RewriteComponentFile(string inputFile, string outputFile, string ow
pdbPath: null,
generatePerfMapFile: false,
perfMapPath: null,
perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: false,
_profileData.CallChainProfile,
customPESectionAlignment: 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public sealed class ReadyToRunCodegenCompilationBuilder : CompilationBuilder
private string _pdbPath;
private bool _generatePerfMapFile;
private string _perfMapPath;
private int _perfMapFormatVersion;
private bool _generateProfileFile;
private int _parallelism;
Func<MethodDesc, string> _printReproInstructions;
Expand Down Expand Up @@ -155,10 +156,11 @@ public ReadyToRunCodegenCompilationBuilder UsePdbFile(bool generatePdbFile, stri
return this;
}

public ReadyToRunCodegenCompilationBuilder UsePerfMapFile(bool generatePerfMapFile, string perfMapPath)
public ReadyToRunCodegenCompilationBuilder UsePerfMapFile(bool generatePerfMapFile, string perfMapPath, int perfMapFormatVersion)
{
_generatePerfMapFile = generatePerfMapFile;
_perfMapPath = perfMapPath;
_perfMapFormatVersion = perfMapFormatVersion;
return this;
}

Expand Down Expand Up @@ -310,6 +312,7 @@ public override ICompilation ToCompilation()
pdbPath: _pdbPath,
generatePerfMapFile: _generatePerfMapFile,
perfMapPath: _perfMapPath,
perfMapFormatVersion: _perfMapFormatVersion,
generateProfileFile: _generateProfileFile,
_parallelism,
_profileData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +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, TargetOS targetOS, TargetArchitecture targetArch)
public void SavePerfMap(string perfMapPath, int perfMapFormatVersion, string dllFileName, TargetOS targetOS, TargetArchitecture targetArch)
{
string perfMapFileName = Path.Combine(perfMapPath, Path.GetFileNameWithoutExtension(dllFileName) + ".ni.r2rmap");
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(), _outputInfoBuilder.EnumerateInputAssemblies(), targetOS, targetArch);
PerfMapWriter.Write(perfMapFileName, perfMapFormatVersion, _outputInfoBuilder.EnumerateMethods(), _outputInfoBuilder.EnumerateInputAssemblies(), targetOS, targetArch);
}
}
}
5 changes: 5 additions & 0 deletions src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace ILCompiler
{
internal class CommandLineOptions
{
public const int DefaultPerfMapFormatVersion = 0;

public bool Help;
public string HelpText;

Expand Down Expand Up @@ -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;
Expand All @@ -81,6 +84,7 @@ public CommandLineOptions(string[] args)
MibcFilePaths = Array.Empty<string>();
CodegenOptions = Array.Empty<string>();

PerfMapFormatVersion = DefaultPerfMapFormatVersion;
Parallelism = Environment.ProcessorCount;
SingleMethodGenericArg = null;

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/tools/aot/crossgen2/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ private void RunSingleCompilation(Dictionary<string, string> inFilePaths, Instru
.UseMapFile(_commandLineOptions.Map)
.UseMapCsvFile(_commandLineOptions.MapCsv)
.UsePdbFile(_commandLineOptions.Pdb, _commandLineOptions.PdbPath)
.UsePerfMapFile(_commandLineOptions.PerfMap, _commandLineOptions.PerfMapPath)
.UsePerfMapFile(_commandLineOptions.PerfMap, _commandLineOptions.PerfMapPath, _commandLineOptions.PerfMapFormatVersion)
.UseProfileFile(jsonProfile != null)
.UseParallelism(_commandLineOptions.Parallelism)
.UseProfileData(profileDataManager)
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/tools/aot/crossgen2/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,7 @@
<data name="PerfMapFilePathOption" xml:space="preserve">
<value>Explicit specification of the PerfMap file path</value>
</data>
</root>
<data name="PerfMapFormatVersionOption" xml:space="preserve">
<value>Explicitly request a particular PerfMap format version</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/coreclr/tools/r2rdump/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static RootCommand RootCommand()
command.AddOption(new Option<string>(new[] { "--pdb-path" }, "PDB output path for --create-pdb"));
command.AddOption(new Option<bool>(new[] { "--create-perfmap" }, "Create PerfMap"));
command.AddOption(new Option<string>(new[] { "--perfmap-path" }, "PerfMap output path for --create-perfmap"));
command.AddOption(new Option<int>(new[] { "--perfmap-format-version" }, "PerfMap format version for --create-perfmap"));
return command;
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/coreclr/tools/r2rdump/R2RDump.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,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; }
Expand All @@ -66,6 +67,11 @@ public class DumpOptions : IAssemblyResolver

private SignatureFormattingOptions signatureFormattingOptions;

public DumpOptions()
{
PerfmapFormatVersion = PerfMapWriter.CurrentFormatVersion;
}

/// <summary>
/// Probing extensions to use when looking up assemblies under reference paths.
/// </summary>
Expand Down Expand Up @@ -426,9 +432,9 @@ public void Dump(ReadyToRunReader r2r)
string perfmapPath = _options.PerfmapPath;
if (string.IsNullOrEmpty(perfmapPath))
{
perfmapPath = Path.ChangeExtension(r2r.Filename, ".map");
perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
}
PerfMapWriter.Write(perfmapPath, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), r2r.TargetOperatingSystem, r2r.TargetArchitecture);
PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), r2r.TargetOperatingSystem, r2r.TargetArchitecture);
}

if (standardDump)
Expand Down

0 comments on commit 8571140

Please sign in to comment.