Skip to content

Commit ec496fe

Browse files
authored
Add memory barriers to native AOT asm helpers (#106004)
* Add memory barriers to native AOT asm helpers Fixes #81151 * Fix pre-existing bug
1 parent 649abc6 commit ec496fe

File tree

7 files changed

+28
-8
lines changed

7 files changed

+28
-8
lines changed

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/ClassConstructorRunner.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ private static unsafe IntPtr CheckStaticClassConstructionReturnNonGCStaticBase(S
4545
private static unsafe object CheckStaticClassConstructionReturnThreadStaticBase(TypeManagerSlot* pModuleData, int typeTlsIndex, StaticClassConstructionContext* context)
4646
{
4747
object threadStaticBase = ThreadStatics.GetThreadStaticBaseForType(pModuleData, typeTlsIndex);
48-
EnsureClassConstructorRun(context);
48+
if (context->cctorMethodAddress != 0)
49+
EnsureClassConstructorRun(context);
4950
return threadStaticBase;
5051
}
5152

src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,5 +257,11 @@ public void EmitRETIfNotEqual()
257257
EmitBEQ(4);
258258
EmitRET();
259259
}
260+
261+
// dmb
262+
public void EmitDMB()
263+
{
264+
Builder.EmitUInt(0x8F5FF3BF);
265+
}
260266
}
261267
}

src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ public void EmitLDR(Register regDst, Register regSrc, int offset)
9090
}
9191
}
9292

93+
// ldar regDst, [regAddr]
94+
public void EmitLDAR(Register regDst, Register regAddr)
95+
{
96+
Debug.Assert((uint)regDst <= 0x1f);
97+
Debug.Assert((uint)regAddr <= 0x1f);
98+
uint instruction = 0xc8dffc00 | ((uint)regAddr << 5) | (uint)regDst;
99+
Builder.EmitUInt(instruction);
100+
}
101+
93102
public void EmitCMP(Register reg, sbyte immediate)
94103
{
95104
if (immediate >= 0)

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunGenericHelperNode.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
7777
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
7878
int cctorContextSize = NonGCStaticsNode.GetClassConstructorContextSize(factory.Target);
7979
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg0, (short)-cctorContextSize);
80+
encoder.EmitDMB();
8081
encoder.EmitCMP(encoder.TargetRegister.Arg1, 0);
8182
encoder.EmitRETIfEqual();
8283

@@ -107,8 +108,9 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
107108
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg2, nonGcRegionLookup, relocsOnly);
108109

109110
int cctorContextSize = NonGCStaticsNode.GetClassConstructorContextSize(factory.Target);
110-
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2, ((short)(factory.Target.PointerSize - cctorContextSize)));
111-
encoder.EmitCMP(encoder.TargetRegister.Arg3, 1);
111+
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2, (short)-cctorContextSize);
112+
encoder.EmitDMB();
113+
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
112114
encoder.EmitRETIfEqual();
113115

114116
encoder.EmitMOV(encoder.TargetRegister.Arg1, encoder.TargetRegister.Result);

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo
3333
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
3434
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2,
3535
(short)-NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
36+
encoder.EmitDMB();
3637
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
3738
encoder.EmitRETIfEqual();
3839

@@ -86,6 +87,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo
8687
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
8788
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2,
8889
(short)-NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
90+
encoder.EmitDMB();
8991
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
9092
encoder.EmitRETIfEqual();
9193

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunGenericHelperNode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
7575
{
7676
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
7777
encoder.EmitSUB(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg0, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
78-
encoder.EmitLDR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
78+
encoder.EmitLDAR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
7979
encoder.EmitCMP(encoder.TargetRegister.Arg2, 0);
8080
encoder.EmitRETIfEqual();
8181

@@ -107,7 +107,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
107107
EmitDictionaryLookup(factory, ref encoder, encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg2, nonGcRegionLookup, relocsOnly);
108108

109109
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
110-
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
110+
encoder.EmitLDAR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
111111
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
112112
encoder.EmitRETIfEqual();
113113

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
3333
{
3434
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
3535
encoder.EmitSUB(encoder.TargetRegister.Arg3, encoder.TargetRegister.Result, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
36-
encoder.EmitLDR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
36+
encoder.EmitLDAR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
3737
encoder.EmitCMP(encoder.TargetRegister.Arg2, 0);
3838
encoder.EmitRETIfEqual();
3939

@@ -75,7 +75,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
7575
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
7676
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
7777

78-
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
78+
encoder.EmitLDAR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
7979
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
8080
encoder.EmitJE(helper);
8181

@@ -101,7 +101,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
101101
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
102102
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
103103
encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
104-
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
104+
encoder.EmitLDAR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
105105
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
106106
encoder.EmitRETIfEqual();
107107

0 commit comments

Comments
 (0)