public static void MergeProfileData(ref bool partialNgen, Dictionary <MethodDesc, MethodProfileData> mergedProfileData, ProfileData profileData) { if (profileData.PartialNGen) { partialNgen = true; } 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>(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); } } }
private void MergeProfileData(ref bool partialNgen, Dictionary<MethodDesc, MethodProfileData> mergedProfileData, ProfileData profileData) { if (profileData.PartialNGen) partialNgen = true; foreach (MethodProfileData data in profileData.GetAllMethodProfileData()) { MethodProfileData dataToMerge; if (mergedProfileData.TryGetValue(data.Method, out dataToMerge)) { mergedProfileData[data.Method] = new MethodProfileData(data.Method, dataToMerge.Flags | data.Flags, dataToMerge.ScenarioMask | data.ScenarioMask); } else { mergedProfileData.Add(data.Method, data); } } }
public void AddCompilationRoots(IRootingServiceProvider rootProvider) { foreach (var methodProfileInfo in _profileData.GetAllMethodProfileData()) { if (!methodProfileInfo.Flags.HasFlag(MethodProfilingDataFlags.ExcludeHotMethodCode) && !methodProfileInfo.Flags.HasFlag(MethodProfilingDataFlags.ExcludeColdMethodCode)) { try { MethodDesc method = methodProfileInfo.Method; CheckCanGenerateMethod(method); rootProvider.AddCompilationRoot(method, "Profile triggered method"); } catch (TypeSystemException) { // Individual methods can fail to load types referenced in their signatures. // Skip them in library mode since they're not going to be callable. continue; } } } if (!_profileData.PartialNGen) { foreach (TypeDesc type in _module.GetAllTypes()) { try { rootProvider.AddCompilationRoot(type, "Library module type"); } catch (TypeSystemException) { // Swallow type load exceptions while rooting continue; } // If this is not a generic definition, root all methods if (!type.HasInstantiation) { RootMethods(type, "Library module method", rootProvider); } } } }
private void MergeProfileData(ref bool partialNgen, Dictionary <MethodDesc, MethodProfileData> mergedProfileData, ProfileData profileData) { if (profileData.PartialNGen) { partialNgen = true; } 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; } } } mergedProfileData[data.Method] = new MethodProfileData(data.Method, dataToMerge.Flags | data.Flags, data.ExclusiveWeight + dataToMerge.ExclusiveWeight, mergedCallWeights, dataToMerge.ScenarioMask | data.ScenarioMask); } else { mergedProfileData.Add(data.Method, data); } } }
public void AddCompilationRoots(IRootingServiceProvider rootProvider) { foreach (var methodProfileInfo in _profileData.GetAllMethodProfileData()) { if (!methodProfileInfo.Flags.HasFlag(MethodProfilingDataFlags.ExcludeHotMethodCode) && !methodProfileInfo.Flags.HasFlag(MethodProfilingDataFlags.ExcludeColdMethodCode)) { try { MethodDesc method = methodProfileInfo.Method; // Validate that this method is fully instantiated if (method.OwningType.IsGenericDefinition || method.OwningType.ContainsSignatureVariables()) { continue; } if (method.IsGenericMethodDefinition) { continue; } bool containsSignatureVariables = false; foreach (TypeDesc t in method.Instantiation) { if (t.IsGenericDefinition) { containsSignatureVariables = true; break; } if (t.ContainsSignatureVariables()) { containsSignatureVariables = true; break; } } if (containsSignatureVariables) { continue; } CheckCanGenerateMethod(method); rootProvider.AddCompilationRoot(method, "Profile triggered method"); } catch (TypeSystemException) { // Individual methods can fail to load types referenced in their signatures. // Skip them in library mode since they're not going to be callable. continue; } } } if (!_profileData.PartialNGen) { foreach (MetadataType type in _module.GetAllTypes()) { try { rootProvider.AddCompilationRoot(type, "Library module type"); } catch (TypeSystemException) { // Swallow type load exceptions while rooting continue; } MetadataType typeWithMethods = type; if (type.HasInstantiation) { typeWithMethods = InstantiateIfPossible(type); if (typeWithMethods == null) { continue; } } RootMethods(typeWithMethods, "Library module method", rootProvider); } } }