Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 8 additions & 0 deletions src/coreclr/gc/gcinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -1066,12 +1066,18 @@ inline GC_ALLOC_FLAGS& operator&=(GC_ALLOC_FLAGS& a, GC_ALLOC_FLAGS b)
#define UNCHECKED_OBJECTREF_TO_OBJECTREF(obj) (obj)
#endif

#if !defined(TARGET_X86) || defined(TARGET_UNIX)
#define USE_STACK_LIMIT
#endif

struct ScanContext
{
Thread* thread_under_crawl;
int thread_number;
int thread_count;
#ifdef USE_STACK_LIMIT
uintptr_t stack_limit; // Lowest point on the thread stack that the scanning logic is permitted to read
#endif // USE_STACK_LIMIT
bool promotion; //TRUE: Promotion, FALSE: Relocation.
bool concurrent; //TRUE: concurrent scanning
void* _unused1;
Expand All @@ -1089,7 +1095,9 @@ struct ScanContext
thread_under_crawl = 0;
thread_number = -1;
thread_count = -1;
#ifdef USE_STACK_LIMIT
stack_limit = 0;
#endif // USE_STACK_LIMIT
promotion = false;
concurrent = false;
pMD = NULL;
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/nativeaot/Runtime/gcrhenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,9 @@ void RedhawkGCInterface::EnumGcRefs(ICodeManager * pCodeManager,
ctx.pCallback = EnumGcRefsCallback;
ctx.f = (EnumGcRefCallbackFunc *)pfnEnumCallback;
ctx.sc = (EnumGcRefScanContext *)pvCallbackData;
#ifdef USE_STACK_LIMIT
ctx.sc->stack_limit = pRegisterSet->GetSP();

#endif // USE_STACK_LIMIT
pCodeManager->EnumGcRefs(pMethodInfo,
safePointAddress,
pRegisterSet,
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/frames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1555,8 +1555,10 @@ BOOL TransitionFrame::Protects(OBJECTREF * ppORef)
{
WRAPPER_NO_CONTRACT;
IsObjRefProtectedScanContext sc (ppORef);
#ifdef USE_STACK_LIMIT
// Set the stack limit for the scan to the SP of the managed frame above the transition frame
sc.stack_limit = GetSP();
#endif // USE_STACK_LIMIT
GcScanRoots (IsObjRefProtected, &sc);
return sc.oref_protected;
}
Expand Down
10 changes: 7 additions & 3 deletions src/coreclr/vm/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,20 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
IsGCSpecialThread() ||
(GetThread() == ThreadSuspend::GetSuspensionThread() && ThreadStore::HoldingThreadStore()));

#if defined(FEATURE_CONSERVATIVE_GC) || defined(USE_STACK_LIMIT)
Frame* pTopFrame = pThread->GetFrame();
Object ** topStack = (Object **)pTopFrame;
if ((pTopFrame != ((Frame*)-1))
&& (pTopFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr())) {
// It is an InlinedCallFrame. Get SP from it.
if (InlinedCallFrame::FrameHasActiveCall(pTopFrame))
{
// It is an InlinedCallFrame with active call. Get SP from it.
InlinedCallFrame* pInlinedFrame = (InlinedCallFrame*)pTopFrame;
topStack = (Object **)pInlinedFrame->GetCallSiteSP();
}
#endif // FEATURE_CONSERVATIVE_GC || USE_STACK_LIMIT

#ifdef USE_STACK_LIMIT
sc->stack_limit = (uintptr_t)topStack;
#endif // USE_STACK_LIMIT

#ifdef FEATURE_CONSERVATIVE_GC
if (g_pConfig->GetGCConservative())
Expand Down
12 changes: 7 additions & 5 deletions src/coreclr/vm/siginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4962,22 +4962,24 @@ void PromoteCarefully(promote_func fn,

#if !defined(DACCESS_COMPILE)

#ifdef USE_STACK_LIMIT
//
// Sanity check the stack scan limit
//
assert(sc->stack_limit != 0);

// Note that the base is at a higher address than the limit, since the stack
// grows downwards.
// To check whether the object is in the stack or not, we also need to check the sc->stack_limit.
// The reason is that on Unix, the stack size can be unlimited. In such case, the system can
// shrink the current reserved stack space. That causes the real limit of the stack to move up and
// the range can be reused for other purposes. But the sc->stack_limit is stable during the scan.
// Even on Windows, we care just about the stack above the stack_limit.
if ((sc->thread_under_crawl->IsAddressInStack(*ppObj)) && (PTR_TO_TADDR(*ppObj) >= sc->stack_limit))
{
return;
}
if ((PTR_TO_TADDR(*ppObj) >= sc->stack_limit))
#endif // USE_STACK_LIMIT
if (sc->thread_under_crawl->IsAddressInStack(*ppObj))
{
return;
}

if (sc->promotion)
{
Expand Down