diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs
index 0af151dddc520..27a8dd31db8eb 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenObjectNode.cs
@@ -1,77 +1,54 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using System.Collections.Generic;
-using System.Diagnostics;
+
using Internal.Text;
using Internal.TypeSystem;
+using Debug = System.Diagnostics.Debug;
+
namespace ILCompiler.DependencyAnalysis
{
- ///
- /// Represents a frozen object that is statically preallocated within the data section
- /// of the executable instead of on the GC heap.
- ///
- public sealed class FrozenObjectNode : EmbeddedObjectNode, ISymbolDefinitionNode
+ public abstract class FrozenObjectNode : EmbeddedObjectNode, ISymbolDefinitionNode
{
- private readonly MetadataType _owningType;
- private readonly TypePreinit.ISerializableReference _data;
- private readonly int _allocationSiteId;
-
- public FrozenObjectNode(MetadataType owningType, int allocationSiteId, TypePreinit.ISerializableReference data)
- {
- _owningType = owningType;
- _allocationSiteId = allocationSiteId;
- _data = data;
- }
-
- public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
- {
- sb.Append(nameMangler.CompilationUnitPrefix).Append("__FrozenObj_")
- .Append(nameMangler.GetMangledTypeName(_owningType))
- .Append(_allocationSiteId.ToStringInvariant());
- }
-
- public override bool StaticDependenciesAreComputed => true;
-
- public TypeDesc ObjectType => _data.Type;
-
- public bool IsKnownImmutable => _data.IsKnownImmutable;
-
- public int GetArrayLength()
- {
- Debug.Assert(ObjectType.IsArray);
- return _data.ArrayLength;
- }
-
int ISymbolNode.Offset => 0;
int ISymbolDefinitionNode.Offset
{
get
{
- // The frozen object symbol points at the MethodTable portion of the object, skipping over the sync block
- return OffsetFromBeginningOfArray + _owningType.Context.Target.PointerSize;
+ // The frozen symbol points at the MethodTable portion of the object, skipping over the sync block
+ return OffsetFromBeginningOfArray + ObjectType.Context.Target.PointerSize;
}
}
- public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
+ public abstract TypeDesc ObjectType { get; }
+
+ public abstract int? ArrayLength { get; }
+ public abstract bool IsKnownImmutable { get; }
+ public int Size => ObjectType.Context.Target.PointerSize + ContentSize; // SyncBlock + size of contents
+ protected abstract int ContentSize { get; }
+
+ public abstract void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb);
+
+ public sealed override bool StaticDependenciesAreComputed => true;
+
+ public sealed override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
{
- // Sync Block
- dataBuilder.EmitZeroPointer();
+ dataBuilder.EmitZeroPointer(); // Sync block
- // byte contents
- _data.WriteContent(ref dataBuilder, this, factory);
+ int sizeBefore = dataBuilder.CountBytes;
+ EncodeContents(ref dataBuilder, factory, relocsOnly);
+ Debug.Assert(dataBuilder.CountBytes == sizeBefore + ContentSize);
}
- protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
-
- public override IEnumerable GetStaticDependencies(NodeFactory factory)
+ public sealed override IEnumerable GetStaticDependencies(NodeFactory factory)
{
- ObjectDataBuilder builder = new ObjectDataBuilder(factory, true);
- EncodeData(ref builder, factory, true);
+ var builder = new ObjectDataBuilder(factory, relocsOnly: true);
+ EncodeData(ref builder, factory, relocsOnly: true);
Relocation[] relocs = builder.ToObjectData().Relocs;
+
DependencyList dependencies = null;
if (relocs != null)
@@ -83,23 +60,15 @@ public override IEnumerable GetStaticDependencies(NodeFacto
}
}
- _data.GetNonRelocationDependencies(ref dependencies, factory);
+ GetNonRelocationDependencies(ref dependencies, factory);
return dependencies;
}
- public override int ClassCode => 1789429316;
-
- public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
+ public virtual void GetNonRelocationDependencies(ref DependencyList dependencies, NodeFactory factory)
{
- var otherFrozenObjectNode = (FrozenObjectNode)other;
- int result = comparer.Compare(otherFrozenObjectNode._owningType, _owningType);
- if (result != 0)
- return result;
-
- return _allocationSiteId.CompareTo(otherFrozenObjectNode._allocationSiteId);
}
- public override string ToString() => $"Frozen {_data.Type.GetDisplayNameWithoutNamespace()} object";
+ public abstract void EncodeContents(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly);
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs
index 66f386785ef61..f00c508f26524 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FrozenStringNode.cs
@@ -1,63 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Collections.Generic;
-
using Internal.Text;
using Internal.TypeSystem;
-using Debug = System.Diagnostics.Debug;
-
namespace ILCompiler.DependencyAnalysis
{
- public sealed class FrozenStringNode : EmbeddedObjectNode, ISymbolDefinitionNode
+ public sealed class FrozenStringNode : FrozenObjectNode
{
private string _data;
- private int _syncBlockSize;
+ private readonly DefType _stringType;
- public FrozenStringNode(string data, TargetDetails target)
+ public FrozenStringNode(string data, CompilerTypeSystemContext context)
{
_data = data;
- _syncBlockSize = target.PointerSize;
+ _stringType = context.GetWellKnownType(WellKnownType.String);
}
- public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(nameMangler.CompilationUnitPrefix).Append("__Str_").Append(nameMangler.GetMangledStringName(_data));
}
- public override bool StaticDependenciesAreComputed => true;
-
- int ISymbolNode.Offset => 0;
+ protected override int ContentSize => _stringType.Context.Target.PointerSize + sizeof(int) + (_data.Length + 1) * sizeof(char);
- int ISymbolDefinitionNode.Offset
+ public override void EncodeContents(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
{
- get
- {
- // The frozen string symbol points at the MethodTable portion of the object, skipping over the sync block
- return OffsetFromBeginningOfArray + _syncBlockSize;
- }
- }
-
- private static IEETypeNode GetEETypeNode(NodeFactory factory)
- {
- DefType systemStringType = factory.TypeSystemContext.GetWellKnownType(WellKnownType.String);
-
- IEETypeNode stringSymbol = factory.ConstructedTypeSymbol(systemStringType);
-
- //
- // The GC requires a direct reference to frozen objects' EETypes. System.String needs
- // to be compiled into this binary.
- //
- Debug.Assert(!stringSymbol.RepresentsIndirectionCell);
- return stringSymbol;
- }
-
- public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
- {
- dataBuilder.EmitZeroPointer(); // Sync block
-
- dataBuilder.EmitPointerReloc(GetEETypeNode(factory));
+ dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(ObjectType));
dataBuilder.EmitInt(_data.Length);
@@ -72,14 +41,6 @@ public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory f
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
- public override IEnumerable GetStaticDependencies(NodeFactory factory)
- {
- return new DependencyListEntry[]
- {
- new DependencyListEntry(GetEETypeNode(factory), "Frozen string literal MethodTable"),
- };
- }
-
public override int ClassCode => -1733946122;
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
@@ -89,6 +50,12 @@ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer
public string Data => _data;
+ public override int? ArrayLength => _data.Length;
+
+ public override bool IsKnownImmutable => true;
+
+ public override TypeDesc ObjectType => _stringType;
+
public override string ToString() => $"\"{_data}\"";
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
index b7322bdd3df5e..0400ba0b77a8a 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -360,12 +360,12 @@ private void CreateNodeCaches()
_frozenStringNodes = new NodeCache((string data) =>
{
- return new FrozenStringNode(data, Target);
+ return new FrozenStringNode(data, TypeSystemContext);
});
- _frozenObjectNodes = new NodeCache(key =>
+ _frozenObjectNodes = new NodeCache(key =>
{
- return new FrozenObjectNode(key.OwnerType, key.AllocationSiteId, key.SerializableObject);
+ return new SerializedFrozenObjectNode(key.OwnerType, key.AllocationSiteId, key.SerializableObject);
});
_interfaceDispatchCells = new NodeCache(callSiteCell =>
@@ -1220,9 +1220,9 @@ public FrozenStringNode SerializedStringObject(string data)
return _frozenStringNodes.GetOrAdd(data);
}
- private NodeCache _frozenObjectNodes;
+ private NodeCache _frozenObjectNodes;
- public FrozenObjectNode SerializedFrozenObject(MetadataType owningType, int allocationSiteId, TypePreinit.ISerializableReference data)
+ public SerializedFrozenObjectNode SerializedFrozenObject(MetadataType owningType, int allocationSiteId, TypePreinit.ISerializableReference data)
{
return _frozenObjectNodes.GetOrAdd(new SerializedFrozenObjectKey(owningType, allocationSiteId, data));
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SerializedFrozenObjectNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SerializedFrozenObjectNode.cs
new file mode 100644
index 0000000000000..c1d71f6572ece
--- /dev/null
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SerializedFrozenObjectNode.cs
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+
+using Internal.Text;
+using Internal.TypeSystem;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ ///
+ /// Represents a frozen object that is statically preallocated within the data section
+ /// of the executable instead of on the GC heap.
+ ///
+ public sealed class SerializedFrozenObjectNode : FrozenObjectNode
+ {
+ private readonly MetadataType _owningType;
+ private readonly TypePreinit.ISerializableReference _data;
+ private readonly int _allocationSiteId;
+
+ public MetadataType OwningType => _owningType;
+
+ public SerializedFrozenObjectNode(MetadataType owningType, int allocationSiteId, TypePreinit.ISerializableReference data)
+ {
+ _owningType = owningType;
+ _allocationSiteId = allocationSiteId;
+ _data = data;
+ }
+
+ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ {
+ sb.Append(nameMangler.CompilationUnitPrefix).Append("__FrozenObj_")
+ .Append(nameMangler.GetMangledTypeName(_owningType))
+ .Append(_allocationSiteId.ToStringInvariant());
+ }
+
+ public override TypeDesc ObjectType => _data.Type;
+
+ public override bool IsKnownImmutable => _data.IsKnownImmutable;
+
+ protected override int ContentSize
+ => _data.Type.IsArray
+ ? _data.Type.Context.Target.PointerSize * 2 + ((ArrayType)_data.Type).ElementType.GetElementSize().AsInt * _data.ArrayLength
+ : ((DefType)_data.Type).InstanceByteCount.AsInt + (_data.Type.IsValueType ? _data.Type.Context.Target.PointerSize : 0);
+
+ public override int? ArrayLength => _data.Type.IsArray ? _data.ArrayLength : null;
+
+ public override void EncodeContents(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
+ {
+ // byte contents
+ _data.WriteContent(ref dataBuilder, this, factory);
+ }
+
+ protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
+ public override void GetNonRelocationDependencies(ref DependencyList dependencies, NodeFactory factory)
+ {
+ _data.GetNonRelocationDependencies(ref dependencies, factory);
+ }
+
+ public override int ClassCode => 1789429316;
+
+ public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
+ {
+ var otherFrozenObjectNode = (SerializedFrozenObjectNode)other;
+ int result = comparer.Compare(otherFrozenObjectNode._owningType, _owningType);
+ if (result != 0)
+ return result;
+
+ return _allocationSiteId.CompareTo(otherFrozenObjectNode._allocationSiteId);
+ }
+
+ public override string ToString() => $"Frozen {_data.Type.GetDisplayNameWithoutNamespace()} object";
+ }
+}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs
index 73133b10de83a..98f2f238b8ca5 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs
@@ -57,7 +57,7 @@ public abstract class MetadataManager : ICompilationRootProvider
private readonly SortedSet _reflectableMethods = new SortedSet(TypeSystemComparer.Instance);
private readonly SortedSet _genericDictionariesGenerated = new SortedSet(CompilerComparer.Instance);
private readonly SortedSet _methodBodiesGenerated = new SortedSet(CompilerComparer.Instance);
- private readonly SortedSet _frozenObjects = new SortedSet(CompilerComparer.Instance);
+ private readonly SortedSet _frozenObjects = new SortedSet(CompilerComparer.Instance);
private readonly SortedSet _typeGVMEntries
= new SortedSet(Comparer.Create((a, b) => TypeSystemComparer.Instance.Compare(a.AssociatedType, b.AssociatedType)));
private readonly SortedSet _typesWithDelegateMarshalling = new SortedSet(TypeSystemComparer.Instance);
@@ -293,11 +293,6 @@ protected virtual void Graph_NewMarkedNode(DependencyNodeCore obj)
_frozenObjects.Add(frozenObj);
}
- if (obj is FrozenStringNode frozenStr)
- {
- _frozenObjects.Add(frozenStr);
- }
-
if (obj is GenericStaticBaseInfoNode genericStaticBaseInfo)
{
_typesWithGenericStaticBaseInfo.Add(genericStaticBaseInfo.Type);
@@ -751,7 +746,7 @@ public IEnumerable GetTypeTemplates()
return _typeTemplates;
}
- public IEnumerable GetFrozenObjects()
+ public IEnumerable GetFrozenObjects()
{
return _frozenObjects;
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
index 31afdea851adb..2cfb3e3b811fa 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
@@ -412,6 +412,7 @@
+
@@ -460,7 +461,7 @@
-
+
diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
index 5e612ac997350..23146ce32d40c 100644
--- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
+++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
@@ -2261,7 +2261,7 @@ private bool getStaticFieldContent(CORINFO_FIELD_STRUCT_* fieldHandle, byte* buf
}
return false;
- case FrozenObjectNode or FrozenStringNode:
+ case FrozenObjectNode:
Debug.Assert(valueOffset == 0);
Debug.Assert(bufferSize == targetPtrSize);
@@ -2315,13 +2315,7 @@ private bool getObjectContent(CORINFO_OBJECT_STRUCT_* objPtr, byte* buffer, int
private CORINFO_CLASS_STRUCT_* getObjectType(CORINFO_OBJECT_STRUCT_* objPtr)
{
- object obj = HandleToObject(objPtr);
- return obj switch
- {
- FrozenStringNode => ObjectToHandle(_compilation.TypeSystemContext.GetWellKnownType(WellKnownType.String)),
- FrozenObjectNode frozenObj => ObjectToHandle(frozenObj.ObjectType),
- _ => throw new NotImplementedException($"Unexpected object in getObjectType: {obj}")
- };
+ return ObjectToHandle(((FrozenObjectNode)HandleToObject(objPtr)).ObjectType);
}
#pragma warning disable CA1822 // Mark members as static
@@ -2334,13 +2328,7 @@ private bool getObjectContent(CORINFO_OBJECT_STRUCT_* objPtr, byte* buffer, int
private bool isObjectImmutable(CORINFO_OBJECT_STRUCT_* objPtr)
{
- object obj = HandleToObject(objPtr);
- return obj switch
- {
- FrozenStringNode => true,
- FrozenObjectNode frozenObj => frozenObj.IsKnownImmutable,
- _ => throw new NotImplementedException($"Unexpected object in isObjectImmutable: {obj}")
- };
+ return ((FrozenObjectNode)HandleToObject(objPtr)).IsKnownImmutable;
}
private bool getStringChar(CORINFO_OBJECT_STRUCT_* strObj, int index, ushort* value)
@@ -2355,13 +2343,7 @@ private bool getStringChar(CORINFO_OBJECT_STRUCT_* strObj, int index, ushort* va
private int getArrayOrStringLength(CORINFO_OBJECT_STRUCT_* objHnd)
{
- object obj = HandleToObject(objHnd);
- return obj switch
- {
- FrozenStringNode frozenStr => frozenStr.Data.Length,
- FrozenObjectNode frozenObj when frozenObj.ObjectType.IsArray => frozenObj.GetArrayLength(),
- _ => -1
- };
+ return ((FrozenObjectNode)HandleToObject(objHnd)).ArrayLength ?? -1;
}
private bool getIsClassInitedFlagAddress(CORINFO_CLASS_STRUCT_* cls, ref CORINFO_CONST_LOOKUP addr, ref int offset)