Skip to content
Merged
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
12 changes: 11 additions & 1 deletion src/coreclr/debug/daccess/dacdbiimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6084,8 +6084,18 @@ HRESULT DacDbiInterfaceImpl::GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pCon
// that has context available for stackwalking (SP and PC)
// For example: RedirectedThreadFrame, InlinedCallFrame, DynamicHelperFrame, CLRToCOMMethodFrame
Frame *frame = pThread->GetFrame();

while (frame != NULL && frame != FRAME_TOP)
{
#ifdef FEATURE_INTERPRETER
if (frame->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)
{
PTR_InterpreterFrame pInterpreterFrame = dac_cast<PTR_InterpreterFrame>(frame);
pInterpreterFrame->SetContextToInterpMethodContextFrame(&tmpContext);
CopyMemory(pContextBuffer, &tmpContext, sizeof(*pContextBuffer));
return S_OK;
}
#endif // FEATURE_INTERPRETER
frame->UpdateRegDisplay(&tmpRd);
if (GetRegdisplaySP(&tmpRd) != 0 && GetControlPC(&tmpRd) != 0)
{
Expand All @@ -6097,7 +6107,7 @@ HRESULT DacDbiInterfaceImpl::GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pCon
// DT_CONTEXT_CONTROL already includes the frame register for X86 and ARM64 architectures
#endif
;
return hr;
return S_OK;
}
frame = frame->Next();
}
Expand Down
23 changes: 22 additions & 1 deletion src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ HRESULT DacDbiInterfaceImpl::UnwindStackWalkFrame(StackWalkHandle pSFIHandle, OU
MethodDesc *pMD = pIter->m_crawl.GetFunction();

// EH.DispatchEx, EH.RhThrowEx, EH.RhThrowHwEx, ExceptionServices.InternalCalls.SfiInit, ExceptionServices.InternalCalls.SfiNext
if (pMD->GetMethodTable() == g_pEHClass || pMD->GetMethodTable() == g_pExceptionServicesInternalCallsClass)
// and System.Runtime.StackFrameIterator.*
if (pMD->GetMethodTable() == g_pEHClass || pMD->GetMethodTable() == g_pExceptionServicesInternalCallsClass || pMD->GetMethodTable() == g_pStackFrameIteratorClass)
{
continue;
}
Expand Down Expand Up @@ -517,6 +518,16 @@ HRESULT DacDbiInterfaceImpl::GetCountOfInternalFrames(VMPTR_Thread vmThread, OUT
continue;
}
}

#ifdef FEATURE_INTERPRETER
if (pFrame->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)
{
// Skip InterpreterFrame
pFrame = pFrame->Next();
continue;
}
#endif // FEATURE_INTERPRETER

CorDebugInternalFrameType ift = GetInternalFrameType(pFrame);
if (ift != STUBFRAME_NONE)
{
Expand Down Expand Up @@ -573,6 +584,16 @@ HRESULT DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thread vmThread, FP_I
continue;
}
}

#ifdef FEATURE_INTERPRETER
if (pFrame->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)
{
// Skip InterpreterFrame
pFrame = pFrame->Next();
continue;
}
#endif // FEATURE_INTERPRETER

// check if the internal frame is interesting
frameData.stubFrame.frameType = GetInternalFrameType(pFrame);
if (frameData.stubFrame.frameType != STUBFRAME_NONE)
Expand Down
13 changes: 12 additions & 1 deletion src/coreclr/interpreter/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,13 @@ InterpInst* InterpCompiler::NewIns(int opcode, int dataLen)
InterpInst *ins = (InterpInst*)getAllocator(IMK_Instruction).allocateZeroed<char>(insSize);
ins->opcode = opcode;
ins->ilOffset = m_currentILOffset;
if (m_isFirstInstForEmptyILStack)
{
// This is the first instruction we are emitting for this IL offset and the stack is empty, which
// implies the IL stack is empty too.
ins->flags |= INTERP_INST_FLAG_EMPTY_IL_STACK;
m_isFirstInstForEmptyILStack = false;
}
m_pLastNewIns = ins;
return ins;
}
Expand Down Expand Up @@ -1069,7 +1076,7 @@ int32_t* InterpCompiler::EmitCodeIns(int32_t *ip, InterpInst *ins, TArray<Reloc*

m_pILToNativeMap[m_ILToNativeMapSize].ilOffset = ilOffset;
m_pILToNativeMap[m_ILToNativeMapSize].nativeOffset = nativeOffset;
m_pILToNativeMap[m_ILToNativeMapSize].source = ICorDebugInfo::SOURCE_TYPE_INVALID;
m_pILToNativeMap[m_ILToNativeMapSize].source = (ins->flags & INTERP_INST_FLAG_EMPTY_IL_STACK) ? ICorDebugInfo::STACK_EMPTY : ICorDebugInfo::SOURCE_TYPE_INVALID;
m_ILToNativeMapSize++;
}
}
Expand Down Expand Up @@ -8379,6 +8386,10 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
if (ILOpcodePeeps.FindAndApplyPeep(this))
continue;


