Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/BuildIntegration/Microsoft.NETCore.Native.targets1
-rw-r--r--src/Common/src/Internal/Text/Utf8String.cs37
-rw-r--r--src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.cs17
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs5
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DelegateCreationInfo.cs28
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayMapNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedDataNode.cs43
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedPointersNode.cs32
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlobNode.cs10
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlockReflectionTypeMapNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalDefinitionEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClassConstructorContextMap.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClonedConstructedEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CompilerComparer.cs41
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DelegateMarshallingStubMapNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs28
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeOptionalFieldsNode.cs13
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedDataContainerNode.cs36
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedObjectNode.cs19
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedPointerIndirectionNode.cs21
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExactMethodInstantiationsNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternSymbolNode.cs12
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternalReferencesTableNode.cs8
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FatFunctionPointerNode.cs20
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenStringNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticDescNode.cs20
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs16
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsPreInitDataNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericCompositionNode.cs36
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs23
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsTemplateMap.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesHashtableNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IEETypeNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IMethodNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ISymbolNode.cs10
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionNode.cs11
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs8
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs43
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs8
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/LoopHijackFlagNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MetadataNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodAssociatedDataNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodCodeNode.cs14
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ModulesSectionNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutInfoNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs33
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs50
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonGCStaticsNode.cs16
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs12
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeModuleFixupNode.cs8
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs50
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHeaderNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs31
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionVirtualInvokeMapNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceDataNode.cs9
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceIndexNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeDeterminedMethodNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ScannedMethodNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs11
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteUnboxingThunkNode.cs11
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SortableDependencyNode.cs170
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StaticsInfoHashtableNode.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringAllocatorMethodNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StructMarshallingStubMapNode.cs4
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMInitialInterfaceDispatchStubNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsIndexNode.cs24
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsOffsetNode.cs16
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeManagerIndirectionNode.cs5
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataMapNode.cs5
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeThreadStaticIndexNode.cs9
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UnboxingStubNode.cs22
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs10
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcThreadStaticsNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugILImagesSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugManagedNativeDictionaryInfoSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMergedAssemblyRecordsSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodMapSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugNeedTypeIndicesStoreNode.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugPseudoAssemblySection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeRecordsSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeSignatureMapSection.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/ObjectDumper.cs13
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs19
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs2
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj5
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppMethodCodeNode.cs7
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs4
-rw-r--r--src/ILCompiler.DependencyAnalysisFramework/src/DependencyAnalyzer.cs34
-rw-r--r--src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyMethodCodeNode.cs7
-rw-r--r--src/System.Private.Jit/src/System.Private.Jit.csproj1
-rw-r--r--tests/runtest.cmd55
111 files changed, 1234 insertions, 166 deletions
diff --git a/src/BuildIntegration/Microsoft.NETCore.Native.targets b/src/BuildIntegration/Microsoft.NETCore.Native.targets
index 3ad2e68a7..6e522fe48 100644
--- a/src/BuildIntegration/Microsoft.NETCore.Native.targets
+++ b/src/BuildIntegration/Microsoft.NETCore.Native.targets
@@ -106,6 +106,7 @@ See the LICENSE file in the project root for more information.
<IlcArg Condition="$(IlcMultiModule) == 'true'" Include="--multifile" />
<IlcArg Condition="$(Optimize) == 'true'" Include="-O" />
<IlcArg Condition="$(DebugSymbols) == 'true'" Include="-g" />
+ <IlcArg Condition="$(IlcGenerateMapFile) == 'true'" Include="--map:$(NativeIntermediateOutputPath)%(ManagedBinary.Filename).map.xml" />
</ItemGroup>
<MakeDir Directories="$(NativeIntermediateOutputPath)" />
diff --git a/src/Common/src/Internal/Text/Utf8String.cs b/src/Common/src/Internal/Text/Utf8String.cs
index 3587a2c92..47e701350 100644
--- a/src/Common/src/Internal/Text/Utf8String.cs
+++ b/src/Common/src/Internal/Text/Utf8String.cs
@@ -8,7 +8,7 @@ using System.Text;
namespace Internal.Text
{
- public struct Utf8String : IEquatable<Utf8String>
+ public struct Utf8String : IEquatable<Utf8String>, IComparable<Utf8String>
{
private byte[] _value;
@@ -112,5 +112,40 @@ namespace Internal.Text
}
}
}
+
+ private static int Compare(Utf8String strA, Utf8String strB)
+ {
+ int length = Math.Min(strA.Length, strB.Length);
+
+ unsafe
+ {
+ fixed (byte* ap = strA._value)
+ fixed (byte* bp = strB._value)
+ {
+ byte* a = ap;
+ byte* b = bp;
+
+ while (length > 0)
+ {
+ if (*a != *b)
+ return *a - *b;
+ a += 1;
+ b += 1;
+ length -= 1;
+ }
+
+ // At this point, we have compared all the characters in at least one string.
+ // The longer string will be larger.
+ // We could optimize and compare lengths before iterating strings, but we want
+ // Foo and Foo1 to be sorted adjacent to eachother.
+ return strA.Length - strB.Length;
+ }
+ }
+ }
+
+ public int CompareTo(Utf8String other)
+ {
+ return Compare(this, other);
+ }
}
}
diff --git a/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.cs b/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.cs
index 58d7c8c69..342e1f834 100644
--- a/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.cs
+++ b/src/Common/src/TypeSystem/Common/Utilities/GCPointerMap.cs
@@ -13,7 +13,7 @@ namespace Internal.TypeSystem
/// Represents a bitmap of GC pointers within a memory region divided into
/// pointer-sized cells.
/// </summary>
- public partial struct GCPointerMap : IEquatable<GCPointerMap>
+ public partial struct GCPointerMap : IEquatable<GCPointerMap>, IComparable<GCPointerMap>
{
// Each bit in this array represents a pointer-sized cell.
private int[] _gcFlags;
@@ -130,6 +130,21 @@ namespace Internal.TypeSystem
sb.Append(bit ? '1' : '0');
return sb.ToString();
}
+
+ public int CompareTo(GCPointerMap other)
+ {
+ if (_numCells != other._numCells)
+ return _numCells - other._numCells;
+
+ for (int i = 0; i < _gcFlags.Length; i++)
+ {
+ if (_gcFlags[i] != other._gcFlags[i])
+ return _gcFlags[i] - other._gcFlags[i];
+ }
+
+ Debug.Assert(Equals(other));
+ return 0;
+ }
}
/// <summary>
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
index 493883b5d..b93fafd42 100644
--- a/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/CompilationBuilder.cs
@@ -85,10 +85,9 @@ namespace ILCompiler
public abstract CompilationBuilder UseBackendOptions(IEnumerable<string> options);
- protected DependencyAnalyzerBase<NodeFactory> CreateDependencyGraph(NodeFactory factory)
+ protected DependencyAnalyzerBase<NodeFactory> CreateDependencyGraph(NodeFactory factory, IComparer<DependencyNodeCore<NodeFactory>> comparer = null)
{
- // TODO: add graph sorter when we go multi-threaded
- return _dependencyTrackingLevel.CreateDependencyGraph(factory);
+ return _dependencyTrackingLevel.CreateDependencyGraph(factory, comparer);
}
public ILScannerBuilder GetILScannerBuilder(CompilationModuleGroup compilationGroup = null)
diff --git a/src/ILCompiler.Compiler/src/Compiler/DelegateCreationInfo.cs b/src/ILCompiler.Compiler/src/Compiler/DelegateCreationInfo.cs
index f7f1994fd..6fc5afe9f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DelegateCreationInfo.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DelegateCreationInfo.cs
@@ -313,5 +313,33 @@ namespace ILCompiler
{
return Constructor.GetHashCode() ^ TargetMethod.GetHashCode();
}
+
+#if !SUPPORT_JIT
+ internal int CompareTo(DelegateCreationInfo other, TypeSystemComparer comparer)
+ {
+ var compare = _targetKind - other._targetKind;
+ if (compare != 0)
+ return compare;
+
+ compare = comparer.Compare(TargetMethod, other.TargetMethod);
+ if (compare != 0)
+ return compare;
+
+ compare = comparer.Compare(Constructor.Method, other.Constructor.Method);
+ if (compare != 0)
+ return compare;
+
+ if (Thunk == other.Thunk)
+ return 0;
+
+ if (Thunk == null)
+ return -1;
+
+ if (other.Thunk == null)
+ return 1;
+
+ return comparer.Compare(Thunk.Method, other.Thunk.Method);
+ }
+#endif
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayMapNode.cs
index 613cc6358..68da99d9e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayMapNode.cs
@@ -77,5 +77,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedDataNode.cs
index 64936d5fe..927710fad 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedDataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedDataNode.cs
@@ -21,25 +21,18 @@ namespace ILCompiler.DependencyAnalysis
/// by placing a starting symbol, followed by contents of <typeparamref name="TEmbedded"/> nodes (optionally
/// sorted using provided comparer), followed by ending symbol.
/// </summary>
- public class ArrayOfEmbeddedDataNode<TEmbedded> : ObjectNode, IHasStartSymbol
+ public class ArrayOfEmbeddedDataNode<TEmbedded> : EmbeddedDataContainerNode, IHasStartSymbol
where TEmbedded : EmbeddedObjectNode
{
private HashSet<TEmbedded> _nestedNodes = new HashSet<TEmbedded>();
private List<TEmbedded> _nestedNodesList = new List<TEmbedded>();
- private ObjectAndOffsetSymbolNode _startSymbol;
- private ObjectAndOffsetSymbolNode _endSymbol;
private IComparer<TEmbedded> _sorter;
- public ArrayOfEmbeddedDataNode(string startSymbolMangledName, string endSymbolMangledName, IComparer<TEmbedded> nodeSorter)
+ public ArrayOfEmbeddedDataNode(string startSymbolMangledName, string endSymbolMangledName, IComparer<TEmbedded> nodeSorter) : base(startSymbolMangledName, endSymbolMangledName)
{
- _startSymbol = new ObjectAndOffsetSymbolNode(this, 0, startSymbolMangledName, true);
- _endSymbol = new ObjectAndOffsetSymbolNode(this, 0, endSymbolMangledName, true);
_sorter = nodeSorter;
}
-
- public ObjectAndOffsetSymbolNode StartSymbol => _startSymbol;
- public ObjectAndOffsetSymbolNode EndSymbol => _endSymbol;
-
+
public void AddEmbeddedObject(TEmbedded symbol)
{
lock (_nestedNodes)
@@ -52,13 +45,7 @@ namespace ILCompiler.DependencyAnalysis
}
}
- public int IndexOfEmbeddedObject(TEmbedded symbol)
- {
- Debug.Assert(_sorter == null);
- return _nestedNodesList.IndexOf(symbol);
- }
-
- protected override string GetName(NodeFactory factory) => $"Region {_startSymbol.GetMangledName(factory.NameMangler)}";
+ protected override string GetName(NodeFactory factory) => $"Region {StartSymbol.GetMangledName(factory.NameMangler)}";
public override ObjectNodeSection Section => ObjectNodeSection.DataSection;
public override bool IsShareable => false;
@@ -69,10 +56,14 @@ namespace ILCompiler.DependencyAnalysis
protected virtual void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
{
+ int index = 0;
foreach (TEmbedded node in NodesList)
{
if (!relocsOnly)
+ {
node.InitializeOffsetFromBeginningOfArray(builder.CountBytes);
+ node.InitializeIndexFromBeginningOfArray(index++);
+ }
node.EncodeData(ref builder, factory, relocsOnly);
if (node is ISymbolDefinitionNode)
@@ -90,12 +81,12 @@ namespace ILCompiler.DependencyAnalysis
if (_sorter != null)
_nestedNodesList.Sort(_sorter);
- builder.AddSymbol(_startSymbol);
+ builder.AddSymbol(StartSymbol);
GetElementDataForNodes(ref builder, factory, relocsOnly);
- _endSymbol.SetSymbolOffset(builder.CountBytes);
- builder.AddSymbol(_endSymbol);
+ EndSymbol.SetSymbolOffset(builder.CountBytes);
+ builder.AddSymbol(EndSymbol);
ObjectData objData = builder.ToObjectData();
return objData;
@@ -114,15 +105,9 @@ namespace ILCompiler.DependencyAnalysis
return dependencies;
}
- }
- // TODO: delete this once we review each use of this and put it on the generic plan with the
- // right element type
- public class ArrayOfEmbeddedDataNode : ArrayOfEmbeddedDataNode<EmbeddedObjectNode>
- {
- public ArrayOfEmbeddedDataNode(string startSymbolMangledName, string endSymbolMangledName, IComparer<EmbeddedObjectNode> nodeSorter)
- : base(startSymbolMangledName, endSymbolMangledName, nodeSorter)
- {
- }
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedDataNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedPointersNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedPointersNode.cs
index d6d4f3885..45271af23 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedPointersNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfEmbeddedPointersNode.cs
@@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// of node each pointer within the vector points to.
/// </summary>
public sealed class ArrayOfEmbeddedPointersNode<TTarget> : ArrayOfEmbeddedDataNode<EmbeddedPointerIndirectionNode<TTarget>>
- where TTarget : ISymbolNode
+ where TTarget : ISortableSymbolNode
{
private int _nextId;
private string _startSymbolMangledName;
@@ -44,16 +44,15 @@ namespace ILCompiler.DependencyAnalysis
return new EmbeddedPointerIndirectionWithSymbolNode(this, target, GetNextId());
}
- public EmbeddedObjectNode NewNodeWithSymbol(TTarget target, OnMarkedDelegate callback)
- {
- return new EmbeddedPointerIndirectionWithSymbolAndOnMarkedCallbackNode(this, target, GetNextId(), callback);
- }
-
int GetNextId()
{
return System.Threading.Interlocked.Increment(ref _nextId);
}
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedPointersNode;
+
private class PointerIndirectionNodeComparer : IComparer<EmbeddedPointerIndirectionNode<TTarget>>
{
private IComparer<TTarget> _innerComparer;
@@ -96,6 +95,8 @@ namespace ILCompiler.DependencyAnalysis
new DependencyListEntry(_parentNode, "Pointer region")
};
}
+
+ protected internal override int ClassCode => -66002498;
}
private class EmbeddedPointerIndirectionWithSymbolNode : SimpleEmbeddedPointerIndirectionNode, ISymbolDefinitionNode
@@ -113,27 +114,10 @@ namespace ILCompiler.DependencyAnalysis
int ISymbolDefinitionNode.Offset => OffsetFromBeginningOfArray;
- public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(nameMangler.CompilationUnitPrefix).Append(_parentNode._startSymbolMangledName).Append("_").Append(_id.ToStringInvariant());
}
}
-
- private class EmbeddedPointerIndirectionWithSymbolAndOnMarkedCallbackNode : EmbeddedPointerIndirectionWithSymbolNode
- {
- private OnMarkedDelegate _onMarkedCallback;
-
- public EmbeddedPointerIndirectionWithSymbolAndOnMarkedCallbackNode(ArrayOfEmbeddedPointersNode<TTarget> futureParent, TTarget target, int id, OnMarkedDelegate onMarkedCallback)
- : base(futureParent, target, id)
- {
- _onMarkedCallback = onMarkedCallback;
- }
-
- protected override void OnMarked(NodeFactory factory)
- {
- base.OnMarked(factory);
- _onMarkedCallback(this);
- }
- }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs
index 705dc4705..70349bdbf 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ArrayOfFrozenObjectsNode.cs
@@ -41,5 +41,7 @@ namespace ILCompiler.DependencyAnalysis
AlignNextObject(ref builder, factory);
builder.EmitZeroPointer();
}
+
+ protected internal override int ClassCode => -1771336339;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlobNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlobNode.cs
index 1d7afc2e4..5f2b27f5c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlobNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlobNode.cs
@@ -5,6 +5,7 @@
using System;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -39,5 +40,14 @@ namespace ILCompiler.DependencyAnalysis
}
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+#if !SUPPORT_JIT
+ protected internal override int ClassCode => -470351029;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _name.CompareTo(((BlobNode)other)._name);
+ }
+#endif
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlockReflectionTypeMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlockReflectionTypeMapNode.cs
index be1d8e4b5..2955b3d0e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlockReflectionTypeMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/BlockReflectionTypeMapNode.cs
@@ -83,5 +83,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.BlockReflectionTypeMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalDefinitionEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalDefinitionEETypeNode.cs
index bd5bf6e73..520781f53 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalDefinitionEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalDefinitionEETypeNode.cs
@@ -42,5 +42,7 @@ namespace ILCompiler.DependencyAnalysis
// Canonical definition types will have their base size set to the minimum
protected override int BaseSize => MinimumObjectSize;
+
+ protected internal override int ClassCode => -1851030036;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
index 9bd1ad7c1..2383df231 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs
@@ -135,5 +135,7 @@ namespace ILCompiler.DependencyAnalysis
base.ComputeValueTypeFieldPadding();
}
+
+ protected internal override int ClassCode => -1798018602;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClassConstructorContextMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClassConstructorContextMap.cs
index 0165aada1..2ee6b9cf9 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClassConstructorContextMap.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClassConstructorContextMap.cs
@@ -81,5 +81,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ClassConstructorContextMap;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClonedConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClonedConstructedEETypeNode.cs
index 0d7feae9a..d64319e90 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClonedConstructedEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ClonedConstructedEETypeNode.cs
@@ -34,5 +34,7 @@ namespace ILCompiler.DependencyAnalysis
//
objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type));
}
+
+ protected internal override int ClassCode => -288888778;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CompilerComparer.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CompilerComparer.cs
new file mode 100644
index 000000000..5e0139a42
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CompilerComparer.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+
+using Internal.TypeSystem;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public class CompilerComparer : TypeSystemComparer
+ {
+ public int Compare(ISortableSymbolNode x, ISortableSymbolNode y)
+ {
+ if (x == y)
+ {
+ return 0;
+ }
+
+ int codeX = x.ClassCode;
+ int codeY = y.ClassCode;
+ if (codeX == codeY)
+ {
+ Debug.Assert(x.GetType() == y.GetType());
+
+ int result = x.CompareToImpl(y, this);
+
+ // We did a reference equality check above so an "Equal" result is not expected
+ Debug.Assert(result != 0);
+
+ return result;
+ }
+ else
+ {
+ Debug.Assert(x.GetType() != y.GetType());
+ return codeX > codeY ? -1 : 1;
+ }
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
index 0237f9b8b..4bfd1ea7f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs
@@ -198,5 +198,7 @@ namespace ILCompiler.DependencyAnalysis
if (!CreationAllowed(type))
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
}
+
+ protected internal override int ClassCode => 590142654;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs
index 81e8eb38d..417d14e60 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DefaultConstructorMapNode.cs
@@ -74,6 +74,10 @@ namespace ILCompiler.DependencyAnalysis
public override ObjectNodeSection Section => _externalReferences.Section;
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => false;
public override bool StaticDependenciesAreComputed => true;
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.DefaultConstructorMapNode;
+
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DelegateMarshallingStubMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DelegateMarshallingStubMapNode.cs
index c90050a63..11318ad2f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DelegateMarshallingStubMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DelegateMarshallingStubMapNode.cs
@@ -6,6 +6,7 @@ using System;
using Internal.NativeFormat;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -74,5 +75,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.DelegateMarshallingStubMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs
index f914be78b..d18e2eb59 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/DynamicInvokeTemplateDataNode.cs
@@ -122,5 +122,8 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.DynamicInvokeTemplateDataNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
index db578fb17..140aed4e2 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -119,18 +119,13 @@ namespace ILCompiler.DependencyAnalysis
get { return _optionalFieldsBuilder.IsAtLeastOneFieldUsed(); }
}
- internal byte[] GetOptionalFieldsData(NodeFactory factory)
+ internal byte[] GetOptionalFieldsData()
{
return _optionalFieldsBuilder.GetBytes();
}
public override bool StaticDependenciesAreComputed => true;
-
- public void SetDispatchMapIndex(int index)
- {
- _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.DispatchMap, checked((uint)index));
- }
-
+
public static string GetMangledName(TypeDesc type, NameMangler nameMangler)
{
return nameMangler.NodeMangler.EEType(type);
@@ -798,6 +793,11 @@ namespace ILCompiler.DependencyAnalysis
/// </summary>
protected internal virtual void ComputeOptionalEETypeFields(NodeFactory factory, bool relocsOnly)
{
+ if (!relocsOnly && _type.RuntimeInterfaces.Length > 0 && factory.InterfaceDispatchMap(_type).Marked)
+ {
+ _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.DispatchMap, checked((uint)factory.InterfaceDispatchMapIndirection(Type).IndexFromBeginningOfArray));
+ }
+
ComputeRareFlags(factory);
ComputeNullableValueOffset();
if (!relocsOnly)
@@ -1150,6 +1150,20 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ protected internal override int ClassCode => 1521789141;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((EETypeNode)other)._type);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
+
private struct SlotCounter
{
private int _startBytes;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeOptionalFieldsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeOptionalFieldsNode.cs
index 1cf45d914..0cc9ef205 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeOptionalFieldsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeOptionalFieldsNode.cs
@@ -2,7 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+using System.Diagnostics;
+
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -53,10 +57,17 @@ namespace ILCompiler.DependencyAnalysis
if (!relocsOnly)
{
_owner.ComputeOptionalEETypeFields(factory, relocsOnly: false);
- objData.EmitBytes(_owner.GetOptionalFieldsData(factory));
+ objData.EmitBytes(_owner.GetOptionalFieldsData());
}
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => 821718028;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return SortableDependencyNode.CompareImpl(_owner, ((EETypeOptionalFieldsNode)other)._owner, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedDataContainerNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedDataContainerNode.cs
new file mode 100644
index 000000000..bc9d9975d
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedDataContainerNode.cs
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.TypeSystem;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ /// <summary>
+ /// Represents a node that contains a set of embedded objects. The main function is
+ /// to serve as a base class, providing symbol name boundaries and node ordering.
+ /// </summary>
+ public abstract class EmbeddedDataContainerNode : ObjectNode
+ {
+ private ObjectAndOffsetSymbolNode _startSymbol;
+ private ObjectAndOffsetSymbolNode _endSymbol;
+ private string _startSymbolMangledName;
+
+ public ObjectAndOffsetSymbolNode StartSymbol => _startSymbol;
+ public ObjectAndOffsetSymbolNode EndSymbol => _endSymbol;
+
+ protected EmbeddedDataContainerNode(string startSymbolMangledName, string endSymbolMangledName)
+ {
+ _startSymbolMangledName = startSymbolMangledName;
+ _startSymbol = new ObjectAndOffsetSymbolNode(this, 0, startSymbolMangledName, true);
+ _endSymbol = new ObjectAndOffsetSymbolNode(this, 0, endSymbolMangledName, true);
+ }
+
+ protected internal override int ClassCode => -1410622237;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _startSymbolMangledName.CompareTo(((EmbeddedDataContainerNode)other)._startSymbolMangledName);
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedObjectNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedObjectNode.cs
index 3d5c5c310..3ea5ebf83 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedObjectNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedObjectNode.cs
@@ -10,17 +10,19 @@ using Debug = System.Diagnostics.Debug;
namespace ILCompiler.DependencyAnalysis
{
- public abstract class EmbeddedObjectNode : DependencyNodeCore<NodeFactory>
+ public abstract class EmbeddedObjectNode : SortableDependencyNode
{
private const int InvalidOffset = int.MinValue;
private int _offset;
+ private int _index;
public IHasStartSymbol ContainingNode { get; set; }
public EmbeddedObjectNode()
{
_offset = InvalidOffset;
+ _index = InvalidOffset;
}
public int OffsetFromBeginningOfArray
@@ -32,12 +34,27 @@ namespace ILCompiler.DependencyAnalysis
}
}
+ public int IndexFromBeginningOfArray
+ {
+ get
+ {
+ Debug.Assert(_index != InvalidOffset);
+ return _index;
+ }
+ }
+
internal void InitializeOffsetFromBeginningOfArray(int offset)
{
Debug.Assert(_offset == InvalidOffset || _offset == offset);
_offset = offset;
}
+ internal void InitializeIndexFromBeginningOfArray(int index)
+ {
+ Debug.Assert(_index == InvalidOffset || _index == index);
+ _index = index;
+ }
+
public virtual bool IsShareable => false;
public virtual bool RepresentsIndirectionCell => false;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedPointerIndirectionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedPointerIndirectionNode.cs
index 64af3f244..766a73706 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedPointerIndirectionNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EmbeddedPointerIndirectionNode.cs
@@ -5,14 +5,16 @@
using System;
using System.Collections.Generic;
+using Internal.Text;
+
namespace ILCompiler.DependencyAnalysis
{
/// <summary>
/// An <see cref="EmbeddedObjectNode"/> whose sole value is a pointer to a different <see cref="ISymbolNode"/>.
/// <typeparamref name="TTarget"/> represents the node type this pointer points to.
/// </summary>
- public abstract class EmbeddedPointerIndirectionNode<TTarget> : EmbeddedObjectNode
- where TTarget : ISymbolNode
+ public abstract class EmbeddedPointerIndirectionNode<TTarget> : EmbeddedObjectNode, ISortableSymbolNode
+ where TTarget : ISortableSymbolNode
{
private TTarget _targetNode;
@@ -36,5 +38,20 @@ namespace ILCompiler.DependencyAnalysis
// At minimum, Target needs to be reported as a static dependency by inheritors.
public abstract override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory);
+
+ int ISymbolNode.Offset => 0;
+
+ public virtual void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ {
+ sb.Append("_embedded_ptr_");
+ Target.AppendMangledName(nameMangler, sb);
+ }
+
+ int ISortableSymbolNode.ClassCode => -2055384490;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_targetNode, ((EmbeddedPointerIndirectionNode<TTarget>)other)._targetNode);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExactMethodInstantiationsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExactMethodInstantiationsNode.cs
index 4625c6bd3..57313c7a9 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExactMethodInstantiationsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExactMethodInstantiationsNode.cs
@@ -151,5 +151,8 @@ namespace ILCompiler.DependencyAnalysis
return true;
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ExactMethodInstantiationsNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternSymbolNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternSymbolNode.cs
index 2e3de600d..f35a57d1c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternSymbolNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternSymbolNode.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using ILCompiler.DependencyAnalysisFramework;
@@ -13,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a symbol that is defined externally and statically linked to the output obj file.
/// </summary>
- public class ExternSymbolNode : DependencyNodeCore<NodeFactory>, ISymbolNode
+ public class ExternSymbolNode : DependencyNodeCore<NodeFactory>, ISortableSymbolNode
{
private Utf8String _name;
@@ -39,5 +40,14 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
+
+#if !SUPPORT_JIT
+ int ISortableSymbolNode.ClassCode => 1092559304;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return _name.CompareTo(((ExternSymbolNode)other)._name);
+ }
+#endif
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternalReferencesTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternalReferencesTableNode.cs
index 038f643b4..84c17aab5 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternalReferencesTableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ExternalReferencesTableNode.cs
@@ -122,6 +122,14 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ExternalReferencesTableNode;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return string.Compare(_blobName, ((ExternalReferencesTableNode)other)._blobName);
+ }
+
struct SymbolAndDelta : IEquatable<SymbolAndDelta>
{
public readonly ISymbolNode Symbol;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FatFunctionPointerNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FatFunctionPointerNode.cs
index 77d71b6b7..a4127e63d 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FatFunctionPointerNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FatFunctionPointerNode.cs
@@ -78,7 +78,7 @@ namespace ILCompiler.DependencyAnalysis
builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod, _isUnboxingStub));
// Find out what's the context to use
- ISymbolNode contextParameter;
+ ISortableSymbolNode contextParameter;
if (canonMethod.RequiresInstMethodDescArg())
{
contextParameter = factory.MethodGenericDictionary(Method);
@@ -96,5 +96,23 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => 190463489;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ var compare = _isUnboxingStub.CompareTo(((FatFunctionPointerNode)other)._isUnboxingStub);
+ if (compare != 0)
+ return compare;
+
+ return comparer.Compare(Method, ((FatFunctionPointerNode)other).Method);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs
index 0c3cea2f5..23b0992bd 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs
@@ -100,5 +100,12 @@ namespace ILCompiler.DependencyAnalysis
{
factory.FrozenSegmentRegion.AddEmbeddedObject(this);
}
+
+ protected internal override int ClassCode => 1789429316;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _preInitFieldInfo.CompareTo(((FrozenArrayNode)other)._preInitFieldInfo, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenStringNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenStringNode.cs
index e58879302..1fa63fc51 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenStringNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenStringNode.cs
@@ -90,5 +90,12 @@ namespace ILCompiler.DependencyAnalysis
{
factory.FrozenSegmentRegion.AddEmbeddedObject(this);
}
+
+ protected internal override int ClassCode => -1733946122;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return string.CompareOrdinal(_data, ((FrozenStringNode)other)._data);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticDescNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticDescNode.cs
index f38bb7d2c..07d482d3e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticDescNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticDescNode.cs
@@ -170,6 +170,19 @@ namespace ILCompiler.DependencyAnalysis
Debug.Assert(numSeries == NumSeries);
}
+
+ internal int CompareTo(GCStaticDescNode other, TypeSystemComparer comparer)
+ {
+ var compare = _isThreadStatic.CompareTo(other._isThreadStatic);
+ return compare != 0 ? compare : comparer.Compare(_type, other._type);
+ }
+
+ protected internal override int ClassCode => 2142332918;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((GCStaticDescNode)other)._type);
+ }
}
public class GCStaticDescRegionNode : ArrayOfEmbeddedDataNode<GCStaticDescNode>
@@ -232,5 +245,12 @@ namespace ILCompiler.DependencyAnalysis
{
return "Standalone" + _standaloneGCStaticDesc.GetMangledName(context.NameMangler);
}
+
+ protected internal override int ClassCode => 2091208431;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _standaloneGCStaticDesc.CompareTo(((StandaloneGCStaticDescRegionNode)other)._standaloneGCStaticDesc, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs
index 7df1ca127..bea0665cd 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs
@@ -100,5 +100,12 @@ namespace ILCompiler.DependencyAnalysis
return dataBuilder.ToObjectData();
}
+
+ protected internal override int ClassCode => 1304929125;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _gcMap.CompareTo(((GCStaticEETypeNode)other)._gcMap);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs
index 64c99b3b1..7e7432644 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsNode.cs
@@ -12,7 +12,7 @@ using GCStaticRegionConstants = Internal.Runtime.GCStaticRegionConstants;
namespace ILCompiler.DependencyAnalysis
{
- public class GCStaticsNode : ObjectNode, IExportableSymbolNode
+ public class GCStaticsNode : ObjectNode, IExportableSymbolNode, ISortableSymbolNode
{
private MetadataType _type;
private List<PreInitFieldInfo> _preInitFieldInfos;
@@ -129,5 +129,19 @@ namespace ILCompiler.DependencyAnalysis
}
}
}
+
+ protected internal override int ClassCode => -522346696;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((GCStaticsNode)other)._type);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsPreInitDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsPreInitDataNode.cs
index 5f76e5967..653a18fa0 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsPreInitDataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GCStaticsPreInitDataNode.cs
@@ -112,5 +112,12 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => 1148300665;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((GCStaticsPreInitDataNode)other)._type);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericCompositionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericCompositionNode.cs
index 5594f71e9..cff9f3746 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericCompositionNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericCompositionNode.cs
@@ -99,6 +99,12 @@ namespace ILCompiler.DependencyAnalysis
}
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ protected internal override int ClassCode => -762680703;
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _details.CompareToImpl(((GenericCompositionNode)other)._details, comparer);
+ }
}
internal struct GenericCompositionDetails : IEquatable<GenericCompositionDetails>
@@ -174,6 +180,36 @@ namespace ILCompiler.DependencyAnalysis
return true;
}
+ public int CompareToImpl(GenericCompositionDetails other, TypeSystemComparer comparer)
+ {
+ var compare = Instantiation.Length.CompareTo(other.Instantiation.Length);
+ if (compare != 0)
+ return compare;
+
+ if (Variance == null && other.Variance != null)
+ return -1;
+
+ if (Variance != null && other.Variance == null)
+ return 1;
+
+ for (int i = 0; i < Instantiation.Length; i++)
+ {
+ compare = comparer.Compare(Instantiation[i], other.Instantiation[i]);
+ if (compare != 0)
+ return compare;
+
+ if (Variance != null)
+ {
+ compare = Variance[i].CompareTo(other.Variance[i]);
+ if (compare != 0)
+ return compare;
+ }
+ }
+
+ Debug.Assert(Equals(other));
+ return 0;
+ }
+
public override bool Equals(object obj)
{
return obj is GenericCompositionDetails && Equals((GenericCompositionDetails)obj);
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs
index d1b3d7073..d40972210 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDefinitionEETypeNode.cs
@@ -75,5 +75,7 @@ namespace ILCompiler.DependencyAnalysis
return dataBuilder.ToObjectData();
}
+
+ protected internal override int ClassCode => -160325006;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs
index 8e300741d..48b7105ec 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericDictionaryNode.cs
@@ -16,7 +16,7 @@ namespace ILCompiler.DependencyAnalysis
/// at runtime to look up runtime artifacts that depend on the concrete
/// context the generic type or method was instantiated with.
/// </summary>
- public abstract class GenericDictionaryNode : ObjectNode, IExportableSymbolNode
+ public abstract class GenericDictionaryNode : ObjectNode, IExportableSymbolNode, ISortableSymbolNode
{
private readonly NodeFactory _factory;
@@ -85,6 +85,13 @@ namespace ILCompiler.DependencyAnalysis
{
return this.GetMangledName(factory.NameMangler);
}
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
public sealed class TypeGenericDictionaryNode : GenericDictionaryNode
@@ -198,6 +205,13 @@ namespace ILCompiler.DependencyAnalysis
_owningType = owningType;
}
+
+ protected internal override int ClassCode => 889700584;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_owningType, ((TypeGenericDictionaryNode)other)._owningType);
+ }
}
public sealed class MethodGenericDictionaryNode : GenericDictionaryNode
@@ -287,5 +301,12 @@ namespace ILCompiler.DependencyAnalysis
_owningMethod = owningMethod;
}
+
+ protected internal override int ClassCode => -1245704203;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_owningMethod, ((MethodGenericDictionaryNode)other)._owningMethod);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs
index fda2463d4..870f48998 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsHashtableNode.cs
@@ -125,5 +125,8 @@ namespace ILCompiler.DependencyAnalysis
ISymbolNode dictionaryNode = factory.MethodGenericDictionary(method);
dependencies.Add(new DependencyListEntry(dictionaryNode, "GenericMethodsHashtable entry dictionary"));
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.GenericMethodsHashtableNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsTemplateMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsTemplateMap.cs
index daaae6f00..7a92d5dce 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsTemplateMap.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericMethodsTemplateMap.cs
@@ -117,5 +117,8 @@ namespace ILCompiler.DependencyAnalysis
return false;
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.GenericMethodsTemplateMap;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesHashtableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesHashtableNode.cs
index 17602c002..f48ec5dd7 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesHashtableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesHashtableNode.cs
@@ -67,5 +67,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(streamBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.GenericTypesHashtableNode;
}
} \ No newline at end of file
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs
index d6a4b295c..2be294a15 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericTypesTemplateMap.cs
@@ -159,5 +159,8 @@ namespace ILCompiler.DependencyAnalysis
return false;
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.GenericTypesTemplateMap;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs
index 9910403eb..7e7e582a4 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/GenericVirtualMethodTableNode.cs
@@ -144,5 +144,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(streamBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.GenericVirtualMethodTableNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IEETypeNode.cs
index 6da67b63a..4aee5b975 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IEETypeNode.cs
@@ -9,7 +9,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// A dependency analysis node that represents a runtime type data structure.
/// </summary>
- public interface IEETypeNode : ISymbolNode
+ public interface IEETypeNode : ISortableSymbolNode
{
TypeDesc Type { get; }
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IMethodNode.cs
index be4edd793..393ee4adf 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IMethodNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IMethodNode.cs
@@ -9,7 +9,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// A dependency analysis node that represents a method.
/// </summary>
- public interface IMethodNode : ISymbolNode
+ public interface IMethodNode : ISortableSymbolNode
{
MethodDesc Method { get; }
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ISymbolNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ISymbolNode.cs
index 7cfaf2344..af38e11d6 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ISymbolNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ISymbolNode.cs
@@ -32,6 +32,16 @@ namespace ILCompiler.DependencyAnalysis
bool RepresentsIndirectionCell { get; }
}
+
+ public interface ISortableSymbolNode : ISymbolNode
+ {
+#if !SUPPORT_JIT
+ int ClassCode { get; }
+ int CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer);
+#endif
+ }
+
+
/// <summary>
/// Represents a definition of a symbol within an <see cref="ObjectNode"/>. The symbol will be defined
/// at the specified offset from the beginning of the <see cref="ObjectNode"/> that reports this as one of
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionNode.cs
index b62b4a511..77bd897ea 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/IndirectionNode.cs
@@ -14,11 +14,11 @@ namespace ILCompiler.DependencyAnalysis
/// </summary>
public class IndirectionNode : ObjectNode, ISymbolDefinitionNode
{
- private ISymbolNode _indirectedNode;
+ private ISortableSymbolNode _indirectedNode;
private int _offsetDelta;
private TargetDetails _target;
- public IndirectionNode(TargetDetails target, ISymbolNode indirectedNode, int offsetDelta)
+ public IndirectionNode(TargetDetails target, ISortableSymbolNode indirectedNode, int offsetDelta)
{
_indirectedNode = indirectedNode;
_offsetDelta = offsetDelta;
@@ -60,5 +60,12 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => -1401349230;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(this._indirectedNode, ((IndirectionNode)other)._indirectedNode);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs
index dd18ffaff..9a4c0fd9c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs
@@ -114,5 +114,13 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -2023802120;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ var compare = comparer.Compare(_targetMethod, ((InterfaceDispatchCellNode)other)._targetMethod);
+ return compare != 0 ? compare : string.Compare(_callSiteIdentifier, ((InterfaceDispatchCellNode)other)._callSiteIdentifier);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
index d49256a05..e2f6a6535 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceDispatchMapNode.cs
@@ -11,29 +11,20 @@ using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
- public class InterfaceDispatchMapNode : ObjectNode, ISymbolDefinitionNode
+ public class InterfaceDispatchMapNode : ObjectNode, ISymbolDefinitionNode, ISortableSymbolNode
{
- const int IndexNotSet = int.MaxValue;
-
- int _dispatchMapTableIndex;
TypeDesc _type;
public InterfaceDispatchMapNode(TypeDesc type)
{
_type = type;
- _dispatchMapTableIndex = IndexNotSet;
}
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
- if (_dispatchMapTableIndex == IndexNotSet)
- {
- throw new InvalidOperationException("MangledName called before InterfaceDispatchMap index was initialized.");
- }
-
- sb.Append(nameMangler.CompilationUnitPrefix).Append("__InterfaceDispatchMap_").Append(_dispatchMapTableIndex.ToStringInvariant());
+ sb.Append(nameMangler.CompilationUnitPrefix).Append("__InterfaceDispatchMap_").Append(nameMangler.SanitizeName(nameMangler.GetMangledTypeName(_type)));
}
public int Offset => 0;
@@ -51,21 +42,7 @@ namespace ILCompiler.DependencyAnalysis
return ObjectNodeSection.DataSection;
}
}
-
- public void SetDispatchMapIndex(NodeFactory factory, int index)
- {
- _dispatchMapTableIndex = index;
- IEETypeNode eeTypeNode = factory.ConstructedTypeSymbol(_type);
-
- if (eeTypeNode is ImportedEETypeSymbolNode)
- {
- Debug.Assert(_type == factory.TypeSystemContext.GetWellKnownType(WellKnownType.String));
- eeTypeNode = factory.ConstructedClonedTypeSymbol(_type);
- }
-
- ((EETypeNode)eeTypeNode).SetDispatchMapIndex(_dispatchMapTableIndex);
- }
-
+
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
{
var result = new DependencyList();
@@ -125,5 +102,19 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => 848664602;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((InterfaceDispatchMapNode)other)._type);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs
index f6cef6f8c..3fd60f7bd 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/InterfaceGenericVirtualMethodTableNode.cs
@@ -213,5 +213,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(streamBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.InterfaceGenericVirtualMethodTableNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs
index 6c8c687d9..abc13496c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs
@@ -2,12 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
-using Internal.TypeSystem;
-
-using Internal.Text;
-
namespace ILCompiler.DependencyAnalysis
{
public abstract partial class JumpStubNode : AssemblyStubNode
@@ -28,5 +22,7 @@ namespace ILCompiler.DependencyAnalysis
}
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ protected internal override int ClassCode => 737788182;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/LoopHijackFlagNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/LoopHijackFlagNode.cs
index 843d58358..69b1bd764 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/LoopHijackFlagNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/LoopHijackFlagNode.cs
@@ -35,6 +35,8 @@ namespace ILCompiler.DependencyAnalysis
public override bool StaticDependenciesAreComputed => true;
+ protected internal override int ClassCode => -266743363;
+
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
// Emit a 4-byte integer flag with initial value of 0.
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MetadataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MetadataNode.cs
index 559fe5210..46bb90e09 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MetadataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MetadataNode.cs
@@ -5,6 +5,7 @@
using System;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -57,5 +58,8 @@ namespace ILCompiler.DependencyAnalysis
_endSymbol
});
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.MetadataNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodAssociatedDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodAssociatedDataNode.cs
index bfa57cfa3..46dacad9e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodAssociatedDataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodAssociatedDataNode.cs
@@ -41,6 +41,13 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
public override bool IsShareable => _methodNode.Method is InstantiatedMethod || EETypeNode.IsTypeNodeShareable(_methodNode.Method.OwningType);
+ protected internal override int ClassCode => 1055183914;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_methodNode, ((MethodAssociatedDataNode)other)._methodNode);
+ }
+
public virtual void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append("_associatedData_").Append(nameMangler.GetMangledMethodName(_methodNode.Method));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodCodeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodCodeNode.cs
index 228cf2401..69832904e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodCodeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/MethodCodeNode.cs
@@ -152,5 +152,19 @@ namespace ILCompiler.DependencyAnalysis
Debug.Assert(_debugVarInfos == null);
_debugVarInfos = debugVarInfos;
}
+
+ protected internal override int ClassCode => 788492407;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_method, ((MethodCodeNode)other)._method);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ModulesSectionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ModulesSectionNode.cs
index 544bcc2ec..ed629af32 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ModulesSectionNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ModulesSectionNode.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+
using Internal.Text;
using Internal.TypeSystem;
@@ -52,5 +54,7 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -1225116970;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutInfoNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutInfoNode.cs
index 2d029ae06..bed4f3fe4 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutInfoNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutInfoNode.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using Internal.Text;
using Internal.NativeFormat;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -93,5 +94,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(_writerSavedBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.NativeLayoutInfoNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs
index 6c593d929..2c1dd5f4d 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NativeLayoutSignatureNode.cs
@@ -84,5 +84,38 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => 1887049331;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ NativeLayoutSignatureNode otherSignature = (NativeLayoutSignatureNode)other;
+ if (_identity is MethodDesc)
+ {
+ if (otherSignature._identity is TypeDesc || otherSignature._identity is FieldDesc)
+ return -1;
+ return comparer.Compare((MethodDesc)_identity, (MethodDesc)((NativeLayoutSignatureNode)other)._identity);
+ }
+ else if (_identity is TypeDesc)
+ {
+ if (otherSignature._identity is MethodDesc)
+ return 1;
+
+ if (otherSignature._identity is FieldDesc)
+ return -1;
+
+ return comparer.Compare((TypeDesc)_identity, (TypeDesc)((NativeLayoutSignatureNode)other)._identity);
+ }
+ else if (_identity is FieldDesc)
+ {
+ if (otherSignature._identity is MethodDesc || otherSignature._identity is TypeDesc)
+ return 1;
+ return comparer.Compare((FieldDesc)_identity, (FieldDesc)((NativeLayoutSignatureNode)other)._identity);
+ }
+ else
+ {
+ throw new NotSupportedException("New type system entity needs a comparison");
+ }
+ }
}
} \ No newline at end of file
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs
index 022225777..2a72b509b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NecessaryCanonicalEETypeNode.cs
@@ -9,7 +9,7 @@ using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
- /// <summary>
+ /// <summary>
/// The node is used in ProjectX to represent a canonical type that does not have a vtable.
/// </summary>
internal sealed class NecessaryCanonicalEETypeNode : EETypeNode
@@ -26,5 +26,7 @@ namespace ILCompiler.DependencyAnalysis
{
return _type.BaseType != null ? factory.NecessaryTypeSymbol(GetFullCanonicalTypeForCanonicalType(_type.BaseType)) : null;
}
+
+ protected internal override int ClassCode => 1505000724;
}
} \ No newline at end of file
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
index 978d5a5db..6cde0dc8e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -214,7 +214,7 @@ namespace ILCompiler.DependencyAnalysis
return new ImportedEETypeSymbolNode(this, type);
});
- _nonGCStatics = new NodeCache<MetadataType, ISymbolNode>((MetadataType type) =>
+ _nonGCStatics = new NodeCache<MetadataType, ISortableSymbolNode>((MetadataType type) =>
{
if (_compilationModuleGroup.ContainsType(type))
{
@@ -230,7 +230,7 @@ namespace ILCompiler.DependencyAnalysis
}
});
- _GCStatics = new NodeCache<MetadataType, ISymbolNode>((MetadataType type) =>
+ _GCStatics = new NodeCache<MetadataType, ISortableSymbolNode>((MetadataType type) =>
{
if (_compilationModuleGroup.ContainsType(type))
{
@@ -362,7 +362,7 @@ namespace ILCompiler.DependencyAnalysis
return new ReadyToRunGenericLookupFromTypeNode(this, data.HelperId, data.Target, data.DictionaryOwner);
});
- _indirectionNodes = new NodeCache<ISymbolNode, ISymbolNode>(indirectedNode =>
+ _indirectionNodes = new NodeCache<ISortableSymbolNode, ISymbolNode>(indirectedNode =>
{
return new IndirectionNode(Target, indirectedNode, 0);
});
@@ -399,11 +399,7 @@ namespace ILCompiler.DependencyAnalysis
_interfaceDispatchMapIndirectionNodes = new NodeCache<TypeDesc, EmbeddedObjectNode>((TypeDesc type) =>
{
- var dispatchMap = InterfaceDispatchMap(type);
- return DispatchMapTable.NewNodeWithSymbol(dispatchMap, (indirectionNode) =>
- {
- dispatchMap.SetDispatchMapIndex(this, DispatchMapTable.IndexOfEmbeddedObject(indirectionNode));
- });
+ return DispatchMapTable.NewNodeWithSymbol(InterfaceDispatchMap(type));
});
_genericCompositions = new NodeCache<GenericCompositionDetails, GenericCompositionNode>((GenericCompositionDetails details) =>
@@ -431,7 +427,7 @@ namespace ILCompiler.DependencyAnalysis
return _vtableSliceProvider.GetSlice(type);
});
- _methodGenericDictionaries = new NodeCache<MethodDesc, ISymbolNode>(method =>
+ _methodGenericDictionaries = new NodeCache<MethodDesc, ISortableSymbolNode>(method =>
{
if (CompilationModuleGroup.ContainsMethodDictionary(method))
{
@@ -443,7 +439,7 @@ namespace ILCompiler.DependencyAnalysis
}
});
- _typeGenericDictionaries = new NodeCache<TypeDesc, ISymbolNode>(type =>
+ _typeGenericDictionaries = new NodeCache<TypeDesc, ISortableSymbolNode>(type =>
{
if (CompilationModuleGroup.ContainsType(type))
{
@@ -560,17 +556,17 @@ namespace ILCompiler.DependencyAnalysis
return _importedTypeSymbols.GetOrAdd(type);
}
- private NodeCache<MetadataType, ISymbolNode> _nonGCStatics;
+ private NodeCache<MetadataType, ISortableSymbolNode> _nonGCStatics;
- public ISymbolNode TypeNonGCStaticsSymbol(MetadataType type)
+ public ISortableSymbolNode TypeNonGCStaticsSymbol(MetadataType type)
{
Debug.Assert(!TypeCannotHaveEEType(type));
return _nonGCStatics.GetOrAdd(type);
}
- private NodeCache<MetadataType, ISymbolNode> _GCStatics;
+ private NodeCache<MetadataType, ISortableSymbolNode> _GCStatics;
- public ISymbolNode TypeGCStaticsSymbol(MetadataType type)
+ public ISortableSymbolNode TypeGCStaticsSymbol(MetadataType type)
{
Debug.Assert(!TypeCannotHaveEEType(type));
return _GCStatics.GetOrAdd(type);
@@ -673,7 +669,7 @@ namespace ILCompiler.DependencyAnalysis
private NodeCache<string, ExternSymbolNode> _externSymbols;
- public ISymbolNode ExternSymbol(string name)
+ public ISortableSymbolNode ExternSymbol(string name)
{
return _externSymbols.GetOrAdd(name);
}
@@ -699,14 +695,14 @@ namespace ILCompiler.DependencyAnalysis
return _vTableNodes.GetOrAdd(type);
}
- private NodeCache<MethodDesc, ISymbolNode> _methodGenericDictionaries;
- public ISymbolNode MethodGenericDictionary(MethodDesc method)
+ private NodeCache<MethodDesc, ISortableSymbolNode> _methodGenericDictionaries;
+ public ISortableSymbolNode MethodGenericDictionary(MethodDesc method)
{
return _methodGenericDictionaries.GetOrAdd(method);
}
- private NodeCache<TypeDesc, ISymbolNode> _typeGenericDictionaries;
- public ISymbolNode TypeGenericDictionary(TypeDesc type)
+ private NodeCache<TypeDesc, ISortableSymbolNode> _typeGenericDictionaries;
+ public ISortableSymbolNode TypeGenericDictionary(TypeDesc type)
{
return _typeGenericDictionaries.GetOrAdd(type);
}
@@ -902,9 +898,9 @@ namespace ILCompiler.DependencyAnalysis
return _genericReadyToRunHelpersFromType.GetOrAdd(new ReadyToRunGenericHelperKey(id, target, dictionaryOwner));
}
- private NodeCache<ISymbolNode, ISymbolNode> _indirectionNodes;
+ private NodeCache<ISortableSymbolNode, ISymbolNode> _indirectionNodes;
- public ISymbolNode Indirection(ISymbolNode symbol)
+ public ISymbolNode Indirection(ISortableSymbolNode symbol)
{
if (symbol.RepresentsIndirectionCell)
{
@@ -997,13 +993,13 @@ namespace ILCompiler.DependencyAnalysis
public ArrayOfEmbeddedPointersNode<GCStaticsNode> GCStaticsRegion = new ArrayOfEmbeddedPointersNode<GCStaticsNode>(
"__GCStaticRegionStart",
- "__GCStaticRegionEnd",
- null);
+ "__GCStaticRegionEnd",
+ new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()));
- public ArrayOfEmbeddedDataNode ThreadStaticsRegion = new ArrayOfEmbeddedDataNode(
+ public ArrayOfEmbeddedDataNode<ThreadStaticsNode> ThreadStaticsRegion = new ArrayOfEmbeddedDataNode<ThreadStaticsNode>(
"__ThreadStaticRegionStart",
"__ThreadStaticRegionEnd",
- null);
+ new SortableDependencyNode.EmbeddedObjectNodeComparer(new CompilerComparer()));
public ArrayOfEmbeddedPointersNode<IMethodNode> EagerCctorTable = new ArrayOfEmbeddedPointersNode<IMethodNode>(
"__EagerCctorStart",
@@ -1013,12 +1009,12 @@ namespace ILCompiler.DependencyAnalysis
public ArrayOfEmbeddedPointersNode<InterfaceDispatchMapNode> DispatchMapTable = new ArrayOfEmbeddedPointersNode<InterfaceDispatchMapNode>(
"__DispatchMapTableStart",
"__DispatchMapTableEnd",
- null);
+ new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer()));
public ArrayOfEmbeddedDataNode<EmbeddedObjectNode> FrozenSegmentRegion = new ArrayOfFrozenObjectsNode<EmbeddedObjectNode>(
"__FrozenSegmentRegionStart",
"__FrozenSegmentRegionEnd",
- null);
+ new SortableDependencyNode.EmbeddedObjectNodeComparer(new CompilerComparer()));
public ReadyToRunHeaderNode ReadyToRunHeader;
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonGCStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonGCStaticsNode.cs
index 7feef9bba..5e271e53b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonGCStaticsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NonGCStaticsNode.cs
@@ -18,7 +18,7 @@ namespace ILCompiler.DependencyAnalysis
/// with the class constructor context if the type has a class constructor that
/// needs to be triggered before the type members can be accessed.
/// </summary>
- public class NonGCStaticsNode : ObjectNode, IExportableSymbolNode
+ public class NonGCStaticsNode : ObjectNode, IExportableSymbolNode, ISortableSymbolNode
{
private MetadataType _type;
private NodeFactory _factory;
@@ -177,5 +177,19 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => -1173104872;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((NonGCStaticsNode)other)._type);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectNode.cs
index 09610d9d3..6dcf96ae8 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ObjectNode.cs
@@ -4,11 +4,13 @@
using System;
using System.Collections.Generic;
+
using ILCompiler.DependencyAnalysisFramework;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
- public abstract class ObjectNode : DependencyNodeCore<NodeFactory>
+ public abstract partial class ObjectNode : SortableDependencyNode
{
public class ObjectData
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs
index ef1dc0aa8..797032e3e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeMethodFixupNode.cs
@@ -5,6 +5,7 @@
using System;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -73,5 +74,16 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => -1592006940;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ var compare = string.Compare(_moduleName, ((PInvokeMethodFixupNode)other)._moduleName);
+ if (compare != 0)
+ return compare;
+
+ return string.Compare(_entryPointName, ((PInvokeMethodFixupNode)other)._entryPointName);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeModuleFixupNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeModuleFixupNode.cs
index 939e2b037..bf83f13b1 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeModuleFixupNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/PInvokeModuleFixupNode.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -48,5 +49,12 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => 159930099;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return string.Compare(_moduleName, ((PInvokeModuleFixupNode)other)._moduleName);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs
index 99e717c40..d07760db4 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunGenericHelperNode.cs
@@ -206,6 +206,52 @@ namespace ILCompiler.DependencyAnalysis
return conditionalDependencies;
}
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ var compare = _id.CompareTo(((ReadyToRunGenericHelperNode)other)._id);
+ if (compare != 0)
+ return compare;
+
+ if (_dictionaryOwner is MethodDesc)
+ {
+ if (((ReadyToRunGenericHelperNode)other)._dictionaryOwner is TypeDesc)
+ return -1;
+
+ compare = comparer.Compare((MethodDesc)_dictionaryOwner, (MethodDesc)((ReadyToRunGenericHelperNode)other)._dictionaryOwner);
+ }
+ else
+ {
+ if (((ReadyToRunGenericHelperNode)other)._dictionaryOwner is MethodDesc)
+ return 1;
+
+ compare = comparer.Compare((TypeDesc)_dictionaryOwner, (TypeDesc)((ReadyToRunGenericHelperNode)other)._dictionaryOwner);
+ }
+
+ if (compare != 0)
+ return compare;
+
+ switch (_id)
+ {
+ case ReadyToRunHelperId.TypeHandle:
+ case ReadyToRunHelperId.GetGCStaticBase:
+ case ReadyToRunHelperId.GetNonGCStaticBase:
+ case ReadyToRunHelperId.GetThreadStaticBase:
+ case ReadyToRunHelperId.DefaultConstructor:
+ return comparer.Compare((TypeDesc)_target, (TypeDesc)((ReadyToRunGenericHelperNode)other)._target);
+ case ReadyToRunHelperId.MethodHandle:
+ case ReadyToRunHelperId.MethodDictionary:
+ case ReadyToRunHelperId.VirtualDispatchCell:
+ case ReadyToRunHelperId.MethodEntry:
+ return comparer.Compare((MethodDesc)_target, (MethodDesc)((ReadyToRunGenericHelperNode)other)._target);
+ case ReadyToRunHelperId.FieldHandle:
+ return comparer.Compare((FieldDesc)_target, (FieldDesc)((ReadyToRunGenericHelperNode)other)._target);
+ case ReadyToRunHelperId.DelegateCtor:
+ return ((DelegateCreationInfo)_target).CompareTo((DelegateCreationInfo)((ReadyToRunGenericHelperNode)other)._target, comparer);
+ default:
+ throw new NotImplementedException();
+ }
+ }
}
public partial class ReadyToRunGenericLookupFromDictionaryNode : ReadyToRunGenericHelperNode
@@ -226,6 +272,8 @@ namespace ILCompiler.DependencyAnalysis
sb.Append("__GenericLookupFromDict_").Append(mangledContextName).Append("_");
AppendLookupSignatureMangledName(nameMangler, sb);
}
+
+ protected internal override int ClassCode => 1055354299;
}
public partial class ReadyToRunGenericLookupFromTypeNode : ReadyToRunGenericHelperNode
@@ -246,5 +294,7 @@ namespace ILCompiler.DependencyAnalysis
sb.Append("__GenericLookupFromType_").Append(mangledContextName).Append("_");
AppendLookupSignatureMangledName(nameMangler, sb);
}
+
+ protected internal override int ClassCode => 913214059;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHeaderNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHeaderNode.cs
index f54e71e70..6c2fd6d73 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHeaderNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHeaderNode.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using Internal.Runtime;
@@ -126,5 +127,7 @@ namespace ILCompiler.DependencyAnalysis
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => -534800244;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs
index 94671a88f..6bcbd7aeb 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReadyToRunHelperNode.cs
@@ -188,5 +188,36 @@ namespace ILCompiler.DependencyAnalysis
return null;
}
+
+#if !SUPPORT_JIT
+ protected internal override int ClassCode => -911637948;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ var compare = _id.CompareTo(((ReadyToRunHelperNode)other)._id);
+ if (compare != 0)
+ return compare;
+
+ switch (_id)
+ {
+ case ReadyToRunHelperId.NewHelper:
+ case ReadyToRunHelperId.NewArr1:
+ case ReadyToRunHelperId.IsInstanceOf:
+ case ReadyToRunHelperId.CastClass:
+ case ReadyToRunHelperId.GetNonGCStaticBase:
+ case ReadyToRunHelperId.GetGCStaticBase:
+ case ReadyToRunHelperId.GetThreadStaticBase:
+ return comparer.Compare((TypeDesc)_target, (TypeDesc)((ReadyToRunHelperNode)other)._target);
+ case ReadyToRunHelperId.VirtualCall:
+ case ReadyToRunHelperId.ResolveVirtualFunction:
+ return comparer.Compare((MethodDesc)_target, (MethodDesc)((ReadyToRunHelperNode)other)._target);
+ case ReadyToRunHelperId.DelegateCtor:
+ return ((DelegateCreationInfo)_target).CompareTo((DelegateCreationInfo)((ReadyToRunHelperNode)other)._target, comparer);
+ default:
+ throw new NotImplementedException();
+ }
+
+ }
+#endif
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs
index bdcfa44cd..9705515b6 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionFieldMapNode.cs
@@ -228,5 +228,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ReflectionFieldMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs
index d58053e77..2d92af22a 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionInvokeMapNode.cs
@@ -194,5 +194,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ReflectionInvokeMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionVirtualInvokeMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionVirtualInvokeMapNode.cs
index c2d9617bb..00b1e9739 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionVirtualInvokeMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ReflectionVirtualInvokeMapNode.cs
@@ -241,5 +241,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ReflectionVirtualInvokeMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceDataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceDataNode.cs
index 8ee203e1a..9ff7a7243 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceDataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceDataNode.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Internal.Text;
-using Internal.TypeSystem.Ecma;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -11,6 +9,10 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
+using Internal.Text;
+using Internal.TypeSystem;
+using Internal.TypeSystem.Ecma;
+
namespace ILCompiler.DependencyAnalysis
{
/// <summary>
@@ -141,6 +143,9 @@ namespace ILCompiler.DependencyAnalysis
_endSymbol.SetSymbolOffset(resourceBlob.Length);
return resourceBlob;
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ResourceDataNode;
}
/// <summary>
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceIndexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceIndexNode.cs
index 175b101f1..053a3112b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceIndexNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ResourceIndexNode.cs
@@ -6,6 +6,7 @@ using System;
using Internal.NativeFormat;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -96,5 +97,8 @@ namespace ILCompiler.DependencyAnalysis
_endSymbol.SetSymbolOffset(blob.Length);
return blob;
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.ResourceIndexNode;
}
} \ No newline at end of file
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeDeterminedMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeDeterminedMethodNode.cs
index 83bd6b0b7..d3a3672ea 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeDeterminedMethodNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeDeterminedMethodNode.cs
@@ -61,5 +61,12 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
+
+ int ISortableSymbolNode.ClassCode => 258139501;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_canonicalMethodNode, ((RuntimeDeterminedMethodNode)other)._canonicalMethodNode);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs
index 7d47a0afa..c1285477f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs
@@ -63,5 +63,12 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -1326215725;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_targetField, ((RuntimeFieldHandleNode)other)._targetField);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs
index 920947aba..79bf416c3 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs
@@ -76,5 +76,12 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -274400625;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_targetMethod, ((RuntimeMethodHandleNode)other)._targetMethod);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ScannedMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ScannedMethodNode.cs
index f37857ee6..43d27c344 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ScannedMethodNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ScannedMethodNode.cs
@@ -62,5 +62,12 @@ namespace ILCompiler.DependencyAnalysis
public override bool InterestingForDynamicDependencyAnalysis => false;
public override bool HasDynamicDependencies => false;
public override bool HasConditionalStaticDependencies => false;
+
+ int ISortableSymbolNode.ClassCode => -1381809560;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(Method, ((ScannedMethodNode)other).Method);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs
index 43c1f4adf..40d7cc978 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteMethodNode.cs
@@ -98,5 +98,16 @@ namespace ILCompiler.DependencyAnalysis
public sealed override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
public sealed override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
+
+ int ISortableSymbolNode.ClassCode => -1440570971;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ var compare = comparer.Compare(Method, ((ShadowConcreteMethodNode)other).Method);
+ if (compare != 0)
+ return compare;
+
+ return comparer.Compare(CanonicalMethodNode, ((ShadowConcreteMethodNode)other).CanonicalMethodNode);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteUnboxingThunkNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteUnboxingThunkNode.cs
index ae9f233d6..fe973fdb3 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteUnboxingThunkNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ShadowConcreteUnboxingThunkNode.cs
@@ -69,5 +69,16 @@ namespace ILCompiler.DependencyAnalysis
public sealed override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
public sealed override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
+
+ int ISortableSymbolNode.ClassCode => -501699818;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ var compare = comparer.Compare(Method, ((ShadowConcreteUnboxingThunkNode)other).Method);
+ if (compare != 0)
+ return compare;
+
+ return comparer.Compare(_canonicalThunk, ((ShadowConcreteUnboxingThunkNode)other)._canonicalThunk);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SortableDependencyNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SortableDependencyNode.cs
new file mode 100644
index 000000000..66e2e7e60
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SortableDependencyNode.cs
@@ -0,0 +1,170 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+using ILCompiler.DependencyAnalysisFramework;
+using Internal.TypeSystem;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public abstract class SortableDependencyNode : DependencyNodeCore<NodeFactory>
+ {
+#if !SUPPORT_JIT
+ /// <summary>
+ /// Allows grouping of <see cref="ObjectNode"/> instances such that all nodes in a lower phase
+ /// will be ordered before nodes in a later phase.
+ /// </summary>
+ protected internal virtual int Phase => (int)ObjectNodePhase.Unordered;
+
+ /// <summary>
+ /// Gets an identifier that is the same for all instances of this <see cref="ObjectNode"/>
+ /// descendant, but different from the <see cref="ClassCode"/> of any other descendant.
+ /// </summary>
+ /// <remarks>
+ /// This is really just a number, ideally produced by "new Random().Next(int.MinValue, int.MaxValue)".
+ /// If two manage to conflict (which is pretty unlikely), just make a new one...
+ /// </remarks>
+ protected internal abstract int ClassCode { get; }
+
+ // Note to implementers: the type of `other` is actually the same as the type of `this`.
+ protected internal virtual int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ throw new NotImplementedException("Multiple nodes of this type are not supported");
+ }
+
+ protected enum ObjectNodePhase
+ {
+ /// <summary>
+ /// Nodes should only be placed in this phase if they have strict output ordering requirements that
+ /// affect compiler correctness. Today that includes native layout tables.
+ /// </summary>
+ Ordered,
+ Unordered
+ }
+
+ protected enum ObjectNodeOrder
+ {
+ //
+ // The ordering of this sequence of nodes is deliberate and currently required for
+ // compiler correctness.
+ //
+ MetadataNode,
+ ResourceDataNode,
+ ResourceIndexNode,
+ TypeMetadataMapNode,
+ ClassConstructorContextMap,
+ DynamicInvokeTemplateDataNode,
+ ReflectionInvokeMapNode,
+ DelegateMarshallingStubMapNode,
+ StructMarshallingStubMapNode,
+ ArrayMapNode,
+ ReflectionFieldMapNode,
+ NativeLayoutInfoNode,
+ ExactMethodInstantiationsNode,
+ GenericTypesHashtableNode,
+ GenericMethodsHashtableNode,
+ GenericVirtualMethodTableNode,
+ InterfaceGenericVirtualMethodTableNode,
+ GenericMethodsTemplateMap,
+ GenericTypesTemplateMap,
+ BlockReflectionTypeMapNode,
+ StaticsInfoHashtableNode,
+ ReflectionVirtualInvokeMapNode,
+ ExternalReferencesTableNode,
+ ArrayOfEmbeddedPointersNode,
+ DefaultConstructorMapNode,
+ ArrayOfEmbeddedDataNode
+ }
+
+ public class EmbeddedObjectNodeComparer : IComparer<EmbeddedObjectNode>
+ {
+ private CompilerComparer _comparer;
+
+ public EmbeddedObjectNodeComparer(CompilerComparer comparer)
+ {
+ _comparer = comparer;
+ }
+
+ public int Compare(EmbeddedObjectNode x, EmbeddedObjectNode y)
+ {
+ return CompareImpl(x, y, _comparer);
+ }
+ }
+
+ /// <summary>
+ /// This comparer is used to sort the marked node list. We only care about ordering ObjectNodes
+ /// for emission into the binary, so any EmbeddedObjectNode or DependencyNodeCore objects are
+ /// skipped for efficiency.
+ /// </summary>
+ public class ObjectNodeComparer : IComparer<DependencyNodeCore<NodeFactory>>
+ {
+ private CompilerComparer _comparer;
+
+ public ObjectNodeComparer(CompilerComparer comparer)
+ {
+ _comparer = comparer;
+ }
+
+ public int Compare(DependencyNodeCore<NodeFactory> x1, DependencyNodeCore<NodeFactory> y1)
+ {
+ ObjectNode x = x1 as ObjectNode;
+ ObjectNode y = y1 as ObjectNode;
+
+ if (x == y)
+ {
+ return 0;
+ }
+
+ // Sort non-object nodes after ObjectNodes
+ if (x == null)
+ return 1;
+
+ if (y == null)
+ return -1;
+
+ return CompareImpl(x, y, _comparer);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int CompareImpl(SortableDependencyNode x, SortableDependencyNode y, CompilerComparer comparer)
+ {
+ int phaseX = x.Phase;
+ int phaseY = y.Phase;
+
+ if (phaseX == phaseY)
+ {
+ int codeX = x.ClassCode;
+ int codeY = y.ClassCode;
+ if (codeX == codeY)
+ {
+ Debug.Assert(x.GetType() == y.GetType() ||
+ (x.GetType().IsConstructedGenericType && y.GetType().IsConstructedGenericType
+ && x.GetType().GetGenericTypeDefinition() == y.GetType().GetGenericTypeDefinition()));
+
+ int result = x.CompareToImpl(y, comparer);
+
+ // We did a reference equality check above so an "Equal" result is not expected
+ Debug.Assert(result != 0 || x == y);
+
+ return result;
+ }
+ else
+ {
+ Debug.Assert(x.GetType() != y.GetType());
+ return codeX - codeY;
+ }
+ }
+ else
+ {
+ return phaseX - phaseY;
+ }
+ }
+#endif
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StaticsInfoHashtableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StaticsInfoHashtableNode.cs
index 31fc9451d..22122f7ed 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StaticsInfoHashtableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StaticsInfoHashtableNode.cs
@@ -147,5 +147,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.StaticsInfoHashtableNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringAllocatorMethodNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringAllocatorMethodNode.cs
index 6318cdcb1..8a071dbcd 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringAllocatorMethodNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StringAllocatorMethodNode.cs
@@ -65,5 +65,12 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory context) => null;
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ int ISortableSymbolNode.ClassCode => 1991750873;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_allocationMethod, ((StringAllocatorMethodNode)other)._allocationMethod);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StructMarshallingStubMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StructMarshallingStubMapNode.cs
index 48227ea5b..604e25076 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StructMarshallingStubMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/StructMarshallingStubMapNode.cs
@@ -6,6 +6,7 @@ using System;
using Internal.NativeFormat;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -103,5 +104,8 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+ protected internal override int ClassCode => (int)ObjectNodeOrder.StructMarshallingStubMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMInitialInterfaceDispatchStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMInitialInterfaceDispatchStubNode.cs
index eae1bc2be..1c201ebe3 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMInitialInterfaceDispatchStubNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMInitialInterfaceDispatchStubNode.cs
@@ -51,5 +51,7 @@ namespace ILCompiler.DependencyAnalysis
{
throw new NotImplementedException();
}
+
+ protected internal override int ClassCode => 588185132;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsIndexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsIndexNode.cs
index 469c1473b..ab1450d1b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsIndexNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsIndexNode.cs
@@ -5,6 +5,7 @@
using System;
using Internal.Text;
+using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
@@ -17,7 +18,7 @@ namespace ILCompiler.DependencyAnalysis
// The TLS slot index allocated for this module by the OS loader. We keep a pointer to this
// value in the module header.
- public class ThreadStaticsIndexNode : ObjectNode, IExportableSymbolNode
+ public class ThreadStaticsIndexNode : ObjectNode, IExportableSymbolNode, ISortableSymbolNode
{
string _prefix;
@@ -80,6 +81,20 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -968500265;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return string.Compare(_prefix, ((ThreadStaticsIndexNode)other)._prefix);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
// The data structure used by the OS loader to load TLS chunks.
@@ -166,5 +181,12 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -754150753;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return string.Compare(_prefix, ((ThreadStaticsDirectoryNode)other)._prefix);
+ }
}
} \ No newline at end of file
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs
index eed926b2c..357dde0fe 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsNode.cs
@@ -75,5 +75,12 @@ namespace ILCompiler.DependencyAnalysis
builder.RequireInitialPointerAlignment();
builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
}
+
+ protected internal override int ClassCode => 2091208431;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((ThreadStaticsNode)other)._type);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsOffsetNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsOffsetNode.cs
index 8dd47f642..83fef35ea 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsOffsetNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ThreadStaticsOffsetNode.cs
@@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// Represents the offset of the thread static region of a given type from the TLS section start.
/// The node is used for cross-module thread statics reference
/// </summary>
- public class ThreadStaticsOffsetNode : EmbeddedObjectNode, IExportableSymbolNode
+ public class ThreadStaticsOffsetNode : EmbeddedObjectNode, IExportableSymbolNode, ISortableSymbolNode
{
private MetadataType _type;
@@ -73,5 +73,19 @@ namespace ILCompiler.DependencyAnalysis
{
builder.EmitReloc(factory.TypeThreadStaticsSymbol(_type), RelocType.IMAGE_REL_SECREL);
}
+
+ protected internal override int ClassCode => 419394032;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((ThreadStaticsOffsetNode)other)._type);
+ }
+
+ int ISortableSymbolNode.ClassCode => 419394032;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeManagerIndirectionNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeManagerIndirectionNode.cs
index 781975087..4199c29fb 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeManagerIndirectionNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeManagerIndirectionNode.cs
@@ -2,7 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -30,5 +33,7 @@ namespace ILCompiler.DependencyAnalysis
objData.EmitZeroPointer();
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -2028598574;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataMapNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataMapNode.cs
index 9a682d9d1..ea58dd350 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataMapNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataMapNode.cs
@@ -6,6 +6,7 @@ using System;
using Internal.NativeFormat;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis
{
@@ -80,5 +81,9 @@ namespace ILCompiler.DependencyAnalysis
return new ObjectData(hashTableBytes, Array.Empty<Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol });
}
+
+ protected internal override int Phase => (int)ObjectNodePhase.Ordered;
+
+ protected internal override int ClassCode => (int)ObjectNodeOrder.TypeMetadataMapNode;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeThreadStaticIndexNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeThreadStaticIndexNode.cs
index 6586d1ce8..11ac06f2c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeThreadStaticIndexNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeThreadStaticIndexNode.cs
@@ -58,7 +58,7 @@ namespace ILCompiler.DependencyAnalysis
if (!relocsOnly)
{
var node = factory.TypeThreadStaticsSymbol(_type);
- typeTlsIndex = factory.ThreadStaticsRegion.IndexOfEmbeddedObject((ThreadStaticsNode)node);
+ typeTlsIndex = ((ThreadStaticsNode)node).IndexFromBeginningOfArray;
}
objData.EmitPointerReloc(factory.TypeManagerIndirection);
@@ -66,5 +66,12 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => -149601250;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_type, ((TypeThreadStaticIndexNode)other)._type);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UnboxingStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UnboxingStubNode.cs
index b51d50bef..2208f7b1a 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UnboxingStubNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UnboxingStubNode.cs
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using Internal.Text;
using Internal.TypeSystem;
@@ -60,6 +59,20 @@ namespace ILCompiler.DependencyAnalysis
}
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ protected internal override int ClassCode => -1846923013;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(Method, ((UnboxingStubNode)other).Method);
+ }
+
+ int ISortableSymbolNode.ClassCode => ClassCode;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return CompareToImpl((ObjectNode)other, comparer);
+ }
}
//
@@ -98,5 +111,12 @@ namespace ILCompiler.DependencyAnalysis
return objData.ToObjectData();
}
+
+ protected internal override int ClassCode => 1102274050;
+
+ protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
+ {
+ return _isEndSymbol.CompareTo(((WindowsUnboxingStubsRegionNode)other)._isEndSymbol);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
index 5c085d192..454ed3a41 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcNodeFactory.cs
@@ -102,7 +102,7 @@ namespace ILCompiler
return new GCStaticDescNode(type, true);
});
- _threadStaticsOffset = new NodeCache<MetadataType, ISymbolNode>((MetadataType type) =>
+ _threadStaticsOffset = new NodeCache<MetadataType, ISortableSymbolNode>((MetadataType type) =>
{
if (CompilationModuleGroup.ContainsType(type))
{
@@ -236,7 +236,7 @@ namespace ILCompiler
CompilationUnitPrefix + "__ThreadStaticGCDescStart",
CompilationUnitPrefix + "__ThreadStaticGCDescEnd");
- public ArrayOfEmbeddedDataNode ThreadStaticsOffsetRegion = new ArrayOfEmbeddedDataNode(
+ public ArrayOfEmbeddedDataNode<ThreadStaticsOffsetNode> ThreadStaticsOffsetRegion = new ArrayOfEmbeddedDataNode<ThreadStaticsOffsetNode>(
CompilationUnitPrefix + "__ThreadStaticOffsetRegionStart",
CompilationUnitPrefix + "__ThreadStaticOffsetRegionEnd",
null);
@@ -285,16 +285,16 @@ namespace ILCompiler
}
}
- private NodeCache<MetadataType, ISymbolNode> _threadStaticsOffset;
+ private NodeCache<MetadataType, ISortableSymbolNode> _threadStaticsOffset;
- public ISymbolNode TypeThreadStaticsOffsetSymbol(MetadataType type)
+ public ISortableSymbolNode TypeThreadStaticsOffsetSymbol(MetadataType type)
{
return _threadStaticsOffset.GetOrAdd(type);
}
private NodeCache<MetadataType, ImportedThreadStaticsIndexNode> _importedThreadStaticsIndices;
- public ISymbolNode TypeThreadStaticsIndexSymbol(TypeDesc type)
+ public ISortableSymbolNode TypeThreadStaticsIndexSymbol(TypeDesc type)
{
if (CompilationModuleGroup.ContainsType(type))
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcThreadStaticsNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcThreadStaticsNode.cs
index ccf216622..64cae3942 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcThreadStaticsNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/UtcThreadStaticsNode.cs
@@ -60,5 +60,7 @@ namespace ILCompiler.DependencyAnalysis
builder.AddSymbol(this);
return builder.ToObjectData();
}
+
+ protected internal override int ClassCode => -1421136129;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugILImagesSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugILImagesSection.cs
index 2d15dde09..5ac16bbb3 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugILImagesSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugILImagesSection.cs
@@ -30,6 +30,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => 2051656903;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugManagedNativeDictionaryInfoSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugManagedNativeDictionaryInfoSection.cs
index d056ac340..5d3ebd6e7 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugManagedNativeDictionaryInfoSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugManagedNativeDictionaryInfoSection.cs
@@ -30,6 +30,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => 1502860768;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMergedAssemblyRecordsSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMergedAssemblyRecordsSection.cs
index 5481e9e9b..49f75a100 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMergedAssemblyRecordsSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMergedAssemblyRecordsSection.cs
@@ -31,6 +31,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => -1250136545;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs
index 3a7065c22..7d4396fc7 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodInfoSection.cs
@@ -149,5 +149,7 @@ namespace ILCompiler.DependencyAnalysis
{
return "___DebugMethodInfoSection";
}
+
+ protected internal override int ClassCode => 513099721;
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodMapSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodMapSection.cs
index 57d29e640..c351d54e8 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodMapSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugMethodMapSection.cs
@@ -30,6 +30,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => -2063194124;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugNeedTypeIndicesStoreNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugNeedTypeIndicesStoreNode.cs
index c2e38a183..71435021c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugNeedTypeIndicesStoreNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugNeedTypeIndicesStoreNode.cs
@@ -21,6 +21,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => 1275723356;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugPseudoAssemblySection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugPseudoAssemblySection.cs
index 8b38611f6..7f393b2d4 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugPseudoAssemblySection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugPseudoAssemblySection.cs
@@ -29,6 +29,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => 920778380;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeRecordsSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeRecordsSection.cs
index 912721e7e..660559ccb 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeRecordsSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeRecordsSection.cs
@@ -33,6 +33,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => -2081034825;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeSignatureMapSection.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeSignatureMapSection.cs
index 1337c162e..0ec387d9c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeSignatureMapSection.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/WindowsDebugTypeSignatureMapSection.cs
@@ -31,6 +31,8 @@ namespace ILCompiler.DependencyAnalysis
public int Offset => 0;
+ protected internal override int ClassCode => 1029840999;
+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(GetName(null));
diff --git a/src/ILCompiler.Compiler/src/Compiler/ObjectDumper.cs b/src/ILCompiler.Compiler/src/Compiler/ObjectDumper.cs
index 2dc9b64a2..194d92693 100644
--- a/src/ILCompiler.Compiler/src/Compiler/ObjectDumper.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/ObjectDumper.cs
@@ -4,6 +4,7 @@
using System;
using System.IO;
+using System.Security.Cryptography;
using System.Xml;
using Internal.Text;
@@ -17,7 +18,7 @@ namespace ILCompiler
public class ObjectDumper : IObjectDumper
{
private readonly string _fileName;
-
+ private SHA256 _sha256;
private XmlWriter _writer;
public ObjectDumper(string fileName)
@@ -33,6 +34,7 @@ namespace ILCompiler
Indent = true,
};
+ _sha256 = SHA256.Create();
_writer = XmlWriter.Create(File.CreateText(_fileName), settings);
_writer.WriteStartElement("ObjectNodes");
}
@@ -69,7 +71,7 @@ namespace ILCompiler
}
_writer.WriteAttributeString("Length", objectData.Data.Length.ToStringInvariant());
-
+ _writer.WriteAttributeString("Hash", HashData(objectData.Data));
_writer.WriteEndElement();
var nodeWithCodeInfo = node as INodeWithCodeInfo;
@@ -78,6 +80,7 @@ namespace ILCompiler
_writer.WriteStartElement("GCInfo");
_writer.WriteAttributeString("Name", name);
_writer.WriteAttributeString("Length", nodeWithCodeInfo.GCInfo.Length.ToStringInvariant());
+ _writer.WriteAttributeString("Hash", HashData(nodeWithCodeInfo.GCInfo));
_writer.WriteEndElement();
if (nodeWithCodeInfo.EHInfo != null)
@@ -85,11 +88,17 @@ namespace ILCompiler
_writer.WriteStartElement("EHInfo");
_writer.WriteAttributeString("Name", name);
_writer.WriteAttributeString("Length", nodeWithCodeInfo.EHInfo.Data.Length.ToStringInvariant());
+ _writer.WriteAttributeString("Hash", HashData(nodeWithCodeInfo.EHInfo.Data));
_writer.WriteEndElement();
}
}
}
+ private string HashData(byte[] data)
+ {
+ return BitConverter.ToString(_sha256.ComputeHash(data)).Replace("-", "").ToLower();
+ }
+
internal void End()
{
_writer.WriteEndElement();
diff --git a/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs b/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs
index da47f3539..00ec7d470 100644
--- a/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs
@@ -369,5 +369,24 @@ namespace ILCompiler
{
return fieldInfo1.Field.Offset.AsInt - fieldInfo2.Field.Offset.AsInt;
}
+
+ public int CompareTo(PreInitFieldInfo other, TypeSystemComparer comparer)
+ {
+ if (Length != other.Length)
+ return Length - other.Length;
+
+ var compare = comparer.Compare(Field, other.Field);
+ if (compare != 0)
+ return compare;
+
+ Debug.Assert(Data.Length == other.Data.Length);
+ for (int i = 0; i < Length; i++)
+ {
+ if (Data[i] != other.Data[i])
+ return Data[i] - other.Data[i];
+ }
+
+ return 0;
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
index 6e5385f67..fbd06eabc 100644
--- a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
@@ -90,7 +90,7 @@ namespace ILCompiler
var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions);
- DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
+ DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory, new ObjectNode.ObjectNodeComparer(new CompilerComparer()));
return new RyuJitCompilation(graph, factory, _compilationRoots, _debugInformationProvider, _logger, jitConfig);
}
}
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index f12c17ad6..a259242a4 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -1,4 +1,4 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" Condition="'$(IsProjectNLibrary)' != 'true'" />
<PropertyGroup>
<OutputType>Library</OutputType>
@@ -113,7 +113,9 @@
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugPseudoAssemblySection.cs" />
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugTypeRecordsSection.cs" />
<Compile Include="Compiler\DependencyAnalysis\WindowsDebugTypeSignatureMapSection.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\CompilerComparer.cs" />
<Compile Include="Compiler\DependencyAnalysis\CustomAttributeBasedDependencyAlgorithm.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\EmbeddedDataContainerNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\FieldMetadataNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\ILScanNodeFactory.cs" />
<Compile Include="Compiler\DependencyAnalysis\IMethodBodyNode.cs" />
@@ -122,6 +124,7 @@
<Compile Include="Compiler\DependencyAnalysis\LoopHijackFlagNode.cs" />
<Compile Include="Compiler\DictionaryLayoutProvider.cs" />
<Compile Include="Compiler\EmptyInteropStubManager.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\SortableDependencyNode.cs" />
<Compile Include="Compiler\PreInitFieldInfo.cs" />
<Compile Include="Compiler\DependencyAnalysis\FrozenArrayNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\GCStaticsPreInitDataNode.cs" />
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppMethodCodeNode.cs b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppMethodCodeNode.cs
index 16ab08d5d..70a138649 100644
--- a/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppMethodCodeNode.cs
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/DependencyAnalysis/CppMethodCodeNode.cs
@@ -75,5 +75,12 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
+
+ int ISortableSymbolNode.ClassCode => 1643555522;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_method, ((CppMethodCodeNode)other)._method);
+ }
}
}
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
index 22b3352bc..be4301303 100644
--- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
+++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs
@@ -1005,6 +1005,10 @@ namespace ILCompiler.CppCodeGen
//RTR header needs to be declared after all modules have already been output
string rtrHeader = string.Empty;
+ // GetData stabilizes the indices of the embedded objects. This must be done manually
+ // for C++ codegen since we don't currently emit the DispatchMapTable node directly.
+ factory.DispatchMapTable.GetData(factory, false);
+
// Iterate through nodes
foreach (var node in nodeIterator.GetNodes())
{
diff --git a/src/ILCompiler.DependencyAnalysisFramework/src/DependencyAnalyzer.cs b/src/ILCompiler.DependencyAnalysisFramework/src/DependencyAnalyzer.cs
index d0aaf7a6d..13b20dac4 100644
--- a/src/ILCompiler.DependencyAnalysisFramework/src/DependencyAnalyzer.cs
+++ b/src/ILCompiler.DependencyAnalysisFramework/src/DependencyAnalyzer.cs
@@ -40,6 +40,7 @@ namespace ILCompiler.DependencyAnalysisFramework
private Dictionary<DependencyNodeCore<DependencyContextType>, HashSet<DependencyNodeCore<DependencyContextType>.CombinedDependencyListEntry>> _conditional_dependency_store = new Dictionary<DependencyNodeCore<DependencyContextType>, HashSet<DependencyNodeCore<DependencyContextType>.CombinedDependencyListEntry>>();
private bool _markingCompleted = false;
+ private Random _stackPopRandomizer = null;
private struct DynamicDependencyNode
{
@@ -68,6 +69,11 @@ namespace ILCompiler.DependencyAnalysisFramework
{
_dependencyContext = dependencyContext;
_resultSorter = resultSorter;
+
+ if (int.TryParse(Environment.GetEnvironmentVariable("CoreRT_DeterminismSeed"), out int seed))
+ {
+ _stackPopRandomizer = new Random(seed);
+ }
}
/// <summary>
@@ -274,7 +280,33 @@ namespace ILCompiler.DependencyAnalysisFramework
{
if (_marker.MarkNode(node, reason1, reason2, reason))
{
- _markStack.Push(node);
+ // Pop the top node of the mark stack
+ if (_stackPopRandomizer == null)
+ {
+ _markStack.Push(node);
+ }
+ else
+ {
+ //
+ // Expose output file determinism bugs in our system by randomizing the order nodes are pushed
+ // on to the mark stack.
+ //
+ int randomNodeIndex = _stackPopRandomizer.Next(_markStack.Count);
+ var tempStack = new Stack<DependencyNodeCore<DependencyContextType>>();
+
+ for (int i = 0; i < randomNodeIndex; i++)
+ {
+ tempStack.Push(_markStack.Pop());
+ }
+
+ _markStack.Push(node);
+
+ while (tempStack.Count > 0)
+ {
+ _markStack.Push(tempStack.Pop());
+ }
+ }
+
_markedNodes.Add(node);
node.CallOnMarked(_dependencyContext);
diff --git a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyMethodCodeNode.cs b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyMethodCodeNode.cs
index 8d92bf996..0cfd4382c 100644
--- a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyMethodCodeNode.cs
+++ b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyMethodCodeNode.cs
@@ -67,5 +67,12 @@ namespace ILCompiler.DependencyAnalysis
public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null;
public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null;
+
+ int ISortableSymbolNode.ClassCode => -1502960727;
+
+ int ISortableSymbolNode.CompareToImpl(ISortableSymbolNode other, CompilerComparer comparer)
+ {
+ return comparer.Compare(_method, ((WebAssemblyMethodCodeNode)other)._method);
+ }
}
}
diff --git a/src/System.Private.Jit/src/System.Private.Jit.csproj b/src/System.Private.Jit/src/System.Private.Jit.csproj
index 3bd997c29..db1d659f2 100644
--- a/src/System.Private.Jit/src/System.Private.Jit.csproj
+++ b/src/System.Private.Jit/src/System.Private.Jit.csproj
@@ -122,6 +122,7 @@
<Compile Include="$(ILCompilerBasePath)\Compiler\DependencyAnalysis\ObjectNodeSection.cs" />
<Compile Include="$(ILCompilerBasePath)\Compiler\DependencyAnalysis\ReadyToRunHelperNode.cs" />
<Compile Include="$(ILCompilerBasePath)\Compiler\DependencyAnalysis\Relocation.cs" />
+ <Compile Include="$(ILCompilerBasePath)\Compiler\DependencyAnalysis\SortableDependencyNode.cs" />
<Compile Include="$(ILCompilerBasePath)\Compiler\DelegateCreationInfo.cs" />
<Compile Include="$(ILCompilerBasePath)\Compiler\JitHelper.cs" />
<Compile Include="$(ILCompilerBasePath)\Compiler\GenericDictionaryLookup.cs" />
diff --git a/tests/runtest.cmd b/tests/runtest.cmd
index 606b2c0f3..85544ec5c 100644
--- a/tests/runtest.cmd
+++ b/tests/runtest.cmd
@@ -53,6 +53,7 @@ if /i "%1" == "/test" (set CoreRT_TestName=%2&shift&shift&goto ArgLoop)
if /i "%1" == "/runtest" (set CoreRT_TestRun=%2&shift&shift&goto ArgLoop)
if /i "%1" == "/dotnetclipath" (set CoreRT_CliDir=%2&shift&shift&goto ArgLoop)
if /i "%1" == "/multimodule" (set CoreRT_MultiFileConfiguration=MultiModule&shift&goto ArgLoop)
+if /i "%1" == "/determinism" (set CoreRT_DeterminismMode=true&shift&goto ArgLoop)
echo Invalid command line argument: %1
goto :Usage
@@ -68,6 +69,8 @@ echo /coreclr : Download and run the CoreCLR repo tests
echo /coreclrsingletest ^<absolute\path\to\test.exe^>
echo : Run a single CoreCLR repo test
echo /multimodule : Compile the framework as a .lib and link tests against it (only supports ryujit)
+echo /determinism : Compile the test twice with randomized dependency node mark stack to validate
+echo compiler determinism in multi-threaded compilation.
echo.
echo --- CoreCLR Subset ---
echo Top200 : Runs broad coverage / CI validation (~200 tests).
@@ -260,24 +263,54 @@ goto :eof
)
)
- echo msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" !extraArgs! !__SourceFileProj!
- echo.
- msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" !extraArgs! !__SourceFileProj!
- endlocal
+ if "%CoreRT_DeterminismMode%"=="true" (
+ set /a CoreRT_DeterminismSeed=%RANDOM%*32768+%RANDOM%
+ echo Running determinism baseline scenario with seed !CoreRT_DeterminismSeed!
- set __SavedErrorLevel=%ErrorLevel%
- if "%CoreRT_TestRun%"=="false" (goto :SkipTestRun)
- if "%__Mode%" == "wasm" (goto :SkipTestRun)
+ echo msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" "/p:IlcGenerateMapFile=true" !extraArgs! !__SourceFileProj!
+ echo.
+ msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" "/p:IlcGenerateMapFile=true" !extraArgs! !__SourceFileProj!
+
+ set __SavedErrorLevel=!ErrorLevel!
+ if not "!__SavedErrorLevel!"=="0" (goto :SkipTestRun)
+
+ REM Back up the map file and delete the obj file so the MSBuild targets won't skip ILC target
+ rename !__SourceFolder!\obj\%CoreRT_BuildType%\%CoreRT_BuildArch%\native\!__SourceFileName!.map.xml !__SourceFileName!.baseline.map.xml
+ del !__SourceFolder!\obj\%CoreRT_BuildType%\%CoreRT_BuildArch%\native\!__SourceFileName!.obj
+
+ set /a CoreRT_DeterminismSeed=%RANDOM%*32768+%RANDOM%
+
+ echo Running determinism comparison scenario with seed !CoreRT_DeterminismSeed!
+ echo msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" "/p:IlcGenerateMapFile=true" !extraArgs! !__SourceFileProj!
+ echo.
+ msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" "/p:IlcGenerateMapFile=true" !extraArgs! !__SourceFileProj!
+ endlocal
+ set __SavedErrorLevel=!ErrorLevel!
+ if not "!__SavedErrorLevel!"=="0" (goto :SkipTestRun)
+
+ fc !__SourceFolder!\obj\%CoreRT_BuildType%\%CoreRT_BuildArch%\native\!__SourceFileName!.baseline.map.xml !__SourceFolder!\obj\%CoreRT_BuildType%\%CoreRT_BuildArch%\native\!__SourceFileName!.map.xml
+ set __SavedErrorLevel=!ErrorLevel!
- if "%__SavedErrorLevel%"=="0" (
+ ) else (
+ echo msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" !extraArgs! !__SourceFileProj!
echo.
- echo Running test !__SourceFileName!
- call !__SourceFile!.cmd !__SourceFolder!\bin\%CoreRT_BuildType%\%CoreRT_BuildArch%\native !__SourceFileName!.exe
+ msbuild /m /ConsoleLoggerParameters:ForceNoAlign "/p:IlcPath=%CoreRT_ToolchainDir%" "/p:Configuration=%CoreRT_BuildType%" "/p:Platform=%CoreRT_BuildArch%" "/p:RepoLocalBuild=true" "/p:FrameworkLibPath=%~dp0..\bin\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\lib" "/p:FrameworkObjPath=%~dp0..\bin\obj\%CoreRT_BuildOS%.%CoreRT_BuildArch%.%CoreRT_BuildType%\Framework" !extraArgs! !__SourceFileProj!
+ endlocal
+
set __SavedErrorLevel=!ErrorLevel!
+ if "%CoreRT_TestRun%"=="false" (goto :SkipTestRun)
+ if "%__Mode%" == "wasm" (goto :SkipTestRun)
+
+ if "%__SavedErrorLevel%"=="0" (
+ echo.
+ echo Running test !__SourceFileName!
+ call !__SourceFile!.cmd !__SourceFolder!\bin\%CoreRT_BuildType%\%CoreRT_BuildArch%\native !__SourceFileName!.exe
+ set __SavedErrorLevel=!ErrorLevel!
+ )
)
:SkipTestRun
- if "%__SavedErrorLevel%"=="0" (
+ if "!__SavedErrorLevel!"=="0" (
set /a __%__Mode%PassedTests=!__%__Mode%PassedTests!+1
echo ^<test name="!__SourceFile!" type="!__SourceFileName!:%__Mode%" method="Main" result="Pass" /^> >> %__CoreRTTestBinDir%\testResults.tmp
) ELSE (