diff --git a/src/coreclr/vm/FrameTypes.h b/src/coreclr/vm/FrameTypes.h index 83a4e0aa6de455..af90d964bfd816 100644 --- a/src/coreclr/vm/FrameTypes.h +++ b/src/coreclr/vm/FrameTypes.h @@ -30,6 +30,7 @@ FRAME_TYPE_NAME(HijackFrame) FRAME_TYPE_NAME(PrestubMethodFrame) FRAME_TYPE_NAME(CallCountingHelperFrame) FRAME_TYPE_NAME(StubDispatchFrame) +FRAME_TYPE_NAME(CodePointerLookupFrame) FRAME_TYPE_NAME(ExternalMethodFrame) FRAME_TYPE_NAME(DynamicHelperFrame) FRAME_TYPE_NAME(ProtectValueClassFrame) diff --git a/src/coreclr/vm/frames.cpp b/src/coreclr/vm/frames.cpp index 11b48a3f227908..a6257498a52f24 100644 --- a/src/coreclr/vm/frames.cpp +++ b/src/coreclr/vm/frames.cpp @@ -952,6 +952,29 @@ Frame::Interception StubDispatchFrame::GetInterception_Impl() return INTERCEPTION_NONE; } +#ifndef DACCESS_COMPILE +CodePointerLookupFrame::CodePointerLookupFrame(TransitionBlock * pTransitionBlock) + : TransitionFrame(FrameIdentifier::CodePointerLookupFrame), m_pTransitionBlock(dac_cast(pTransitionBlock)) +{ + LIMITED_METHOD_CONTRACT; + + m_pZapModule = NULL; + m_pIndirection = (TADDR)NULL; +} +#endif + +BOOL CodePointerLookupFrame::TraceFrame_Impl(Thread *thread, BOOL fromPatch, + TraceDestination *trace, REGDISPLAY *regs) +{ + WRAPPER_NO_CONTRACT; + + // CodePointerLookupFrame is used for interface dispatch resolution and never directly calls managed code. + // Returning false instructs the debugger to step out of the call that erected this frame. + LOG((LF_CORDB, LL_INFO1000, "CodePointerLookupFrame::TraceFrame: return FALSE\n")); + + return FALSE; +} + #ifndef DACCESS_COMPILE CallCountingHelperFrame::CallCountingHelperFrame(TransitionBlock *pTransitionBlock, MethodDesc *pMD) : FramedMethodFrame(FrameIdentifier::CallCountingHelperFrame, pTransitionBlock, pMD) diff --git a/src/coreclr/vm/frames.h b/src/coreclr/vm/frames.h index 5491e238918411..3810aa44386c35 100644 --- a/src/coreclr/vm/frames.h +++ b/src/coreclr/vm/frames.h @@ -1723,6 +1723,70 @@ struct cdac_data typedef DPTR(class StubDispatchFrame) PTR_StubDispatchFrame; +//------------------------------------------------------------------------ +// CodePointerLookupFrame is used for resolving interface dispatch calls. +// Unlike StubDispatchFrame, it inherits directly from TransitionFrame to +// avoid double GC reporting of argument registers. The calling code handles +// GC reporting via the TransitionFrame base class. +//------------------------------------------------------------------------ + +class CodePointerLookupFrame : public TransitionFrame +{ + TADDR m_pTransitionBlock; + + // Indirection cell and containing module. + PTR_Module m_pZapModule; + TADDR m_pIndirection; + +public: + CodePointerLookupFrame(TransitionBlock * pTransitionBlock); + + TADDR GetTransitionBlock_Impl() + { + LIMITED_METHOD_DAC_CONTRACT; + return m_pTransitionBlock; + } + +#ifndef DACCESS_COMPILE + void SetCallSite(Module * pZapModule, TADDR pIndirection) + { + LIMITED_METHOD_CONTRACT; + + m_pZapModule = pZapModule; + m_pIndirection = pIndirection; + } +#endif + + PCODE GetUnadjustedReturnAddress() + { + LIMITED_METHOD_DAC_CONTRACT; + return GetReturnAddress_Impl(); + } + + BOOL TraceFrame_Impl(Thread *thread, BOOL fromPatch, + TraceDestination *trace, REGDISPLAY *regs); + + int GetFrameType_Impl() + { + LIMITED_METHOD_CONTRACT; + return TYPE_CALL; + } + + Interception GetInterception_Impl() + { + LIMITED_METHOD_DAC_CONTRACT; + return INTERCEPTION_NONE; + } + + ETransitionType GetTransitionType_Impl() + { + LIMITED_METHOD_DAC_CONTRACT; + return TT_InternalCall; + } +}; + +typedef DPTR(class CodePointerLookupFrame) PTR_CodePointerLookupFrame; + typedef DPTR(class CallCountingHelperFrame) PTR_CallCountingHelperFrame; class CallCountingHelperFrame : public FramedMethodFrame