Skip to content

Commit 79798fb

Browse files
committed
Specialcase active frames in EnumGcRefs
1 parent e8fbb78 commit 79798fb

10 files changed

+47
-13
lines changed

src/coreclr/nativeaot/Runtime/ICodeManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ class ICodeManager
152152
virtual void EnumGcRefs(MethodInfo * pMethodInfo,
153153
PTR_VOID safePointAddress,
154154
REGDISPLAY * pRegisterSet,
155-
GCEnumContext * hCallback) = 0;
155+
GCEnumContext * hCallback,
156+
bool isActiveStackFrame) = 0;
156157

157158
virtual bool UnwindStackFrame(MethodInfo * pMethodInfo,
158159
REGDISPLAY * pRegisterSet, // in/out

src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ StackFrameIterator::StackFrameIterator(Thread * pThreadToWalk, PInvokeTransition
9696
#ifdef FEATURE_SUSPEND_REDIRECTION
9797
if (pInitialTransitionFrame == REDIRECTED_THREAD_MARKER)
9898
{
99-
InternalInit(pThreadToWalk, pThreadToWalk->GetRedirectionContext(), GcStackWalkFlags);
99+
InternalInit(pThreadToWalk, pThreadToWalk->GetRedirectionContext(), GcStackWalkFlags | ActiveStackFrame);
100100
}
101101
else
102102
#endif
@@ -1407,7 +1407,7 @@ void StackFrameIterator::NextInternal()
14071407
{
14081408
UnwindOutOfCurrentManagedFrame:
14091409
ASSERT(m_dwFlags & MethodStateCalculated);
1410-
m_dwFlags &= ~(ExCollide|MethodStateCalculated|UnwoundReversePInvoke);
1410+
m_dwFlags &= ~(ExCollide|MethodStateCalculated|UnwoundReversePInvoke|ActiveStackFrame);
14111411
ASSERT(IsValid());
14121412

14131413
m_pHijackedReturnValue = NULL;
@@ -1757,6 +1757,12 @@ MethodInfo * StackFrameIterator::GetMethodInfo()
17571757
return &m_methodInfo;
17581758
}
17591759

1760+
bool StackFrameIterator::IsActiveStackFrame()
1761+
{
1762+
ASSERT(IsValid());
1763+
return (m_dwFlags & ActiveStackFrame) != 0;
1764+
}
1765+
17601766
#ifdef DACCESS_COMPILE
17611767
#define FAILFAST_OR_DAC_RETURN_FALSE(x) if(!(x)) return false;
17621768
#else

src/coreclr/nativeaot/Runtime/StackFrameIterator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class StackFrameIterator
4343
REGDISPLAY * GetRegisterSet();
4444
PTR_ICodeManager GetCodeManager();
4545
MethodInfo * GetMethodInfo();
46+
bool IsActiveStackFrame();
4647
bool GetHijackedReturnValueLocation(PTR_RtuObjectRef * pLocation, GCRefKind * pKind);
4748
void SetControlPC(PTR_VOID controlPC);
4849

@@ -138,6 +139,9 @@ class StackFrameIterator
138139
// This is a state returned by Next() which indicates that we just unwound a reverse pinvoke method
139140
UnwoundReversePInvoke = 0x20,
140141

142+
// The thread was interrupted in the current frame at the current IP by a signal, SuspendThread or similar.
143+
ActiveStackFrame = 0x40,
144+
141145
GcStackWalkFlags = (CollapseFunclets | RemapHardwareFaultsToSafePoint),
142146
EHStackWalkFlags = ApplyReturnAddressAdjustment,
143147
StackTraceStackWalkFlags = GcStackWalkFlags

src/coreclr/nativeaot/Runtime/gcrhenv.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ void RedhawkGCInterface::EnumGcRefs(ICodeManager * pCodeManager,
515515
PTR_VOID safePointAddress,
516516
REGDISPLAY * pRegisterSet,
517517
void * pfnEnumCallback,
518-
void * pvCallbackData)
518+
void * pvCallbackData,
519+
bool isActiveStackFrame)
519520
{
520521
EnumGcRefContext ctx;
521522
ctx.pCallback = EnumGcRefsCallback;
@@ -526,7 +527,8 @@ void RedhawkGCInterface::EnumGcRefs(ICodeManager * pCodeManager,
526527
pCodeManager->EnumGcRefs(pMethodInfo,
527528
safePointAddress,
528529
pRegisterSet,
529-
&ctx);
530+
&ctx,
531+
isActiveStackFrame);
530532
}
531533

532534
// static

src/coreclr/nativeaot/Runtime/gcrhinterface.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ class RedhawkGCInterface
120120
PTR_VOID safePointAddress,
121121
REGDISPLAY * pRegisterSet,
122122
void * pfnEnumCallback,
123-
void * pvCallbackData);
123+
void * pvCallbackData,
124+
bool isActiveStackFrame);
124125

