static int InnerMergeMain(CommandLineOptions commandLineOptions) { if (commandLineOptions.InputFilesToMerge.Count == 0) { PrintUsage(commandLineOptions, "--input must be specified"); return(-8); } if (commandLineOptions.OutputFileName == null) { PrintUsage(commandLineOptions, "--output must be specified"); return(-8); } PEReader[] mibcReaders = new PEReader[commandLineOptions.InputFilesToMerge.Count]; for (int i = 0; i < mibcReaders.Length; i++) { PrintMessage($"Opening {commandLineOptions.InputFilesToMerge[i].FullName}"); mibcReaders[i] = MIbcProfileParser.OpenMibcAsPEReader(commandLineOptions.InputFilesToMerge[i].FullName); } HashSet <string> assemblyNamesInBubble = null; if (commandLineOptions.IncludedAssemblies.Count > 0) { assemblyNamesInBubble = new HashSet <string>(); foreach (var asmName in commandLineOptions.IncludedAssemblies) { assemblyNamesInBubble.Add(asmName.Name); } } try { var tsc = new TypeRefTypeSystem.TypeRefTypeSystemContext(mibcReaders); bool partialNgen = false; Dictionary <MethodDesc, MethodProfileData> mergedProfileData = new Dictionary <MethodDesc, MethodProfileData>(); for (int i = 0; i < mibcReaders.Length; i++) { var peReader = mibcReaders[i]; PrintDetailedMessage($"Merging {commandLineOptions.InputFilesToMerge[i].FullName}"); ProfileData.MergeProfileData(ref partialNgen, mergedProfileData, MIbcProfileParser.ParseMIbcFile(tsc, peReader, assemblyNamesInBubble, onlyDefinedInAssembly: null)); } return(MibcEmitter.GenerateMibcFile(tsc, commandLineOptions.OutputFileName, mergedProfileData.Values, commandLineOptions.ValidateOutputFile, commandLineOptions.Uncompressed)); } finally { foreach (var peReader in mibcReaders) { peReader.Dispose(); } } }
public ProfileDataManager(IEnumerable <string> mibcFiles, CompilerTypeSystemContext context) { List <ProfileData> _inputData = new List <ProfileData>(); foreach (string file in mibcFiles) { using (PEReader peReader = MIbcProfileParser.OpenMibcAsPEReader(file)) { _inputData.Add(MIbcProfileParser.ParseMIbcFile(context, peReader, null, null)); } } bool dummy = false; // Merge all data together foreach (ProfileData profileData in _inputData) { ProfileData.MergeProfileData(ref dummy, _mergedProfileData, profileData); } }
static int ValidateMIbcData(TypeSystemContext tsc, FileInfo outputFileName, byte[] moduleBytes, IEnumerable <MethodProfileData> methodsToAttemptToPrepare) { var peReader = new System.Reflection.PortableExecutable.PEReader(System.Collections.Immutable.ImmutableArray.Create <byte>(moduleBytes)); var profileData = MIbcProfileParser.ParseMIbcFile(tsc, peReader, null, null); Dictionary <MethodDesc, MethodProfileData> mibcDict = new Dictionary <MethodDesc, MethodProfileData>(); foreach (var mibcData in profileData.GetAllMethodProfileData()) { mibcDict.Add((MethodDesc)(object)mibcData.Method, mibcData); } bool failure = false; if (methodsToAttemptToPrepare.Count() != mibcDict.Count) { Program.PrintError($"Not same count of methods {methodsToAttemptToPrepare.Count()} != {mibcDict.Count}"); failure = true; } foreach (var entry in methodsToAttemptToPrepare) { MethodDesc method = entry.Method; if (!mibcDict.ContainsKey(method)) { Program.PrintError($"{method} not found in mibcEntryData"); failure = true; continue; } } if (failure) { return(-1); } else { Program.PrintMessage($"Validated {outputFileName.FullName}"); return(0); } }
public ProfileDataManager(Logger logger, IEnumerable <ModuleDesc> possibleReferenceModules, IEnumerable <ModuleDesc> inputModules, IEnumerable <ModuleDesc> versionBubbleModules, ModuleDesc nonLocalGenericsHome, IReadOnlyList <string> mibcFiles, CallChainProfile callChainProfile, CompilerTypeSystemContext context, ReadyToRunCompilationModuleGroupBase compilationGroup) { _ibcParser = new IBCProfileParser(logger, possibleReferenceModules); _compilationGroup = compilationGroup; _callChainProfile = callChainProfile; HashSet <ModuleDesc> versionBubble = new HashSet <ModuleDesc>(versionBubbleModules); { // Parse MIbc Data string onlyParseItemsDefinedInAssembly = nonLocalGenericsHome == null?inputModules.First().Assembly.GetName().Name : null; HashSet <string> versionBubbleModuleStrings = new HashSet <string>(); foreach (ModuleDesc versionBubbleModule in versionBubble) { versionBubbleModuleStrings.Add(versionBubbleModule.Assembly.GetName().Name); } foreach (string file in mibcFiles) { _inputData.Add(MIbcProfileParser.ParseMIbcFile(context, file, versionBubbleModuleStrings, onlyParseItemsDefinedInAssembly)); } } { // Parse Ibc data foreach (var module in inputModules) { _inputData.Add(_ibcParser.ParseIBCDataFromModule((EcmaModule)module)); _placedProfileMethods.Add(module, new HashSet <MethodDesc>()); } } // Merge all data together foreach (ProfileData profileData in _inputData) { MergeProfileData(ref _partialNGen, _mergedProfileData, profileData); } // With the merged data find the set of methods to be placed within this module foreach (var profileData in _mergedProfileData) { // If the method is not excluded from processing if (!profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeHotMethodCode) && !profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeColdMethodCode)) { // Check for methods which are defined within the version bubble, and only rely on other modules within the bubble if (!_compilationGroup.VersionsWithMethodBody(profileData.Key)) { continue; // Method not contained within version bubble } if (_compilationGroup.ContainsType(profileData.Key.OwningType) && (profileData.Key.OwningType is MetadataType declaringType)) { // In this case the method is placed in its natural home (which is the defining module of the method) _placedProfileMethods[declaringType.Module].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } else { // If the defining module is not within the input set, if the nonLocalGenericsHome is provided, place it there if ((nonLocalGenericsHome != null) && (profileData.Key.GetTypicalMethodDefinition() != profileData.Key)) { _placedProfileMethods[nonLocalGenericsHome].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } } } } }
public ProfileDataManager(Logger logger, IEnumerable <ModuleDesc> possibleReferenceModules, IEnumerable <ModuleDesc> inputModules, IEnumerable <ModuleDesc> versionBubbleModules, IEnumerable <ModuleDesc> crossModuleInlineModules, ModuleDesc nonLocalGenericsHome, IReadOnlyList <string> mibcFiles, MIbcProfileParser.MibcGroupParseRules parseRule, CallChainProfile callChainProfile, CompilerTypeSystemContext context, ReadyToRunCompilationModuleGroupBase compilationGroup, bool embedPgoDataInR2RImage, bool parseIbcData, Func <MethodDesc, bool> canBeIncludedInCurrentCompilation) { EmbedPgoDataInR2RImage = embedPgoDataInR2RImage; _ibcParser = new IBCProfileParser(logger, possibleReferenceModules); _compilationGroup = compilationGroup; _callChainProfile = callChainProfile; HashSet <ModuleDesc> versionBubble = new HashSet <ModuleDesc>(versionBubbleModules); { // Parse MIbc Data string onlyParseItemsDefinedInAssembly = null; if (nonLocalGenericsHome == null && !compilationGroup.IsCompositeBuildMode) { onlyParseItemsDefinedInAssembly = inputModules.First().Assembly.GetName().Name; } HashSet <string> versionBubbleModuleStrings = new HashSet <string>(); foreach (ModuleDesc versionBubbleModule in versionBubble) { versionBubbleModuleStrings.Add(versionBubbleModule.Assembly.GetName().Name); } HashSet <string> crossModuleStrings = new HashSet <string>(); foreach (ModuleDesc crossModule in crossModuleInlineModules) { crossModuleStrings.Add(crossModule.Assembly.GetName().Name); } foreach (string file in mibcFiles) { using (PEReader peReader = MIbcProfileParser.OpenMibcAsPEReader(file)) { _inputData.Add(MIbcProfileParser.ParseMIbcFile(context, peReader, versionBubbleModuleStrings, onlyParseItemsDefinedInAssembly, crossModuleInlineModules: crossModuleStrings, parseRule: parseRule)); } } } if (parseIbcData) { // Parse Ibc data foreach (var module in inputModules) { _inputData.Add(_ibcParser.ParseIBCDataFromModule((EcmaModule)module)); } } // Ensure each module has a hashset of methods available foreach (var module in inputModules) { _placedProfileMethods.Add(module, new HashSet <MethodDesc>()); } // Merge all data together foreach (ProfileData profileData in _inputData) { ProfileData.MergeProfileData(ref _partialNGen, _mergedProfileData, profileData); } // With the merged data find the set of methods to be placed within this module foreach (var profileData in _mergedProfileData) { // If the method is not excluded from processing if (!profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeHotMethodCode) && !profileData.Value.Flags.HasFlag(MethodProfilingDataFlags.ExcludeColdMethodCode)) { // Check for methods which are defined within the version bubble, and only rely on other modules within the bubble if (!_compilationGroup.VersionsWithMethodBody(profileData.Key) && !_compilationGroup.CrossModuleCompileable(profileData.Key)) { continue; // Method not contained within version bubble and not cross module compileable } if (_compilationGroup.ContainsType(profileData.Key.OwningType) && (profileData.Key.OwningType is MetadataType declaringType)) { // In this case the method is placed in its natural home (which is the defining module of the method) _placedProfileMethods[declaringType.Module].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } else { // If the defining module is not within the input set, if the nonLocalGenericsHome is provided, place it there if ((nonLocalGenericsHome != null) && (profileData.Key.GetTypicalMethodDefinition() != profileData.Key)) { _placedProfileMethods[nonLocalGenericsHome].Add(profileData.Key); _placedProfileMethodsAll.Add(profileData.Key); } } } } }