Skip to content

Commit

Permalink
[NativeAOT-LLVM] Workaround to align thread statics to 8 byte boundary (
Browse files Browse the repository at this point in the history
#2609)

* workaround to align thread statics to 8 byte boundary

* add test for thread static alignment
  • Loading branch information
yowl committed Jun 12, 2024
1 parent cd3f95a commit e2a9332
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ private static unsafe object AllocateThreadStaticStorageForType(TypeManagerHandl
gcDesc = Internal.Runtime.Augments.RuntimeAugments.TypeLoaderCallbacks.GetThreadStaticGCDescForDynamicType(typeManager, typeTlsIndex);
}

#if TARGET_WASM
// TODO-LLVM: Remove when there is an upstream fix. See https://github.com/dotnet/runtimelab/issues/2606 and https://github.com/dotnet/runtime/issues/103234
// This is a fix for aligning to 8, thread static fields that should be aligned 8, we just conservatively align everything to 8.
return InternalCalls.RhpNewFastAlign8((MethodTable*)gcDesc);
#else
return RuntimeImports.RhNewObject((MethodTable*)gcDesc);
#endif
}
}
}
45 changes: 45 additions & 0 deletions src/tests/nativeaot/SmokeTests/HelloWasm/HelloWasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,8 @@ private static unsafe int Main(string[] args)

LSSATests.Run();

TestThreadStaticAlignment();

if (OperatingSystem.IsBrowser())
{
EventLoopTestClass.TestEventLoopIntegration();
Expand Down Expand Up @@ -4251,6 +4253,49 @@ static void TestGenStructContains()
EndTest(contains);
}

[InlineArray(3)]
internal struct ReturnArea
{
private ulong buffer;

internal unsafe nint AddressOfReturnArea()
{
return (nint)Unsafe.AsPointer(ref buffer);
}
}

internal class ThreadStaticAlignCheck1
{
[ThreadStatic]
[FixedAddressValueType]
internal static ReturnArea returnArea = default;
}

internal class Padder
{
private object o1;
}

internal class ThreadStaticAlignCheck2
{
[ThreadStatic]
[FixedAddressValueType]
internal static ReturnArea returnArea = default;
}

static void TestThreadStaticAlignment()
{
StartTest("Test ThreadStatic Alignment");

// Assume that these are allocated sequentially, use a padding object of size 12 ( mod 8 is not 0 ) to move the alignment of the second AddressOfReturnArea in case the first is
// coincidentally aligned 8.
var ts1Addr = ThreadStaticAlignCheck1.returnArea.AddressOfReturnArea();
var p = new Padder();
var ts2Addr = ThreadStaticAlignCheck2.returnArea.AddressOfReturnArea();

EndTest((((nint)ts1Addr) % 8 == 0) && (((nint)ts2Addr) % 8 == 0));
}

static ushort ReadUInt16()
{
// something with MSB set
Expand Down

0 comments on commit e2a9332

Please sign in to comment.