| File: Compiler\ProfileData.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.ReadyToRun\ILCompiler.ReadyToRun.csproj (ILCompiler.ReadyToRun) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using ILCompiler.IBC; using Internal.Pgo; using Internal.TypeSystem; namespace ILCompiler { [Flags] public enum MethodProfilingDataFlags { // Important: update toolbox\ibcmerge\ibcmerge.cs if you change these ReadMethodCode = 0, // 0x00001 // Also means the method was executed ReadMethodDesc = 1, // 0x00002 RunOnceMethod = 2, // 0x00004 RunNeverMethod = 3, // 0x00008 // MethodStoredDataAccess = 4, // 0x00010 // obsolete WriteMethodDesc = 5, // 0x00020 // ReadFCallHash = 6, // 0x00040 // obsolete ReadGCInfo = 7, // 0x00080 CommonReadGCInfo = 8, // 0x00100 // ReadMethodDefRidMap = 9, // 0x00200 // obsolete ReadCerMethodList = 10, // 0x00400 ReadMethodPrecode = 11, // 0x00800 WriteMethodPrecode = 12, // 0x01000 ExcludeHotMethodCode = 13, // 0x02000 // Hot method should be excluded from the ReadyToRun image ExcludeColdMethodCode = 14, // 0x04000 // Cold method should be excluded from the ReadyToRun image DisableInlining = 15, // 0x08000 // Disable inlining of this method in optimized AOT native code } public class MethodProfileData { public MethodProfileData(MethodDesc method, MethodProfilingDataFlags flags, double exclusiveWeight, Dictionary<MethodDesc, int> callWeights, uint scenarioMask, PgoSchemaElem[] schemaData) { #pragma warning disable CA1507 // Use nameof to express symbol names Method = method ?? throw new ArgumentNullException("method"); #pragma warning restore CA1507 // Use nameof to express symbol names Flags = flags; ScenarioMask = scenarioMask; ExclusiveWeight = exclusiveWeight; CallWeights = callWeights; SchemaData = schemaData; } public readonly MethodDesc Method; public readonly MethodProfilingDataFlags Flags; public readonly uint ScenarioMask; public readonly double ExclusiveWeight; public readonly Dictionary<MethodDesc, int> CallWeights; public readonly PgoSchemaElem[] SchemaData; } public abstract class ProfileData { public abstract MibcConfig Config { get; } public abstract bool PartialNGen { get; } public abstract MethodProfileData GetMethodProfileData(MethodDesc m); public abstract IEnumerable<MethodProfileData> GetAllMethodProfileData(); public abstract byte[] GetMethodBlockCount(MethodDesc m); public static void MergeProfileData(Dictionary<MethodDesc, MethodProfileData> mergedProfileData, ProfileData profileData) { PgoSchemaElem[][] schemaElemMergerArray = new PgoSchemaElem[2][]; foreach (MethodProfileData data in profileData.GetAllMethodProfileData()) { MethodProfileData dataToMerge; if (mergedProfileData.TryGetValue(data.Method, out dataToMerge)) { var mergedCallWeights = data.CallWeights; if (mergedCallWeights == null) { mergedCallWeights = dataToMerge.CallWeights; } else if (dataToMerge.CallWeights != null) { mergedCallWeights = new Dictionary<MethodDesc, int>(data.CallWeights); foreach (var entry in dataToMerge.CallWeights) { if (mergedCallWeights.TryGetValue(entry.Key, out var initialWeight)) { mergedCallWeights[entry.Key] = initialWeight + entry.Value; } else { mergedCallWeights[entry.Key] = entry.Value; } } } PgoSchemaElem[] mergedSchemaData; if (data.SchemaData == null) { mergedSchemaData = dataToMerge.SchemaData; } else if (dataToMerge.SchemaData == null) { mergedSchemaData = data.SchemaData; } else { // Actually merge schemaElemMergerArray[0] = dataToMerge.SchemaData; schemaElemMergerArray[1] = data.SchemaData; mergedSchemaData = PgoProcessor.Merge<TypeSystemEntityOrUnknown, TypeSystemEntityOrUnknown>(schemaElemMergerArray); } mergedProfileData[data.Method] = new MethodProfileData(data.Method, dataToMerge.Flags | data.Flags, data.ExclusiveWeight + dataToMerge.ExclusiveWeight, mergedCallWeights, dataToMerge.ScenarioMask | data.ScenarioMask, mergedSchemaData); } else { mergedProfileData.Add(data.Method, data); } } } } public class EmptyProfileData : ProfileData { private static readonly EmptyProfileData s_singleton = new EmptyProfileData(); private EmptyProfileData() { } public override MibcConfig Config { get; } = new(); public override bool PartialNGen => false; public static EmptyProfileData Singleton => s_singleton; public override MethodProfileData GetMethodProfileData(MethodDesc m) { return null; } public override IEnumerable<MethodProfileData> GetAllMethodProfileData() { return Array.Empty<MethodProfileData>(); } public override byte[] GetMethodBlockCount(MethodDesc m) { return null; } } }