Skip to content

Commit

Permalink
Add memory barriers to native AOT asm helpers (#106004)
Browse files Browse the repository at this point in the history
* Add memory barriers to native AOT asm helpers

Fixes #81151

* Fix pre-existing bug
  • Loading branch information
jkotas authored Aug 10, 2024
1 parent 649abc6 commit ec496fe
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ private static unsafe IntPtr CheckStaticClassConstructionReturnNonGCStaticBase(S
private static unsafe object CheckStaticClassConstructionReturnThreadStaticBase(TypeManagerSlot* pModuleData, int typeTlsIndex, StaticClassConstructionContext* context)
{
object threadStaticBase = ThreadStatics.GetThreadStaticBaseForType(pModuleData, typeTlsIndex);
EnsureClassConstructorRun(context);
if (context->cctorMethodAddress != 0)
EnsureClassConstructorRun(context);
return threadStaticBase;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,11 @@ public void EmitRETIfNotEqual()
EmitBEQ(4);
EmitRET();
}

// dmb
public void EmitDMB()
{
Builder.EmitUInt(0x8F5FF3BF);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ public void EmitLDR(Register regDst, Register regSrc, int offset)
}
}

// ldar regDst, [regAddr]
public void EmitLDAR(Register regDst, Register regAddr)
{
Debug.Assert((uint)regDst <= 0x1f);
Debug.Assert((uint)regAddr <= 0x1f);
uint instruction = 0xc8dffc00 | ((uint)regAddr << 5) | (uint)regDst;
Builder.EmitUInt(instruction);
}

public void EmitCMP(Register reg, sbyte immediate)
{
if (immediate >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARMEmitter enco
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
int cctorContextSize = NonGCStaticsNode.GetClassConstructorContextSize(factory.Target);
encoder.EmitLDR(encoder.TargetRegister.Arg1, encoder.TargetRegister.Arg0, (short)-cctorContextSize);
encoder.EmitDMB();
encoder.EmitCMP(encoder.TargetRegister.Arg1, 0);
encoder.EmitRETIfEqual();

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

int cctorContextSize = NonGCStaticsNode.GetClassConstructorContextSize(factory.Target);
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2, ((short)(factory.Target.PointerSize - cctorContextSize)));
encoder.EmitCMP(encoder.TargetRegister.Arg3, 1);
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2, (short)-cctorContextSize);
encoder.EmitDMB();
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitRETIfEqual();

encoder.EmitMOV(encoder.TargetRegister.Arg1, encoder.TargetRegister.Result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2,
(short)-NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
encoder.EmitDMB();
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitRETIfEqual();

Expand Down Expand Up @@ -86,6 +87,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo
encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target));
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2,
(short)-NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
encoder.EmitDMB();
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitRETIfEqual();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected sealed override void EmitCode(NodeFactory factory, ref ARM64Emitter en
{
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
encoder.EmitSUB(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg0, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
encoder.EmitLDR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
encoder.EmitLDAR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
encoder.EmitCMP(encoder.TargetRegister.Arg2, 0);
encoder.EmitRETIfEqual();

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

encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitLDAR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitRETIfEqual();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
{
// We need to trigger the cctor before returning the base. It is stored at the beginning of the non-GC statics region.
encoder.EmitSUB(encoder.TargetRegister.Arg3, encoder.TargetRegister.Result, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target));
encoder.EmitLDR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
encoder.EmitLDAR(encoder.TargetRegister.Arg2, encoder.TargetRegister.Arg3);
encoder.EmitCMP(encoder.TargetRegister.Arg2, 0);
encoder.EmitRETIfEqual();

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

encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitLDAR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2);
encoder.EmitCMP(encoder.TargetRegister.Arg3, 0);
encoder.EmitJE(helper);

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

Expand Down

0 comments on commit ec496fe

Please sign in to comment.