// Empty stack at the beginning of the IL instruction implies IL stack being empty too
m_isFirstInstForEmptyILStack = (m_pStackPointer - m_pStackBase) == 0;

uint8_t opcode = *m_ip;
switch (opcode)
{
Expand Down
9 changes: 7 additions & 2 deletions src/coreclr/interpreter/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ enum InterpInstFlags
{
INTERP_INST_FLAG_CALL = 0x01,
// Flag used internally by the var offset allocator
INTERP_INST_FLAG_ACTIVE_CALL = 0x02
INTERP_INST_FLAG_ACTIVE_CALL = 0x02,
// The IL stack is empty at this instruction
INTERP_INST_FLAG_EMPTY_IL_STACK = 0x04
};

struct InterpInst
Expand Down Expand Up @@ -670,6 +672,9 @@ class InterpCompiler
int32_t m_currentILOffset;
InterpInst* m_pInitLocalsIns;

// Indicates that we are going to generate the first interpreter byte code instruction for an IL opcode with an empty stack.
bool m_isFirstInstForEmptyILStack = true;

// If the method has a hidden argument, GenerateCode allocates a var to store it and
// populates the var at method entry
int32_t m_hiddenArgumentVar;
Expand Down Expand Up @@ -819,7 +824,7 @@ class InterpCompiler
private:
// Instructions
InterpBasicBlock *m_pCBB, *m_pEntryBB;
InterpInst* m_pLastNewIns;
InterpInst* m_pLastNewIns = nullptr;

int32_t GetInsLength(InterpInst *pIns);
bool InsIsNop(InterpInst *pIns);
Expand Down
10 changes: 6 additions & 4 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3188,7 +3188,7 @@ void CallCatchFunclet(OBJECTREF throwable, BYTE* pHandlerIP, REGDISPLAY* pvRegDi
pThread->GetExceptionState()->GetDebuggerState()->GetDebuggerInterceptInfo(&pInterceptMD, NULL, (PBYTE*)&(sfInterceptStackFrame.SP), &ulRelOffset, NULL);
if (sfInterceptStackFrame.SP == GetSP(pvRegDisplay->pCurrentContext))
{
PCODE pStartAddress = pInterceptMD->GetNativeCode();
PCODE pStartAddress = pInterceptMD->GetCodeForInterpreterOrJitted();

EECodeInfo codeInfo(pStartAddress);
_ASSERTE(codeInfo.IsValid());
Expand Down Expand Up @@ -3226,7 +3226,9 @@ void CallCatchFunclet(OBJECTREF throwable, BYTE* pHandlerIP, REGDISPLAY* pvRegDi
{
if (fIntercepted)
{
ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext, targetSSP);
EECodeInfo codeInfo(GetIP(pvRegDisplay->pCurrentContext));
_ASSERTE(codeInfo.IsValid());
codeInfo.GetCodeManager()->ResumeAfterCatch(pvRegDisplay->pCurrentContext, targetSSP, /* fIntercepted */ true);
}
#ifdef HOST_UNIX
if (propagateExceptionCallback)
Expand Down Expand Up @@ -3325,7 +3327,7 @@ void ResumeAtInterceptionLocation(REGDISPLAY* pvRegDisplay)

ExInfo::PopExInfos(pThread, (void*)targetSp);

PCODE pStartAddress = pInterceptMD->GetNativeCode();
PCODE pStartAddress = pInterceptMD->GetCodeForInterpreterOrJitted();

EECodeInfo codeInfo(pStartAddress);
_ASSERTE(codeInfo.IsValid());
Expand All @@ -3338,7 +3340,7 @@ void ResumeAtInterceptionLocation(REGDISPLAY* pvRegDisplay)
SetIP(pvRegDisplay->pCurrentContext, uResumePC);

STRESS_LOG2(LF_EH, LL_INFO100, "Resuming at interception location at IP=%p, SP=%p\n", uResumePC, GetSP(pvRegDisplay->pCurrentContext));
ClrRestoreNonvolatileContext(pvRegDisplay->pCurrentContext, targetSSP);
codeInfo.GetCodeManager()->ResumeAfterCatch(pvRegDisplay->pCurrentContext, targetSSP, /* fIntercepted */ true);
}

void CallFinallyFunclet(BYTE* pHandlerIP, REGDISPLAY* pvRegDisplay, ExInfo* exInfo)
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/vm/frames.h
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,12 @@ class InterpreterFrame : public FramedMethodFrame
m_isFaulting = isFaulting;
}

Interception GetInterception_Impl()
{
LIMITED_METHOD_DAC_CONTRACT;
return m_isFaulting ? INTERCEPTION_EXCEPTION : INTERCEPTION_NONE;
}

void GcScanRoots_Impl(promote_func *fn, ScanContext* sc)
{
fn(dac_cast<PTR_PTR_Object>(dac_cast<TADDR>(&m_continuation)), sc, 0);
Expand Down
Loading