Skip to content
Open
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
21 changes: 11 additions & 10 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3962,7 +3962,8 @@ CLR_BOOL SfiNextWorker(StackFrameIterator* pThis, uint* uExCollideClauseIdx, CLR
InterpreterFrame *pInterpreterFrame = (InterpreterFrame *)pThis->m_crawl.GetFrame();
// If the GetReturnAddress returns 0, it means the caller is InterpreterCodeManager::CallFunclet.
// We don't have any TransitionFrame to update the regdisplay from in that case.
if (pInterpreterFrame->GetReturnAddress() != 0)
PCODE returnAddress = pInterpreterFrame->GetReturnAddress();
if (returnAddress != 0)
{
// The callerIP is InterpreterFrame::DummyCallerIP when we are going to unwind from the first interpreted frame belonging to an InterpreterFrame.
// That means it is at a transition where non-interpreted code called interpreted one.
Expand All @@ -3971,18 +3972,18 @@ CLR_BOOL SfiNextWorker(StackFrameIterator* pThis, uint* uExCollideClauseIdx, CLR
_ASSERTE(retVal != SWA_FAILED);
_ASSERTE(pThis->GetFrameState() == StackFrameIterator::SFITER_FRAME_FUNCTION);
_ASSERTE(pThis->m_crawl.GetFrame()->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame);
// Move to the caller of the interpreted code
retVal = pThis->Next();
_ASSERTE(retVal != SWA_FAILED);
if (pThis->GetFrameState() != StackFrameIterator::SFITER_FRAMELESS_METHOD)
if (ExecutionManager::IsManagedCode(returnAddress))
{
// The caller is a managed code, so we can update the regdisplay to point to it.
pInterpreterFrame->UpdateRegDisplay(pThis->m_crawl.GetRegisterSet(), /* updateFloats */ true);
}
// The caller of the interpreted code is a managed code
retVal = pThis->Next();
_ASSERTE(retVal != SWA_FAILED);
_ASSERTE(pThis->GetFrameState() == StackFrameIterator::SFITER_FRAMELESS_METHOD);
isNativeTransition = false;
}
else
{
// The caller of the interpreted code is managed.
isNativeTransition = false;
// The caller is native code, so we can update the regdisplay to point to it.
pInterpreterFrame->UpdateRegDisplay(pThis->m_crawl.GetRegisterSet(), /* updateFloats */ true);
}
}
}
Expand Down
38 changes: 36 additions & 2 deletions src/coreclr/vm/interpexec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,40 @@ static void CallPreStub(MethodDesc *pMD)
PAL_ENDTRY
}

MethodDesc* CallGetMethodDescOfVirtualizedCode(MethodDesc *pMD, OBJECTREF *orThis)
{
STATIC_STANDARD_VM_CONTRACT;
_ASSERTE(pMD != NULL);

struct Param
{
MethodDesc *pMD;
OBJECTREF *orThis;
MethodDesc *pRetMD;
}
param = { pMD, orThis, NULL };

PAL_TRY(Param *, pParam, &param)
{
pParam->pRetMD = pParam->pMD->GetMethodDescOfVirtualizedCode(pParam->orThis, pParam->pMD->GetMethodTable());
}
PAL_EXCEPT_FILTER(IgnoreCppExceptionFilter)
{
// There can be both C++ (thrown by the COMPlusThrow) and managed exceptions thrown
// from the GetMethodDescOfVirtualizedCode call chain.
// We need to process only managed ones here, the C++ ones are handled by the
// INSTALL_/UNINSTALL_UNWIND_AND_CONTINUE_HANDLER in the InterpExecMethod.
// The managed ones are represented by SEH exception, which cannot be handled there
// because it is not possible to handle both SEH and C++ exceptions in the same frame.
GCX_COOP_NO_DTOR();
OBJECTREF ohThrowable = GetThread()->LastThrownObject();
DispatchManagedException(ohThrowable);
}
PAL_ENDTRY

return param.pRetMD;
}

void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFrame *pFrame, InterpThreadContext *pThreadContext, ExceptionClauseArgs *pExceptionClauseArgs)
{
CONTRACTL
Expand Down Expand Up @@ -2419,7 +2453,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
// Interpreter-TODO
// This needs to be optimized, not operating at MethodDesc level, rather with ftnptr
// slots containing the interpreter IR pointer
targetMethod = pMD->GetMethodDescOfVirtualizedCode(pThisArg, pMD->GetMethodTable());
targetMethod = CallGetMethodDescOfVirtualizedCode(pMD, pThisArg);
ip += 4;
goto CALL_INTERP_METHOD;
}
Expand Down Expand Up @@ -2560,7 +2594,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
if (isOpenVirtual)
{
targetMethod = COMDelegate::GetMethodDescForOpenVirtualDelegate(*delegateObj);
targetMethod = targetMethod->GetMethodDescOfVirtualizedCode(LOCAL_VAR_ADDR(callArgsOffset + INTERP_STACK_SLOT_SIZE, OBJECTREF), targetMethod->GetMethodTable());
targetMethod = CallGetMethodDescOfVirtualizedCode(targetMethod, LOCAL_VAR_ADDR(callArgsOffset + INTERP_STACK_SLOT_SIZE, OBJECTREF));
}
else
{
Expand Down
Loading