Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/coreclr/inc/volatile.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@

#include "staticcontract.h"

#include <atomic>

//
// This code is extremely compiler- and CPU-specific, and will need to be altered to
// support new compilers and/or CPUs. Here we enforce that we can only compile using
Expand Down Expand Up @@ -325,6 +327,18 @@ void VolatileLoadBarrier()
#endif
}

//
// Compiler reordering barrier. Prevents the compiler from moving memory accesses across this
// point. It emits no instructions and provides no CPU or cross-thread ordering; use it only to
// order accesses with respect to asynchronous interruption on the SAME thread, such as a signal
// or hardware-exception handler.
//
inline
void CompilerBarrier()
{
std::atomic_signal_fence(std::memory_order_acq_rel);
}

//
// Volatile<T> implements accesses with our volatile semantics over a variable of type T.
// Wherever you would have used a "volatile Foo" or, equivalently, "Foo volatile", use Volatile<Foo>
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3360,7 +3360,11 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
if (!pChildFrame)
{
pChildFrame = (InterpMethodContextFrame*)alloca(sizeof(InterpMethodContextFrame));
// We make sure that a new frame can't be seen with invalid ip/next when a stack
// overflow is triggered at a location outside of our control.
pChildFrame->ip = NULL;
pChildFrame->pNext = NULL;
CompilerBarrier();
pFrame->pNext = pChildFrame;
}
pChildFrame->ReInit(pFrame, targetIp, returnValueAddress, LOCAL_VAR_ADDR(callArgsOffset, int8_t));
Expand Down Expand Up @@ -3463,7 +3467,11 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
if (!pChildFrame)
{
pChildFrame = (InterpMethodContextFrame*)alloca(sizeof(InterpMethodContextFrame));
// We make sure that a new frame can't be seen with invalid ip/next when a stack
// overflow is triggered at a location outside of our control.
pChildFrame->ip = NULL;
pChildFrame->pNext = NULL;
CompilerBarrier();
pFrame->pNext = pChildFrame;
}
pChildFrame->ReInit(pFrame, targetIp, returnValueAddress, callArgsAddress);
Expand Down Expand Up @@ -4296,7 +4304,11 @@ do \
if (!pChildFrame)
{
pChildFrame = (InterpMethodContextFrame*)alloca(sizeof(InterpMethodContextFrame));
// We make sure that a new frame can't be seen with invalid ip/next when a stack
// overflow is triggered at a location outside of our control.
pChildFrame->ip = NULL;
pChildFrame->pNext = NULL;
CompilerBarrier();
pFrame->pNext = pChildFrame;
}
// Set the frame to the same values as the caller frame.
Expand Down