Example #1
0
        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();
                }
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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);
                        }
                    }
                }
            }
        }
Example #5
0
        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);
                        }
                    }
                }
            }
        }