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
34 changes: 33 additions & 1 deletion src/coreclr/vm/gcinfodecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#endif

#include "gcinfodecoder.h"
#ifdef FEATURE_INTERPRETER
#include "interpexec.h"
#endif // FEATURE_INTERPRETER

#ifdef USE_GC_INFO_DECODER

Expand Down Expand Up @@ -2114,6 +2117,7 @@ template <typename GcInfoEncoding> OBJECTREF* TGcInfoDecoder<GcInfoEncoding>::Ge
#endif // Unknown platform

#ifdef FEATURE_INTERPRETER

template <> OBJECTREF* TGcInfoDecoder<InterpreterGcInfoEncoding>::GetStackSlot(
INT32 spOffset,
GcStackSlotBase spBase,
Expand All @@ -2139,7 +2143,26 @@ template <> OBJECTREF* TGcInfoDecoder<InterpreterGcInfoEncoding>::GetStackSlot(
_ASSERTE(fp);
pObjRef = (OBJECTREF*)(fp + spOffset);
}
InterpMethodContextFrame* pFrame = (InterpMethodContextFrame*)GetSP(pRD->pCurrentContext);
_ASSERTE(pFrame->pStack == (int8_t *)GetFP(pRD->pCurrentContext));
InterpMethodContextFrame* pFrameCallee = pFrame->pNext;

// If the stack slot is in a callee's frame, then we do not actually need to report it. This should ONLY happen if the
// stack slot is in the argument area of the caller. As a double check, we validate in the caller of this function that
// the stack slot in question is a interior pinned slot (which when FEATURE_INTERPRETER is defined indicates a conservatively reported stack slot).
if (pFrameCallee != NULL)
{
if (pFrameCallee->ip != 0)
{
_ASSERTE(pFrameCallee->pStack > pFrame->pStack); // Since only the last funclet is GC reported, we shouldn't have any cases where the stack doesn't grow
if (pFrameCallee->pStack <= (int8_t*)pObjRef)
{
// The stack slot is in the callee's frame, not the caller's frame.
// Return as a sentinel to indicate nothing is reported here.
pObjRef = NULL;
}
}
}
return pObjRef;
}
#endif
Expand Down Expand Up @@ -2221,7 +2244,16 @@ template <typename GcInfoEncoding> void TGcInfoDecoder<GcInfoEncoding>::ReportSt

OBJECTREF* pObjRef = GetStackSlot(spOffset, spBase, pRD);
_ASSERTE(IS_ALIGNED(pObjRef, sizeof(OBJECTREF*)));

#ifdef FEATURE_INTERPRETER
// This value is returned when the interpreter stack slot is not actually meaningful.
// This should only happen for stack slots which are conservatively reported, and for better perf
// we completely skip reporting them.
if (pObjRef == (OBJECTREF*)NULL)
{
_ASSERTE((gcFlags & (GC_CALL_PINNED | GC_CALL_INTERIOR)) == (GC_CALL_PINNED | GC_CALL_INTERIOR));
return;
}
#endif // FEATURE_INTERPRETER
#ifdef _DEBUG
LOG((LF_GCROOTS, LL_INFO1000, /* Part One */
"Reporting %s" FMT_STK,
Expand Down
1 change: 1 addition & 0 deletions src/tests/GC/API/GC/Collect0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

public class Test_Collect0 {
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/118965", typeof(TestLibrary.Utilities), nameof(TestLibrary.Utilities.IsCoreClrInterpreter))]
public static int TestEntryPoint() {

int[] array = new int[25];
Expand Down
1 change: 1 addition & 0 deletions src/tests/GC/API/GC/Collect0.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Collect0.cs" />
<ProjectReference Include="$(TestLibraryProjectPath)" />
</ItemGroup>
</Project>