Skip to content

Commit

Permalink
Fix comments around static constructor memory model (dotnet#105911)
Browse files Browse the repository at this point in the history
- Fix comments around static constructor memory model
- Delete unnecessary MemoryBarrier

Contributes to dotnet#81151
  • Loading branch information
jkotas authored Aug 6, 2024
1 parent 1246154 commit af5a23c
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static unsafe void EnsureClassConstructorRun(StaticClassConstructionConte
IntPtr pfnCctor = pContext->cctorMethodAddress;
NoisyLog("EnsureClassConstructorRun, context={0}, thread={1}", pContext, CurrentManagedThreadId);

// If we were called from MRT, this check is redundant but harmless. This is in case someone within classlib
// If we were called from JIT helper, this check is redundant but harmless. This is in case someone within classlib
// (cough, Reflection) needs to call this explicitly.
if (pfnCctor == 0)
{
Expand Down Expand Up @@ -87,13 +87,6 @@ public static unsafe void EnsureClassConstructorRun(StaticClassConstructionConte

((delegate*<void>)pfnCctor)();

// Insert a memory barrier here to order any writes executed as part of static class
// construction above with respect to the initialized flag update we're about to make
// below. This is important since the fast path for checking the cctor uses a normal read
// and doesn't come here so without the barrier it could observe initialized == 1 but
// still see uninitialized static fields on the class.
Interlocked.MemoryBarrier();

NoisyLog("Set type inited, context={0}, thread={1}", pContext, currentManagedThreadId);

pContext->cctorMethodAddress = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ namespace System.Runtime.CompilerServices
public struct StaticClassConstructionContext
{
// Pointer to the code for the static class constructor method. Set to 0 once the cctor has run.
// Volatile to insert memory barriers to order any writes executed as part of static class
// constructor with respect to this flag.
public volatile IntPtr cctorMethodAddress;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ private static unsafe void CheckStaticClassConstruction(ref StaticClassConstruct

((delegate*<void>)oldInitializationState)();

// Insert a memory barrier here to order any writes executed as part of static class
// construction above with respect to the initialized flag update we're about to make
// below. This is important since the fast path for checking the cctor uses a normal read
// and doesn't come here so without the barrier it could observe initialized == 1 but
// still see uninitialized static fields on the class.
Interlocked.MemoryBarrier();

// Set the cctorMethodAddress to 0 to indicate to the runtime and other threads that this cctor has now
// been run.
context.cctorMethodAddress = (IntPtr)0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace System.Runtime.CompilerServices
[StructLayout(LayoutKind.Sequential)]
public struct StaticClassConstructionContext
{
// Pointer to the code for the static class constructor method. Set to 0 .
// Pointer to the code for the static class constructor method. Set to 0 once the cctor has run.
// Volatile to insert memory barriers to order any writes executed as part of static class
// constructor with respect to this flag.
public volatile IntPtr cctorMethodAddress;
}
}

0 comments on commit af5a23c

Please sign in to comment.