125126
static void EnumGcRefsInRegionConservatively(PTR_RtuObjectRef pLowerBound,
126127
PTR_RtuObjectRef pUpperBound,

src/coreclr/nativeaot/Runtime/thread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ void Thread::GcScanRootsWorker(void * pfnEnumCallback, void * pvCallbackData, St
533533
frameIterator.GetEffectiveSafePointAddress(),
534534
frameIterator.GetRegisterSet(),
535535
pfnEnumCallback,
536-
pvCallbackData);
536+
pvCallbackData,
537+
frameIterator.IsActiveStackFrame());
537538
}
538539

539540
// Each enumerated frame (including the first one) may have an associated stack range we need to

src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ bool UnixNativeCodeManager::IsSafePoint(PTR_VOID pvAddress)
136136
void UnixNativeCodeManager::EnumGcRefs(MethodInfo * pMethodInfo,
137137
PTR_VOID safePointAddress,
138138
REGDISPLAY * pRegisterSet,
139-
GCEnumContext * hCallback)
139+
GCEnumContext * hCallback,
140+
bool isActiveStackFrame)
140141
{
141142
UnixNativeMethodInfo * pNativeMethodInfo = (UnixNativeMethodInfo *)pMethodInfo;
142143

@@ -155,7 +156,7 @@ void UnixNativeCodeManager::EnumGcRefs(MethodInfo * pMethodInfo,
155156
GcInfoDecoder decoder(
156157
GCInfoToken(p),
157158
GcInfoDecoderFlags(DECODE_GC_LIFETIMES | DECODE_SECURITY_OBJECT | DECODE_VARARG),
158-
codeOffset - 1 // TODO: Is this adjustment correct?
159+
codeOffset - 1 // TODO: isActiveStackFrame
159160
);
160161

161162
ICodeManagerFlags flags = (ICodeManagerFlags)0;

src/coreclr/nativeaot/Runtime/unix/UnixNativeCodeManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class UnixNativeCodeManager : public ICodeManager
3939
void EnumGcRefs(MethodInfo * pMethodInfo,
4040
PTR_VOID safePointAddress,
4141
REGDISPLAY * pRegisterSet,
42-
GCEnumContext * hCallback);
42+
GCEnumContext * hCallback,
43+
bool isActiveStackFrame);
4344

4445
bool UnwindStackFrame(MethodInfo * pMethodInfo,
4546
REGDISPLAY * pRegisterSet, // in/out

src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,11 +379,23 @@ bool CoffNativeCodeManager::IsSafePoint(PTR_VOID pvAddress)
379379
void CoffNativeCodeManager::EnumGcRefs(MethodInfo * pMethodInfo,
380380
PTR_VOID safePointAddress,
381381
REGDISPLAY * pRegisterSet,
382-
GCEnumContext * hCallback)
382+
GCEnumContext * hCallback,
383+
bool isActiveStackFrame)
383384
{
384385
PTR_UInt8 gcInfo;
385386
uint32_t codeOffset = GetCodeOffset(pMethodInfo, safePointAddress, &gcInfo);
386387

388+
if (!isActiveStackFrame)
389+
{
390+
// If we are not in the active method, we are currently pointing
391+
// to the return address. That may not be reachable after a call (if call does not return)
392+
// or reachable via a jump and thus have a different live set.
393+
// Therefore we simply adjust the offset to inside of call instruction.
394+
// NOTE: The GcInfoDecoder depends on this; if you change it, you must
395+
// revisit the GcInfoEncoder/Decoder
396+
codeOffset--;
397+
}
398+
387399
GcInfoDecoder decoder(
388400
GCInfoToken(gcInfo),
389401
GcInfoDecoderFlags(DECODE_GC_LIFETIMES | DECODE_SECURITY_OBJECT | DECODE_VARARG),
@@ -393,12 +405,16 @@ void CoffNativeCodeManager::EnumGcRefs(MethodInfo * pMethodInfo,
393405
ICodeManagerFlags flags = (ICodeManagerFlags)0;
394406
if (((CoffNativeMethodInfo *)pMethodInfo)->executionAborted)
395407
flags = ICodeManagerFlags::ExecutionAborted;
408+
396409
if (IsFilter(pMethodInfo))
397410
flags = (ICodeManagerFlags)(flags | ICodeManagerFlags::NoReportUntracked);
398411

412+
if (isActiveStackFrame)
413+
flags = (ICodeManagerFlags)(flags | ICodeManagerFlags::ActiveStackFrame);
414+
399415
if (!decoder.EnumerateLiveSlots(
400416
pRegisterSet,
401-
false /* reportScratchSlots */,
417+
isActiveStackFrame /* reportScratchSlots */,
402418
flags,
403419
hCallback->pCallback,
404420
hCallback

src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ class CoffNativeCodeManager : public ICodeManager
7777
void EnumGcRefs(MethodInfo * pMethodInfo,
7878
PTR_VOID safePointAddress,
7979
REGDISPLAY * pRegisterSet,
80-
GCEnumContext * hCallback);
80+
GCEnumContext * hCallback,
81+
bool isActiveStackFrame);
8182

8283
bool UnwindStackFrame(MethodInfo * pMethodInfo,
8384
REGDISPLAY * pRegisterSet, // in/out

0 commit comments

Comments
 (0)