Skip to content

Commit

Permalink
Stabilize summary blobs
Browse files Browse the repository at this point in the history
I was trying to repro dotnet#66191 and assumed determinism is the root cause. I used `CoreRT_DeterminismSeed` to perturb the dependency node evaluation and it found differences.

Now, I don't think the differences really matter. We already seem to be deterministic in the multithreaded compilation (the outputs are always the same no matter how many times I try).

`CoreRT_DeterminismSeed` perturbs the order in which node dependencies are evaluated and that exposes more ordering issues than we practically have.

In normal multithreaded compilation we grab nodes in different order from the `NodeFactory` as part of method compilation, but the order in which those nodes are evaluated is still fixed. This means the nodes we grabbed are still getting marked in a deterministic order and we get stable ordering even without an explicit sort in this spot.

But maybe as part of https://github.com/dotnet/runtimelab/issues/1631 we should enable `CoreRT_Determinism` in our testing and for that we need this extra sorting.
  • Loading branch information
MichalStrehovsky committed Mar 24, 2022
1 parent 7508080 commit 5d51a4e
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace ILCompiler.DependencyAnalysis
{
public class CompilerComparer : TypeSystemComparer, IComparer<ISortableNode>
{
public static new CompilerComparer Instance { get; } = new CompilerComparer();

public int Compare(ISortableNode x, ISortableNode y)
{
if (x == y)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;

using Debug = System.Diagnostics.Debug;

namespace Internal.TypeSystem
Expand All @@ -23,8 +25,10 @@ namespace Internal.TypeSystem
// to sort itself with respect to other instances of the same type.
// Comparisons between different categories of types are centralized to a single location that
// can provide rules to sort them.
public class TypeSystemComparer
public class TypeSystemComparer : IComparer<TypeDesc>, IComparer<MethodDesc>, IComparer<FieldDesc>, IComparer<MethodSignature>
{
public static TypeSystemComparer Instance { get; } = new TypeSystemComparer();

public int Compare(TypeDesc x, TypeDesc y)
{
if (x == y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,9 @@ public int GetIdForMethod(MethodDesc dynamicInvokeMethod, NodeFactory factory)

private void BuildMethodToIdMap(NodeFactory factory)
{
// Get a sorted list of generated stubs
List<MethodDesc> methods = new List<MethodDesc>(factory.MetadataManager.GetDynamicInvokeTemplateMethods());

// Sort the stubs
var typeSystemComparer = new TypeSystemComparer();
methods.Sort((first, second) => typeSystemComparer.Compare(first, second));

// Assign each stub an ID
var methodToTemplateIndex = new Dictionary<MethodDesc, int>();
foreach (MethodDesc method in methods)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ internal class InterfaceGVMEntryInfo : TypeGVMEntryInfo
private readonly TypeDesc _associatedType;
private DependencyList _staticDependencies;

public TypeDesc AssociatedType => _associatedType;

public TypeGVMEntriesNode(TypeDesc associatedType)
{
Debug.Assert(associatedType.IsTypeDefinition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,18 @@ public abstract class MetadataManager : ICompilationRootProvider
protected readonly ManifestResourceBlockingPolicy _resourceBlockingPolicy;
protected readonly DynamicInvokeThunkGenerationPolicy _dynamicInvokeThunkGenerationPolicy;

private List<NonGCStaticsNode> _cctorContextsGenerated = new List<NonGCStaticsNode>();
private readonly HashSet<TypeDesc> _typesWithEETypesGenerated = new HashSet<TypeDesc>();
private readonly HashSet<TypeDesc> _typesWithConstructedEETypesGenerated = new HashSet<TypeDesc>();
private HashSet<MethodDesc> _methodsGenerated = new HashSet<MethodDesc>();
private HashSet<MethodDesc> _reflectableMethods = new HashSet<MethodDesc>();
private HashSet<GenericDictionaryNode> _genericDictionariesGenerated = new HashSet<GenericDictionaryNode>();
private HashSet<IMethodBodyNode> _methodBodiesGenerated = new HashSet<IMethodBodyNode>();
private List<TypeGVMEntriesNode> _typeGVMEntries = new List<TypeGVMEntriesNode>();
private HashSet<DefType> _typesWithDelegateMarshalling = new HashSet<DefType>();
private HashSet<DefType> _typesWithStructMarshalling = new HashSet<DefType>();
private HashSet<MethodDesc> _dynamicInvokeTemplates = new HashSet<MethodDesc>();
private readonly SortedSet<NonGCStaticsNode> _cctorContextsGenerated = new SortedSet<NonGCStaticsNode>(CompilerComparer.Instance);
private readonly SortedSet<TypeDesc> _typesWithEETypesGenerated = new SortedSet<TypeDesc>(TypeSystemComparer.Instance);
private readonly SortedSet<TypeDesc> _typesWithConstructedEETypesGenerated = new SortedSet<TypeDesc>(TypeSystemComparer.Instance);
private readonly SortedSet<MethodDesc> _methodsGenerated = new SortedSet<MethodDesc>(TypeSystemComparer.Instance);
private readonly SortedSet<MethodDesc> _reflectableMethods = new SortedSet<MethodDesc>(TypeSystemComparer.Instance);
private readonly SortedSet<GenericDictionaryNode> _genericDictionariesGenerated = new SortedSet<GenericDictionaryNode>(CompilerComparer.Instance);
private readonly SortedSet<IMethodBodyNode> _methodBodiesGenerated = new SortedSet<IMethodBodyNode>(CompilerComparer.Instance);
private readonly SortedSet<TypeGVMEntriesNode> _typeGVMEntries
= new SortedSet<TypeGVMEntriesNode>(Comparer<TypeGVMEntriesNode>.Create((a, b) => TypeSystemComparer.Instance.Compare(a.AssociatedType, b.AssociatedType)));
private readonly SortedSet<DefType> _typesWithDelegateMarshalling = new SortedSet<DefType>(TypeSystemComparer.Instance);
private readonly SortedSet<DefType> _typesWithStructMarshalling = new SortedSet<DefType>(TypeSystemComparer.Instance);
private readonly SortedSet<MethodDesc> _dynamicInvokeTemplates = new SortedSet<MethodDesc>(TypeSystemComparer.Instance);
private HashSet<NativeLayoutTemplateMethodSignatureVertexNode> _templateMethodEntries = new HashSet<NativeLayoutTemplateMethodSignatureVertexNode>();

internal NativeLayoutInfoNode NativeLayoutInfo { get; private set; }
Expand Down

0 comments on commit 5d51a4e

Please sign in to comment.