Skip to content

Commit 0321ec2

Browse files
Place read-only non-GC static bases into read-only section (#114477)
If all fields that contribute to the base are effectively read only, place the base into read-only section. This only takes effect if data dehydration is turned off.
1 parent 2f5c61c commit 0321ec2

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,36 @@ public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializ
3434

3535
protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory)
3636
{
37-
if (HasCCtorContext
38-
|| _preinitializationManager.IsPreinitialized(_type))
37+
if (HasCCtorContext)
3938
{
40-
// We have data to be emitted so this needs to be in an initialized data section
39+
// Needs to be writable initialized section because we need info on how to run cctor and whether it ran.
4140
return ObjectNodeSection.DataSection;
4241
}
42+
else if (_preinitializationManager.IsPreinitialized(_type))
43+
{
44+
// Unix linkers don't like relocs to readonly data section
45+
if (!factory.Target.IsWindows)
46+
return ObjectNodeSection.DataSection;
47+
48+
ReadOnlyFieldPolicy readOnlyPolicy = _preinitializationManager.ReadOnlyFieldPolicy;
49+
50+
bool allFieldsReadOnly = true;
51+
foreach (FieldDesc field in _type.GetFields())
52+
{
53+
if (!IsNonGcStaticField(field))
54+
continue;
55+
56+
allFieldsReadOnly = readOnlyPolicy.IsReadOnly(field);
57+
if (!allFieldsReadOnly)
58+
break;
59+
}
60+
61+
// If all fields are read only, we can place this into a read only section
62+
if (allFieldsReadOnly)
63+
return ObjectNodeSection.ReadOnlyDataSection;
64+
else
65+
return ObjectNodeSection.DataSection;
66+
}
4367
else
4468
{
4569
// This is all zeros; place this to the BSS section
@@ -149,6 +173,9 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
149173
return dependencyList;
150174
}
151175

176+
private static bool IsNonGcStaticField(FieldDesc field)
177+
=> field.IsStatic && !field.HasRva && !field.IsLiteral && !field.IsThreadStatic && !field.HasGCStaticBase;
178+
152179
protected override ObjectData GetDehydratableData(NodeFactory factory, bool relocsOnly)
153180
{
154181
ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
@@ -193,7 +220,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
193220
int initialOffset = builder.CountBytes;
194221
foreach (FieldDesc field in _type.GetFields())
195222
{
196-
if (!field.IsStatic || field.HasRva || field.IsLiteral || field.IsThreadStatic || field.HasGCStaticBase)
223+
if (!IsNonGcStaticField(field))
197224
continue;
198225

199226
int padding = field.Offset.AsInt - builder.CountBytes + initialOffset;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class PreinitializationManager
1717
{
1818
private readonly bool _supportsLazyCctors;
1919

20+
public ReadOnlyFieldPolicy ReadOnlyFieldPolicy => _preinitHashTable._readOnlyPolicy;
21+
2022
public PreinitializationManager(TypeSystemContext context, CompilationModuleGroup compilationGroup, ILProvider ilprovider, TypePreinit.TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, FlowAnnotations flowAnnotations)
2123
{
2224
_supportsLazyCctors = context.SystemModule.GetType("System.Runtime.CompilerServices", "ClassConstructorRunner", throwIfNotFound: false) != null;
@@ -139,7 +141,7 @@ private sealed class PreinitializationInfoHashtable : LockFreeReaderHashtable<Me
139141
private readonly CompilationModuleGroup _compilationGroup;
140142
private readonly ILProvider _ilProvider;
141143
internal readonly TypePreinit.TypePreinitializationPolicy _policy;
142-
private readonly ReadOnlyFieldPolicy _readOnlyPolicy;
144+
internal readonly ReadOnlyFieldPolicy _readOnlyPolicy;
143145
private readonly FlowAnnotations _flowAnnotations;
144146

145147
public PreinitializationInfoHashtable(CompilationModuleGroup compilationGroup, ILProvider ilProvider, TypePreinit.TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, FlowAnnotations flowAnnotations)

0 commit comments

Comments
 (0)