Skip to content

Commit 75476f9

Browse files
Represent field RVA data with a dedicated node (#72826)
We were using the general purpose `ReadOnlyDataBlobNode` but that meant that whenever we needed to refer to one, we had to read the RVA data into a freshly allocated array and then see if there's a node with that data. Removes 200 MB of allocations while compiling the Techempower benchmark.
1 parent a660c0f commit 75476f9

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,7 @@ public virtual ISymbolNode GetFieldRvaData(FieldDesc field)
142142
else
143143
{
144144
// Use the typical field definition in case this is an instantiated generic type
145-
field = field.GetTypicalFieldDefinition();
146-
int fieldTypePack = (field.FieldType as MetadataType)?.GetClassLayout().PackingSize ?? 1;
147-
return NodeFactory.ReadOnlyDataBlob(NameMangler.GetMangledFieldName(field),
148-
((EcmaField)field).GetFieldRvaData(), Math.Max(NodeFactory.Target.PointerSize, fieldTypePack));
145+
return NodeFactory.FieldRvaData((EcmaField)field.GetTypicalFieldDefinition());
149146
}
150147
}
151148

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
6+
using Internal.Text;
7+
using Internal.TypeSystem;
8+
using Internal.TypeSystem.Ecma;
9+
10+
using Debug = System.Diagnostics.Debug;
11+
12+
namespace ILCompiler.DependencyAnalysis
13+
{
14+
public class FieldRvaDataNode : ObjectNode, ISymbolDefinitionNode
15+
{
16+
private readonly EcmaField _field;
17+
18+
public FieldRvaDataNode(EcmaField field)
19+
{
20+
Debug.Assert(field.HasRva);
21+
_field = field;
22+
}
23+
24+
public override ObjectNodeSection Section => ObjectNodeSection.ReadOnlyDataSection;
25+
public override bool StaticDependenciesAreComputed => true;
26+
27+
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
28+
{
29+
sb.Append(nameMangler.GetMangledFieldName(_field));
30+
}
31+
public int Offset => 0;
32+
public override bool IsShareable => true;
33+
34+
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
35+
{
36+
int fieldTypePack = (_field.FieldType as MetadataType)?.GetClassLayout().PackingSize ?? 1;
37+
byte[] data = relocsOnly ? Array.Empty<byte>() : _field.GetFieldRvaData();
38+
return new ObjectData(
39+
data,
40+
Array.Empty<Relocation>(),
41+
Math.Max(factory.Target.PointerSize, fieldTypePack),
42+
new ISymbolDefinitionNode[] { this });
43+
}
44+
45+
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
46+
47+
#if !SUPPORT_JIT
48+
public override int ClassCode => -456126;
49+
50+
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
51+
{
52+
return comparer.Compare(_field, ((FieldRvaDataNode)other)._field);
53+
}
54+
#endif
55+
}
56+
}

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,11 @@ private void CreateNodeCaches()
236236
return new BlobNode(key.Name, ObjectNodeSection.ReadOnlyDataSection, key.Data, key.Alignment);
237237
});
238238

239+
_fieldRvaDataBlobs = new NodeCache<Internal.TypeSystem.Ecma.EcmaField, FieldRvaDataNode>(key =>
240+
{
241+
return new FieldRvaDataNode(key);
242+
});
243+
239244
_uninitializedWritableDataBlobs = new NodeCache<UninitializedWritableDataBlobKey, BlobNode>(key =>
240245
{
241246
return new BlobNode(key.Name, ObjectNodeSection.BssSection, new byte[key.Size], key.Alignment);
@@ -708,6 +713,14 @@ public BlobNode ReadOnlyDataBlob(Utf8String name, byte[] blobData, int alignment
708713
{
709714
return _readOnlyDataBlobs.GetOrAdd(new ReadOnlyDataBlobKey(name, blobData, alignment));
710715
}
716+
717+
private NodeCache<Internal.TypeSystem.Ecma.EcmaField, FieldRvaDataNode> _fieldRvaDataBlobs;
718+
719+
public ISymbolNode FieldRvaData(Internal.TypeSystem.Ecma.EcmaField field)
720+
{
721+
return _fieldRvaDataBlobs.GetOrAdd(field);
722+
}
723+
711724
private NodeCache<TypeDesc, SealedVTableNode> _sealedVtableNodes;
712725

713726
internal SealedVTableNode SealedVTable(TypeDesc type)

src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@
372372
<Compile Include="Compiler\DependencyAnalysis\DynamicDependencyAttributeAlgorithm.cs" />
373373
<Compile Include="Compiler\DependencyAnalysis\DynamicInvokeTemplateNode.cs" />
374374
<Compile Include="Compiler\DependencyAnalysis\ExternSymbolsImportedNodeProvider.cs" />
375+
<Compile Include="Compiler\DependencyAnalysis\FieldRvaDataNode.cs" />
375376
<Compile Include="Compiler\DependencyAnalysis\IndirectionExtensions.cs" />
376377
<Compile Include="Compiler\DependencyAnalysis\InterfaceDispatchCellSectionNode.cs" />
377378
<Compile Include="Compiler\DependencyAnalysis\MethodExceptionHandlingInfoNode.cs" />

0 commit comments

Comments
 (0)