From 8319fa88b38ed64e416d539cde26d8ad555c1c99 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 02:22:06 +0200 Subject: [PATCH 1/8] Add MibcConfig to mibc --- src/coreclr/tools/dotnet-pgo/MibcConfig.cs | 25 ++++++ src/coreclr/tools/dotnet-pgo/MibcEmitter.cs | 34 +++++++- src/coreclr/tools/dotnet-pgo/Program.cs | 88 +++++++++++++++++++-- 3 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 src/coreclr/tools/dotnet-pgo/MibcConfig.cs diff --git a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs new file mode 100644 index 0000000000000..7381135cfaa69 --- /dev/null +++ b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Reflection; + +namespace Microsoft.Diagnostics.Tools.Pgo; + +public class MibcConfig +{ + public string FormatVersion = "1.0"; + public string Os; + public string Arch; + public string Runtime; + + public override string ToString() + { + string str = ""; + foreach (FieldInfo field in GetType().GetFields()) + { + string paddedName = (field.Name + ":").PadRight(18, ' '); + str += $"{paddedName} {field.GetValue(this)}\n"; + } + return str; + } +} diff --git a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs index e99fc610d86ca..c5b528fcbc722 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs @@ -212,12 +212,44 @@ private static void AddAssembliesAssociatedWithMethod(MethodDesc method, HashSet } } - public static int GenerateMibcFile(TypeSystemContext tsc, FileInfo outputFileName, IEnumerable methodsToAttemptToPlaceIntoProfileData, bool validate, bool uncompressed) + // ... + /// + /// Emit a global method "MibcConfig" that will contain key-value settings in the following format: + /// ldstr "key1" + /// ldstr "value1" + /// pop + /// pop + /// ldstr "key2" + /// ldstr "value2" + /// pop + /// pop + /// ... + /// + public static void GenerateConfigData(MibcConfig config, TypeSystemMetadataEmitter emitter) + { + var buffer = new BlobBuilder(); + var il = new InstructionEncoder(buffer); + + foreach (FieldInfo mibcCfgField in typeof(MibcConfig).GetFields()) + { + Debug.Assert(!mibcCfgField.IsStatic && mibcCfgField.FieldType == typeof(string)); + il.LoadString(emitter.GetUserStringHandle(mibcCfgField.Name)); + il.LoadString(emitter.GetUserStringHandle((string)mibcCfgField.GetValue(config) ?? "")); + il.OpCode(ILOpCode.Pop); + il.OpCode(ILOpCode.Pop); + } + il.OpCode(ILOpCode.Ret); + emitter.AddGlobalMethod(nameof(MibcConfig), il, 8); + } + + public static int GenerateMibcFile(MibcConfig config, TypeSystemContext tsc, FileInfo outputFileName, IEnumerable methodsToAttemptToPlaceIntoProfileData, bool validate, bool uncompressed) { TypeSystemMetadataEmitter emitter = new TypeSystemMetadataEmitter(new AssemblyName(outputFileName.Name), tsc); emitter.InjectSystemPrivateCanon(); emitter.AllowUseOfAddGlobalMethod(); + GenerateConfigData(config, emitter); + SortedDictionary groups = new SortedDictionary(); StringBuilder mibcGroupNameBuilder = new StringBuilder(); HashSet assembliesAssociatedWithMethod = new HashSet(); diff --git a/src/coreclr/tools/dotnet-pgo/Program.cs b/src/coreclr/tools/dotnet-pgo/Program.cs index 8972d34ef6227..3c6c126583a0b 100644 --- a/src/coreclr/tools/dotnet-pgo/Program.cs +++ b/src/coreclr/tools/dotnet-pgo/Program.cs @@ -276,7 +276,7 @@ static int InnerDumpMain(CommandLineOptions commandLineOptions) PrintDetailedMessage($"Parsing {commandLineOptions.InputFileToDump}"); var profileData = MIbcProfileParser.ParseMIbcFile(tsc, mibcPeReader, null, onlyDefinedInAssembly: null); - PrintMibcStats(profileData); + PrintMibcStats(ParseMibcConfig(tsc, mibcPeReader), profileData); using (FileStream outputFile = new FileStream(commandLineOptions.OutputFileName.FullName, FileMode.Create, FileAccess.Write)) { @@ -354,6 +354,67 @@ static int InnerDumpMain(CommandLineOptions commandLineOptions) return 0; } + static MibcConfig ParseMibcConfig(TypeRefTypeSystem.TypeRefTypeSystemContext tsc, params PEReader[] pEReaders) + { + MibcConfig mergedConfig = new(); + // When we merge multiple mibc let's just unconditionally pick the first valid MibcConfig + foreach (PEReader peReader in pEReaders) + { + EcmaModule mibcModule = EcmaModule.Create(tsc, peReader, null); + EcmaMethod mibcConfigMth = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod(nameof(MibcConfig), null); + if (mibcConfigMth != null) + { + var ilBody = EcmaMethodIL.Create(mibcConfigMth); + var ilReader = new ILReader(ilBody.GetILBytes()); + + // Parse: + // + // ldstr "key1" + // ldstr "value1" + // pop + // pop + // ldstr "key2" + // ldstr "value2" + // pop + // pop + // ... + // ret + string fieldName = null; + while (ilReader.HasNext) + { + ILOpcode opcode = ilReader.ReadILOpcode(); + switch (opcode) + { + case ILOpcode.ldstr: + var ldStrValue = (string)ilBody.GetObject(ilReader.ReadILToken()); + if (fieldName != null) + { + var field = mergedConfig.GetType().GetField(fieldName); + if (field != null) + { + field.SetValue(mergedConfig, ldStrValue); + } + } + else + { + fieldName = ldStrValue; + } + break; + + case ILOpcode.ret: + case ILOpcode.pop: + fieldName = null; + break; + + default: + throw new InvalidOperationException($"Unexpected opcode: {opcode}"); + } + } + break; + } + } + return mergedConfig; + } static int InnerMergeMain(CommandLineOptions commandLineOptions) { @@ -399,7 +460,8 @@ static int InnerMergeMain(CommandLineOptions commandLineOptions) ProfileData.MergeProfileData(ref partialNgen, mergedProfileData, MIbcProfileParser.ParseMIbcFile(tsc, peReader, assemblyNamesInBubble, onlyDefinedInAssembly: null)); } - int result = MibcEmitter.GenerateMibcFile(tsc, commandLineOptions.OutputFileName, mergedProfileData.Values, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed); + MibcConfig mergedConfig = ParseMibcConfig(tsc, mibcReaders); + int result = MibcEmitter.GenerateMibcFile(mergedConfig, tsc, commandLineOptions.OutputFileName, mergedProfileData.Values, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed); if (result == 0 && commandLineOptions.InheritTimestamp) { commandLineOptions.OutputFileName.CreationTimeUtc = commandLineOptions.InputFilesToMerge.Max(fi => fi.CreationTimeUtc); @@ -445,10 +507,10 @@ static int InnerCompareMibcMain(CommandLineOptions options) ProfileData profile2 = MIbcProfileParser.ParseMIbcFile(tsc, mibc2, null, onlyDefinedInAssembly: null); PrintOutput($"Comparing {name1} to {name2}"); PrintOutput($"Statistics for {name1}"); - PrintMibcStats(profile1); + PrintMibcStats(ParseMibcConfig(tsc, mibc1), profile1); PrintOutput(""); PrintOutput($"Statistics for {name2}"); - PrintMibcStats(profile2); + PrintMibcStats(ParseMibcConfig(tsc, mibc2), profile2); PrintOutput(""); PrintOutput("Comparison"); @@ -792,9 +854,10 @@ static void PrintLikelihoodHistogram(double[] likelihoods) Console.WriteLine(); } - static void PrintMibcStats(ProfileData data) + static void PrintMibcStats(MibcConfig config, ProfileData data) { - List methods = data.GetAllMethodProfileData().ToList(); + PrintOutput(config.ToString()); + List methods = data.GetAllMethodProfileData().ToList(); List profiledMethods = methods.Where(spd => spd.SchemaData != null).ToList(); PrintOutput($"# Methods: {methods.Count}"); PrintOutput($"# Methods with any profile data: {profiledMethods.Count(spd => spd.SchemaData.Length > 0)}"); @@ -1659,13 +1722,24 @@ void AddToInstrumentationData(int eventClrInstanceId, long methodID, int methodF GenerateJittraceFile(commandLineOptions.OutputFileName, methodsUsedInProcess, commandLineOptions.JitTraceOptions); else if (commandLineOptions.FileType.Value == PgoFileType.mibc) { + var config = new MibcConfig(); + + // Look for OS and Arch, e.g. "Windows" and "x64" + TraceEvent processInfo = p.EventsInProcess.Filter(t => t.EventName == "ProcessInfo").FirstOrDefault(); + config.Os = processInfo?.PayloadByName("OSInformation")?.ToString(); + config.Arch = processInfo?.PayloadByName("ArchInformation")?.ToString(); + + // Look for Sku, e.g. "CoreClr" + TraceEvent runtimeStart = p.EventsInProcess.Filter(t => t.EventName == "Runtime/Start").FirstOrDefault(); + config.Runtime = runtimeStart?.PayloadByName("Sku")?.ToString(); + ILCompiler.MethodProfileData[] methodProfileData = new ILCompiler.MethodProfileData[methodsUsedInProcess.Count]; for (int i = 0; i < methodProfileData.Length; i++) { ProcessedMethodData processedData = methodsUsedInProcess[i]; methodProfileData[i] = new ILCompiler.MethodProfileData(processedData.Method, ILCompiler.MethodProfilingDataFlags.ReadMethodCode, processedData.ExclusiveWeight, processedData.WeightedCallData, 0xFFFFFFFF, processedData.InstrumentationData); } - return MibcEmitter.GenerateMibcFile(tsc, commandLineOptions.OutputFileName, methodProfileData, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed); + return MibcEmitter.GenerateMibcFile(config, tsc, commandLineOptions.OutputFileName, methodProfileData, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed); } } return 0; From 3a8f82dbadb6ae040c7ac85aa7ce9ba53fe16ae9 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 20:17:08 +0200 Subject: [PATCH 2/8] Address feedback --- .../Compiler/ProfileData.cs | 4 + .../IBC/IBCProfileData.cs | 9 +- .../IBC/MIbcProfileParser.cs | 64 ++++++++++++- src/coreclr/tools/dotnet-pgo/MibcConfig.cs | 15 ++-- src/coreclr/tools/dotnet-pgo/Program.cs | 89 +++++++------------ 5 files changed, 112 insertions(+), 69 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs index dc5641a83366d..483b612b12ef2 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs @@ -9,6 +9,7 @@ using Internal.Pgo; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; +using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler { @@ -59,6 +60,7 @@ public MethodProfileData(MethodDesc method, MethodProfilingDataFlags flags, doub public abstract class ProfileData { + public abstract MibcConfig Config { get; } public abstract bool PartialNGen { get; } public abstract MethodProfileData GetMethodProfileData(MethodDesc m); public abstract IEnumerable GetAllMethodProfileData(); @@ -131,6 +133,8 @@ private EmptyProfileData() { } + public override MibcConfig Config { get; } = new (); + public override bool PartialNGen => false; public static EmptyProfileData Singleton => s_singleton; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs index e028dbdcd993d..56af311a68e04 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs @@ -5,13 +5,14 @@ using System.Collections.Generic; using Internal.TypeSystem; using System.Linq; +using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler.IBC { public class IBCProfileData : ProfileData { - public IBCProfileData(bool partialNGen, IEnumerable methodData) + public IBCProfileData(MibcConfig config, bool partialNGen, IEnumerable methodData) { MethodProfileData[] dataArray = methodData.ToArray(); foreach (MethodProfileData data in dataArray) @@ -22,12 +23,16 @@ public IBCProfileData(bool partialNGen, IEnumerable methodDat } } _partialNGen = partialNGen; + _config = config; } private readonly Dictionary _methodData = new Dictionary(); private readonly bool _partialNGen; + private readonly MibcConfig _config; - public override bool PartialNGen { get { return _partialNGen; } } + public override MibcConfig Config => _config; + + public override bool PartialNGen => _partialNGen; public override MethodProfileData GetMethodProfileData(MethodDesc m) { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs index f0d7c5afc4100..ffa7390389a7f 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs @@ -17,6 +17,7 @@ using System.Diagnostics; using System.Reflection.PortableExecutable; +using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler.IBC { @@ -219,7 +220,68 @@ public static ProfileData ParseMIbcFile(TypeSystemContext tsc, PEReader peReader } } - return new IBCProfileData(false, loadedMethodProfileData); + return new IBCProfileData(ParseMibcConfig(tsc, peReader), false, loadedMethodProfileData); + + + } + + public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReader) + { + MibcConfig mergedConfig = new(); + // When we merge multiple mibc let's just unconditionally pick the first valid MibcConfig + EcmaModule mibcModule = EcmaModule.Create(tsc, pEReader, null); + EcmaMethod mibcConfigMth = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod(nameof(MibcConfig), null); + + if (mibcConfigMth == null) + return null; + + var ilBody = EcmaMethodIL.Create(mibcConfigMth); + var ilReader = new ILReader(ilBody.GetILBytes()); + + // Parse: + // + // ldstr "key1" + // ldstr "value1" + // pop + // pop + // ldstr "key2" + // ldstr "value2" + // pop + // pop + // ... + // ret + string fieldName = null; + while (ilReader.HasNext) + { + ILOpcode opcode = ilReader.ReadILOpcode(); + switch (opcode) + { + case ILOpcode.ldstr: + var ldStrValue = (string)ilBody.GetObject(ilReader.ReadILToken()); + if (fieldName != null) + { + var field = mergedConfig.GetType().GetField(fieldName); + if (field != null) + { + field.SetValue(mergedConfig, ldStrValue); + } + } + else + { + fieldName = ldStrValue; + } + break; + + case ILOpcode.ret: + case ILOpcode.pop: + fieldName = null; + break; + + default: + throw new InvalidOperationException($"Unexpected opcode: {opcode}"); + } + } + return mergedConfig; } enum MibcGroupParseState diff --git a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs index 7381135cfaa69..af6fe0eb57b8b 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs @@ -14,12 +14,13 @@ public class MibcConfig public override string ToString() { - string str = ""; - foreach (FieldInfo field in GetType().GetFields()) - { - string paddedName = (field.Name + ":").PadRight(18, ' '); - str += $"{paddedName} {field.GetValue(this)}\n"; - } - return str; + return + $""" + FormatVersion: {FormatVersion} + Runtime: {Runtime} + Os: {Os} + Arch: {Arch} + + """; ; } } diff --git a/src/coreclr/tools/dotnet-pgo/Program.cs b/src/coreclr/tools/dotnet-pgo/Program.cs index 3c6c126583a0b..1bad145bfb8a0 100644 --- a/src/coreclr/tools/dotnet-pgo/Program.cs +++ b/src/coreclr/tools/dotnet-pgo/Program.cs @@ -276,7 +276,7 @@ static int InnerDumpMain(CommandLineOptions commandLineOptions) PrintDetailedMessage($"Parsing {commandLineOptions.InputFileToDump}"); var profileData = MIbcProfileParser.ParseMIbcFile(tsc, mibcPeReader, null, onlyDefinedInAssembly: null); - PrintMibcStats(ParseMibcConfig(tsc, mibcPeReader), profileData); + PrintMibcStats(profileData); using (FileStream outputFile = new FileStream(commandLineOptions.OutputFileName.FullName, FileMode.Create, FileAccess.Write)) { @@ -354,66 +354,37 @@ static int InnerDumpMain(CommandLineOptions commandLineOptions) return 0; } - static MibcConfig ParseMibcConfig(TypeRefTypeSystem.TypeRefTypeSystemContext tsc, params PEReader[] pEReaders) + static MibcConfig ParseMibcConfigsAndMerge(TypeSystemContext tsc, params PEReader[] pEReader) { - MibcConfig mergedConfig = new(); - // When we merge multiple mibc let's just unconditionally pick the first valid MibcConfig - foreach (PEReader peReader in pEReaders) + MibcConfig firstCfg = null; + foreach (PEReader peReader in pEReader) { - EcmaModule mibcModule = EcmaModule.Create(tsc, peReader, null); - EcmaMethod mibcConfigMth = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod(nameof(MibcConfig), null); - if (mibcConfigMth != null) + MibcConfig config = MIbcProfileParser.ParseMibcConfig(tsc, peReader); + if (firstCfg == null) { - var ilBody = EcmaMethodIL.Create(mibcConfigMth); - var ilReader = new ILReader(ilBody.GetILBytes()); - - // Parse: - // - // ldstr "key1" - // ldstr "value1" - // pop - // pop - // ldstr "key2" - // ldstr "value2" - // pop - // pop - // ... - // ret - string fieldName = null; - while (ilReader.HasNext) + firstCfg = config; + } + else + { + if (firstCfg.Runtime != config.Runtime) { - ILOpcode opcode = ilReader.ReadILOpcode(); - switch (opcode) - { - case ILOpcode.ldstr: - var ldStrValue = (string)ilBody.GetObject(ilReader.ReadILToken()); - if (fieldName != null) - { - var field = mergedConfig.GetType().GetField(fieldName); - if (field != null) - { - field.SetValue(mergedConfig, ldStrValue); - } - } - else - { - fieldName = ldStrValue; - } - break; - - case ILOpcode.ret: - case ILOpcode.pop: - fieldName = null; - break; - - default: - throw new InvalidOperationException($"Unexpected opcode: {opcode}"); - } + PrintMessage( + $"Warning: Attempting to merge MIBCs collected on different runtimes: {firstCfg.Runtime} != {config.Runtime}"); + } + if (firstCfg.FormatVersion != config.FormatVersion) + { + PrintMessage( + $"Warning: Attempting to merge MIBCs with different format versions: {firstCfg.FormatVersion} != {config.FormatVersion}"); + } + if (firstCfg.Os != config.Os || + firstCfg.Arch != config.Arch) + { + PrintMessage( + $"Warning: Attempting to merge MIBCs collected on different RIDs: {firstCfg.Os}-{firstCfg.Arch} != {config.Os}-{config.Arch}"); } - break; } } - return mergedConfig; + return firstCfg; } static int InnerMergeMain(CommandLineOptions commandLineOptions) @@ -460,7 +431,7 @@ static int InnerMergeMain(CommandLineOptions commandLineOptions) ProfileData.MergeProfileData(ref partialNgen, mergedProfileData, MIbcProfileParser.ParseMIbcFile(tsc, peReader, assemblyNamesInBubble, onlyDefinedInAssembly: null)); } - MibcConfig mergedConfig = ParseMibcConfig(tsc, mibcReaders); + MibcConfig mergedConfig = ParseMibcConfigsAndMerge(tsc, mibcReaders); int result = MibcEmitter.GenerateMibcFile(mergedConfig, tsc, commandLineOptions.OutputFileName, mergedProfileData.Values, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed); if (result == 0 && commandLineOptions.InheritTimestamp) { @@ -507,10 +478,10 @@ static int InnerCompareMibcMain(CommandLineOptions options) ProfileData profile2 = MIbcProfileParser.ParseMIbcFile(tsc, mibc2, null, onlyDefinedInAssembly: null); PrintOutput($"Comparing {name1} to {name2}"); PrintOutput($"Statistics for {name1}"); - PrintMibcStats(ParseMibcConfig(tsc, mibc1), profile1); + PrintMibcStats(profile1); PrintOutput(""); PrintOutput($"Statistics for {name2}"); - PrintMibcStats(ParseMibcConfig(tsc, mibc2), profile2); + PrintMibcStats(profile2); PrintOutput(""); PrintOutput("Comparison"); @@ -854,9 +825,9 @@ static void PrintLikelihoodHistogram(double[] likelihoods) Console.WriteLine(); } - static void PrintMibcStats(MibcConfig config, ProfileData data) + static void PrintMibcStats(ProfileData data) { - PrintOutput(config.ToString()); + PrintOutput(data.Config?.ToString()); List methods = data.GetAllMethodProfileData().ToList(); List profiledMethods = methods.Where(spd => spd.SchemaData != null).ToList(); PrintOutput($"# Methods: {methods.Count}"); From 0b68488552bd45e4e2eae6abedcace2c2c6d99df Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 20:19:24 +0200 Subject: [PATCH 3/8] Clean up --- src/coreclr/tools/dotnet-pgo/MibcConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs index af6fe0eb57b8b..bbcd507b37d0a 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs @@ -21,6 +21,6 @@ public override string ToString() Os: {Os} Arch: {Arch} - """; ; + """; } } From 17144079e829d8be067b41545a9d27b6baeee10f Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 20:50:49 +0200 Subject: [PATCH 4/8] Fix build --- .../Compiler/ProfileData.cs | 1 - .../IBC/IBCProfileData.cs | 20 +++++++++++++- .../IBC/MIbcProfileParser.cs | 1 - src/coreclr/tools/dotnet-pgo/MibcConfig.cs | 26 ------------------- 4 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 src/coreclr/tools/dotnet-pgo/MibcConfig.cs diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs index 483b612b12ef2..cec289f04bf23 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ProfileData.cs @@ -9,7 +9,6 @@ using Internal.Pgo; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; -using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs index 56af311a68e04..6142314c6d520 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs @@ -5,10 +5,28 @@ using System.Collections.Generic; using Internal.TypeSystem; using System.Linq; -using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler.IBC { + public class MibcConfig + { + public string FormatVersion = "1.0"; + public string Os; + public string Arch; + public string Runtime; + + public override string ToString() + { + return + $""" + FormatVersion: {FormatVersion} + Runtime: {Runtime} + Os: {Os} + Arch: {Arch} + + """; + } + } public class IBCProfileData : ProfileData { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs index ffa7390389a7f..73959d5d1c881 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs @@ -17,7 +17,6 @@ using System.Diagnostics; using System.Reflection.PortableExecutable; -using Microsoft.Diagnostics.Tools.Pgo; namespace ILCompiler.IBC { diff --git a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs b/src/coreclr/tools/dotnet-pgo/MibcConfig.cs deleted file mode 100644 index bbcd507b37d0a..0000000000000 --- a/src/coreclr/tools/dotnet-pgo/MibcConfig.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection; - -namespace Microsoft.Diagnostics.Tools.Pgo; - -public class MibcConfig -{ - public string FormatVersion = "1.0"; - public string Os; - public string Arch; - public string Runtime; - - public override string ToString() - { - return - $""" - FormatVersion: {FormatVersion} - Runtime: {Runtime} - Os: {Os} - Arch: {Arch} - - """; - } -} From 6ebfbcb6035ede6b2e5bfaa97885bb123677fcac Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 21:35:59 +0200 Subject: [PATCH 5/8] Fix restore --- .../tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs index 245c800a7cc4e..b119f3bce5e4f 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs @@ -159,7 +159,7 @@ public ProfileData ParseIBCDataFromModule(EcmaModule ecmaModule) } } - return new IBCProfileData(parsedData.PartialNGen, methodProfileData); + return new IBCProfileData(null, parsedData.PartialNGen, methodProfileData); } public struct IBCBlobKey : IEquatable From 11cab7a18b159a72fa05a44c0f8f22fd9a44f0ad Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 28 Jun 2022 22:53:12 +0200 Subject: [PATCH 6/8] fix crash --- src/coreclr/tools/dotnet-pgo/MibcEmitter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs index c5b528fcbc722..8491a25991c0a 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs @@ -248,7 +248,8 @@ public static int GenerateMibcFile(MibcConfig config, TypeSystemContext tsc, Fil emitter.InjectSystemPrivateCanon(); emitter.AllowUseOfAddGlobalMethod(); - GenerateConfigData(config, emitter); + if (config != null) + GenerateConfigData(config, emitter); SortedDictionary groups = new SortedDictionary(); StringBuilder mibcGroupNameBuilder = new StringBuilder(); From 285eab64b9287b106355e8c1ef351fd18faefc62 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 30 Jun 2022 15:51:13 +0200 Subject: [PATCH 7/8] Get rid of reflection --- .../ILCompiler.ReadyToRun/IBC/IBCProfileData.cs | 16 ++++++++++++++++ .../IBC/MIbcProfileParser.cs | 11 ++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs index 6142314c6d520..266be8710eb0b 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileData.cs @@ -26,6 +26,22 @@ public override string ToString() """; } + + public static MibcConfig FromKeyValueMap(Dictionary kvMap) + { + MibcConfig config = new(); + foreach (var kvPair in kvMap) + { + switch (kvPair.Key) + { + case nameof(FormatVersion): config.FormatVersion = kvPair.Value; break; + case nameof(Os): config.Os = kvPair.Value; break; + case nameof(Arch): config.Arch = kvPair.Value; break; + case nameof(Runtime): config.Runtime = kvPair.Value; break; + } + } + return config; + } } public class IBCProfileData : ProfileData diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs index 73959d5d1c881..b59dee490c6f5 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs @@ -226,7 +226,6 @@ public static ProfileData ParseMIbcFile(TypeSystemContext tsc, PEReader peReader public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReader) { - MibcConfig mergedConfig = new(); // When we merge multiple mibc let's just unconditionally pick the first valid MibcConfig EcmaModule mibcModule = EcmaModule.Create(tsc, pEReader, null); EcmaMethod mibcConfigMth = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod(nameof(MibcConfig), null); @@ -250,6 +249,7 @@ public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReade // ... // ret string fieldName = null; + Dictionary keyValue = new(); while (ilReader.HasNext) { ILOpcode opcode = ilReader.ReadILOpcode(); @@ -259,11 +259,7 @@ public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReade var ldStrValue = (string)ilBody.GetObject(ilReader.ReadILToken()); if (fieldName != null) { - var field = mergedConfig.GetType().GetField(fieldName); - if (field != null) - { - field.SetValue(mergedConfig, ldStrValue); - } + keyValue[fieldName] = ldStrValue; } else { @@ -280,7 +276,8 @@ public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReade throw new InvalidOperationException($"Unexpected opcode: {opcode}"); } } - return mergedConfig; + + return MibcConfig.FromKeyValueMap(keyValue); } enum MibcGroupParseState From 1cf0aef6172531484f1c8aee465c7dac454401b7 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 1 Jul 2022 22:11:53 +0200 Subject: [PATCH 8/8] Address feedback --- src/coreclr/inc/eventtracebase.h | 3 ++- src/coreclr/nativeaot/Runtime/eventtracebase.h | 3 ++- .../tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs | 3 --- src/mono/mono/eventpipe/ep-rt-mono.c | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/coreclr/inc/eventtracebase.h b/src/coreclr/inc/eventtracebase.h index 012af669ac67a..b6a9ec2e2ccfa 100644 --- a/src/coreclr/inc/eventtracebase.h +++ b/src/coreclr/inc/eventtracebase.h @@ -1169,7 +1169,8 @@ namespace ETW typedef enum _Sku { DesktopCLR=0x1, - CoreCLR=0x2 + CoreCLR=0x2, + Mono=0x4 }Sku; typedef enum _EtwMode diff --git a/src/coreclr/nativeaot/Runtime/eventtracebase.h b/src/coreclr/nativeaot/Runtime/eventtracebase.h index 11112593a9e4e..ebac235859313 100644 --- a/src/coreclr/nativeaot/Runtime/eventtracebase.h +++ b/src/coreclr/nativeaot/Runtime/eventtracebase.h @@ -692,7 +692,8 @@ namespace ETW typedef enum _Sku { DesktopCLR=0x1, - CoreCLR=0x2 + CoreCLR=0x2, + Mono=0x4 }Sku; typedef enum _EtwMode diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs index b59dee490c6f5..66dd82173e99d 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IBC/MIbcProfileParser.cs @@ -220,13 +220,10 @@ public static ProfileData ParseMIbcFile(TypeSystemContext tsc, PEReader peReader } return new IBCProfileData(ParseMibcConfig(tsc, peReader), false, loadedMethodProfileData); - - } public static MibcConfig ParseMibcConfig(TypeSystemContext tsc, PEReader pEReader) { - // When we merge multiple mibc let's just unconditionally pick the first valid MibcConfig EcmaModule mibcModule = EcmaModule.Create(tsc, pEReader, null); EcmaMethod mibcConfigMth = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod(nameof(MibcConfig), null); diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 109ecb9e1ea92..9e9cd70dece9d 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -150,7 +150,7 @@ typedef struct _EventPipeSampleProfileStackWalkData { } EventPipeSampleProfileStackWalkData; // Rundown flags. -#define RUNTIME_SKU_CORECLR 0x2 +#define RUNTIME_SKU_MONO 0x4 #define METHOD_FLAGS_DYNAMIC_METHOD 0x1 #define METHOD_FLAGS_GENERIC_METHOD 0x2 #define METHOD_FLAGS_SHARED_GENERIC_METHOD 0x4 @@ -2801,7 +2801,7 @@ ep_rt_mono_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkp FireEtwRuntimeInformationDCStart ( clr_instance_get_id (), - RUNTIME_SKU_CORECLR, + RUNTIME_SKU_MONO, RuntimeProductMajorVersion, RuntimeProductMinorVersion, RuntimeProductPatchVersion,