diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs index b7095c3579a0e7..a7fa028e9cb338 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs @@ -54,14 +54,19 @@ class AsmOffsets #if TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x8; - public const int SIZEOF__StackFrameIterator = 0x358; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x33A; - public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x350; + public const int SIZEOF__StackFrameIterator = 0x150; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x132; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x148; +#elif TARGET_X86 + public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; + public const int SIZEOF__StackFrameIterator = 0x3c4; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x3b2; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c0; #else // TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; - public const int SIZEOF__StackFrameIterator = 0x2c8; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x2b6; - public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x2c4; + public const int SIZEOF__StackFrameIterator = 0xc4; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc0; #endif // TARGET_64BIT #else // DEBUG @@ -106,14 +111,19 @@ class AsmOffsets #if TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x8; - public const int SIZEOF__StackFrameIterator = 0x350; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x332; - public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x348; + public const int SIZEOF__StackFrameIterator = 0x148; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x12a; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x140; +#elif TARGET_X86 + public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; + public const int SIZEOF__StackFrameIterator = 0x3bc; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x3aa; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3b8; #else // TARGET_64BIT public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4; - public const int SIZEOF__StackFrameIterator = 0x2c0; - public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x2ae; - public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x2bc; + public const int SIZEOF__StackFrameIterator = 0xbc; + public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xaa; + public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xb8; #endif // TARGET_64BIT #endif // DEBUG @@ -164,7 +174,7 @@ class AsmOffsets #if TARGET_64BIT public const int SIZEOF__EHEnum = 0x20; - public const int OFFSETOF__StackFrameIterator__m_pRegDisplay = 0x228; + public const int OFFSETOF__StackFrameIterator__m_pRegDisplay = 0x20; public const int OFFSETOF__ExInfo__m_pPrevExInfo = 0; public const int OFFSETOF__ExInfo__m_pExContext = 0xa8; public const int OFFSETOF__ExInfo__m_exception = 0xb0; @@ -175,7 +185,7 @@ class AsmOffsets public const int OFFSETOF__ExInfo__m_notifyDebuggerSP = OFFSETOF__ExInfo__m_frameIter + SIZEOF__StackFrameIterator; #else // TARGET_64BIT public const int SIZEOF__EHEnum = 0x10; - public const int OFFSETOF__StackFrameIterator__m_pRegDisplay = 0x218; + public const int OFFSETOF__StackFrameIterator__m_pRegDisplay = 0x14; public const int OFFSETOF__ExInfo__m_pPrevExInfo = 0; public const int OFFSETOF__ExInfo__m_pExContext = 0x5c; public const int OFFSETOF__ExInfo__m_exception = 0x60; @@ -224,7 +234,7 @@ class AsmOffsets static_assert_no_msg(offsetof(ExInfo, m_idxCurClause) == OFFSETOF__ExInfo__m_idxCurClause); static_assert_no_msg(offsetof(ExInfo, m_frameIter) == OFFSETOF__ExInfo__m_frameIter); static_assert_no_msg(offsetof(ExInfo, m_notifyDebuggerSP) == OFFSETOF__ExInfo__m_notifyDebuggerSP); -#endif +#endif } #if __cplusplus diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp index e14e39d9a0ca90..7e46a16ce773e3 100644 --- a/src/coreclr/debug/ee/controller.cpp +++ b/src/coreclr/debug/ee/controller.cpp @@ -5938,7 +5938,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in) #ifdef TARGET_X86 LOG((LF_CORDB,LL_INFO1000, "GetJitInfo for pc = 0x%x (addr of " "that value:0x%x)\n", (const BYTE*)(GetControlPC(&info->m_activeFrame.registers)), - info->m_activeFrame.registers.PCTAddr)); + GetRegdisplayPCTAddr(&info->m_activeFrame.registers))); #endif // Note: we used to pass in the IP from the active frame to GetJitInfo, but there seems to be no value in that, and diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp index 0f984d3fc998d8..049c16c72fad63 100644 --- a/src/coreclr/debug/ee/debugger.cpp +++ b/src/coreclr/debug/ee/debugger.cpp @@ -16858,21 +16858,19 @@ void FuncEvalFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa pRD->SetEcxLocation(&(pDE->m_context.Ecx)); pRD->SetEaxLocation(&(pDE->m_context.Eax)); pRD->SetEbpLocation(&(pDE->m_context.Ebp)); - pRD->PCTAddr = GetReturnAddressPtr(); + SetRegdisplayPCTAddr(pRD, GetReturnAddressPtr()); #ifdef FEATURE_EH_FUNCLETS pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr); pRD->pCurrentContext->Esp = (DWORD)GetSP(&pDE->m_context); SyncRegDisplayToCurrentContext(pRD); #else // FEATURE_EH_FUNCLETS - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); pRD->SP = (DWORD)GetSP(&pDE->m_context); #endif // FEATURE_EH_FUNCLETS diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h index 71e78c539b19bb..8dfd26356440cd 100644 --- a/src/coreclr/inc/eetwain.h +++ b/src/coreclr/inc/eetwain.h @@ -65,18 +65,6 @@ typedef void (*GCEnumCallback)( DAC_ARG(DacSlotLocation loc) // where the reference came from ); -/****************************************************************************** - The stackwalker maintains some state on behalf of ICodeManager. -*/ - -const int CODEMAN_STATE_SIZE = 512; - -struct CodeManState -{ - DWORD dwIsSet; // Is set to 0 by the stackwalk as appropriate - BYTE stateBuf[CODEMAN_STATE_SIZE]; -}; - /****************************************************************************** These flags are used by some functions, although not all combinations might make sense for all functions. @@ -169,7 +157,6 @@ virtual void FixContext(ContextType ctxType, DWORD dwRelOffset, DWORD nestingLevel, OBJECTREF thrownObject, - CodeManState *pState, size_t ** ppShadowSP, // OUT size_t ** ppEndRegion) = 0; // OUT #endif // !FEATURE_EH_FUNCLETS @@ -183,8 +170,7 @@ virtual void FixContext(ContextType ctxType, virtual TADDR GetAmbientSP(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, DWORD dwRelOffset, - DWORD nestingLevel, - CodeManState *pState) = 0; + DWORD nestingLevel) = 0; #endif // TARGET_X86 /* @@ -203,8 +189,7 @@ virtual ULONG32 GetStackParameterSize(EECodeInfo* pCodeInfo) = 0; */ virtual bool UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) = 0; + unsigned flags) = 0; #ifdef FEATURE_EH_FUNCLETS virtual void EnsureCallerContextIsValid(PREGDISPLAY pRD, EECodeInfo * pCodeInfo = NULL, unsigned flags = 0) = 0; @@ -265,8 +250,7 @@ virtual GenericParamContextType GetParamContextType(PREGDISPLAY pContext, */ virtual void * GetGSCookieAddr(PREGDISPLAY pContext, EECodeInfo * pCodeInfo, - unsigned flags, - CodeManState * pState) = 0; + unsigned flags) = 0; #ifndef USE_GC_INFO_DECODER /* @@ -378,7 +362,6 @@ void FixContext(ContextType ctxType, DWORD dwRelOffset, DWORD nestingLevel, OBJECTREF thrownObject, - CodeManState *pState, size_t ** ppShadowSP, // OUT size_t ** ppEndRegion); // OUT #endif // !FEATURE_EH_FUNCLETS @@ -393,8 +376,7 @@ virtual TADDR GetAmbientSP(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, DWORD dwRelOffset, - DWORD nestingLevel, - CodeManState *pState); + DWORD nestingLevel); #endif // TARGET_X86 /* @@ -416,8 +398,7 @@ virtual bool UnwindStackFrame( PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState); + unsigned flags); #ifdef HAS_LIGHTUNWIND enum LightUnwindFlag @@ -515,8 +496,7 @@ PTR_VOID GetExactGenericsToken(SIZE_T baseStackSlot, virtual void * GetGSCookieAddr(PREGDISPLAY pContext, EECodeInfo * pCodeInfo, - unsigned flags, - CodeManState * pState); + unsigned flags); #ifndef USE_GC_INFO_DECODER @@ -606,21 +586,6 @@ HRESULT FixContextForEnC(PCONTEXT pCtx, }; -#ifdef TARGET_X86 -#include "gc_unwind_x86.h" - -/***************************************************************************** - How the stackwalkers buffer will be interpreted -*/ - -struct CodeManStateBuf -{ - DWORD hdrInfoSize; - hdrInfo hdrInfoBody; -}; - -#endif - #ifdef FEATURE_INTERPRETER class InterpreterCodeManager : public ICodeManager { @@ -639,7 +604,6 @@ void FixContext(ContextType ctxType, DWORD dwRelOffset, DWORD nestingLevel, OBJECTREF thrownObject, - CodeManState *pState, size_t ** ppShadowSP, // OUT size_t ** ppEndRegion) // OUT { @@ -658,8 +622,7 @@ virtual TADDR GetAmbientSP(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, DWORD dwRelOffset, - DWORD nestingLevel, - CodeManState *pState) + DWORD nestingLevel) { // Interpreter-TODO: Implement this if needed _ASSERTE(FALSE); @@ -677,8 +640,7 @@ virtual bool UnwindStackFrame( PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState); + unsigned flags); #ifdef FEATURE_EH_FUNCLETS virtual @@ -721,8 +683,7 @@ virtual GenericParamContextType GetParamContextType(PREGDISPLAY pContext, virtual void * GetGSCookieAddr(PREGDISPLAY pContext, EECodeInfo * pCodeInfo, - unsigned flags, - CodeManState * pState) + unsigned flags) { return NULL; } diff --git a/src/coreclr/inc/gc_unwind_x86.h b/src/coreclr/inc/gc_unwind_x86.h index 2430254e40ea61..311c032c9ccc9d 100644 --- a/src/coreclr/inc/gc_unwind_x86.h +++ b/src/coreclr/inc/gc_unwind_x86.h @@ -351,7 +351,7 @@ struct hdrInfo bool isSpeculativeStackWalk; // is the stackwalk seeded by an untrusted source (e.g., sampling profiler)? // These always includes EBP for EBP-frames and double-aligned-frames - RegMask savedRegMask:8; // which callee-saved regs are saved on stack + RegMask savedRegMask; // which callee-saved regs are saved on stack // Count of the callee-saved registers, excluding the frame pointer. // This does not include EBP for EBP-frames and double-aligned-frames. @@ -397,6 +397,8 @@ bool UnwindStackFrameX86(PREGDISPLAY pContext, IN_EH_FUNCLETS_COMMA(bool isFunclet) bool updateAllRegs); +unsigned int DecodeGCHdrInfoMethodSize(GCInfoToken gcInfoToken); + size_t DecodeGCHdrInfo(GCInfoToken gcInfoToken, unsigned curOffset, hdrInfo * infoPtr); diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index 33ad56d9d28e72..59944c23c5cefa 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -135,9 +135,17 @@ inline LPVOID GetRegdisplayFPAddress(REGDISPLAY *display) { return (LPVOID)display->GetEbpLocation(); } +inline TADDR GetRegdisplayPCTAddr(REGDISPLAY *display) +{ + return display->PCTAddr; +} + inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr) { display->PCTAddr = addr; +#ifdef FEATURE_EH_FUNCLETS + display->pCurrentContext->Eip = *PTR_PCODE(addr); +#endif display->ControlPC = *PTR_PCODE(addr); } @@ -145,13 +153,12 @@ inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr) // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) { LIMITED_METHOD_CONTRACT; - - return (TADDR)stackPointer < display->PCTAddr; + return (TADDR)stackPointer < GetRegdisplayPCTAddr(display); } inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) { LIMITED_METHOD_DAC_CONTRACT; - return display->PCTAddr; + return GetRegdisplayPCTAddr(display); } #elif defined(TARGET_64BIT) diff --git a/src/coreclr/unwinder/i386/unwinder.cpp b/src/coreclr/unwinder/i386/unwinder.cpp index deb385c2659f6f..4ad7cfeccc0ff6 100644 --- a/src/coreclr/unwinder/i386/unwinder.cpp +++ b/src/coreclr/unwinder/i386/unwinder.cpp @@ -13,9 +13,6 @@ BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTE FillRegDisplay(&rd, pContextRecord); - rd.SP = pContextRecord->Esp; - rd.PCTAddr = (UINT_PTR)&(pContextRecord->Eip); - if (pContextPointers) { rd.pCurrentContextPointers = pContextPointers; @@ -26,15 +23,14 @@ BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTE EECodeInfo codeInfo; codeInfo.Init((PCODE) ControlPc); - GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, codeInfo.GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + PTR_CBYTE table = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); if (!UnwindStackFrameX86(&rd, PTR_CBYTE(codeInfo.GetSavedMethodCode()), codeInfo.GetRelOffset(), - &hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + hdrInfoBody, + table, PTR_CBYTE(codeInfo.GetJitManager()->GetFuncletStartAddress(&codeInfo)), codeInfo.IsFunclet(), true)) diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 986ad82abd3dba..f15202bc321eff 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -67,6 +67,9 @@ Module Name: #include "pedecoder.h" #include "gcinfo.h" #include "eexcp.h" +#ifdef TARGET_X86 +#include "gc_unwind_x86.h" +#endif class MethodDesc; class ICorJitCompiler; @@ -2902,6 +2905,8 @@ class EECodeInfo WRAPPER_NO_CONTRACT; return GetCodeManager()->GetFrameSize(GetGCInfoToken()); } + + PTR_CBYTE DecodeGCHdrInfo(hdrInfo ** infoPtr); #endif // TARGET_X86 #if defined(TARGET_WASM) @@ -2926,6 +2931,11 @@ ULONG GetFixedStackSize(); PTR_RUNTIME_FUNCTION m_pFunctionEntry; #endif // FEATURE_EH_FUNCLETS +#ifdef TARGET_X86 + PTR_CBYTE m_hdrInfoTable; + hdrInfo m_hdrInfoBody; +#endif + #ifdef TARGET_AMD64 // Simple helper to return a pointer to the UNWIND_INFO given the offset to the unwind info. UNWIND_INFO * GetUnwindInfoHelper(ULONG unwindInfoOffset); diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 9009fd2d048b3a..743511eea2092a 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -57,7 +57,6 @@ void EECodeManager::FixContext( ContextType ctxType, DWORD dwRelOffset, DWORD nestingLevel, OBJECTREF thrownObject, - CodeManState *pState, size_t ** ppShadowSP, size_t ** ppEndRegion) { @@ -68,21 +67,15 @@ void EECodeManager::FixContext( ContextType ctxType, _ASSERTE((ctxType == FINALLY_CONTEXT) == (thrownObject == NULL)); - _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); - CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; - /* Extract the necessary information from the info block header */ - - stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(), - dwRelOffset, - &stateBuf->hdrInfoBody); - pState->dwIsSet = 1; + hdrInfo *hdrInfoBody; + pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); #ifdef _DEBUG if (trFixContext) { minipal_log_print_info("FixContext [%s][%s] for %s.%s: ", - stateBuf->hdrInfoBody.ebpFrame?"ebp":" ", - stateBuf->hdrInfoBody.interruptible?"int":" ", + hdrInfoBody->ebpFrame?"ebp":" ", + hdrInfoBody->interruptible?"int":" ", "UnknownClass","UnknownMethod"); minipal_log_flush_info(); } @@ -90,11 +83,11 @@ void EECodeManager::FixContext( ContextType ctxType, /* make sure that we have an ebp stack frame */ - _ASSERTE(stateBuf->hdrInfoBody.ebpFrame); - _ASSERTE(stateBuf->hdrInfoBody.handlers); // @TODO : This will always be set. Remove it + _ASSERTE(hdrInfoBody->ebpFrame); + _ASSERTE(hdrInfoBody->handlers); // @TODO : This will always be set. Remove it TADDR baseSP; - GetHandlerFrameInfo(&stateBuf->hdrInfoBody, ctx->Ebp, + GetHandlerFrameInfo(hdrInfoBody, ctx->Ebp, ctxType == FILTER_CONTEXT ? ctx->Esp : IGNORE_VAL, ctxType == FILTER_CONTEXT ? (DWORD) IGNORE_VAL : nestingLevel, &baseSP, @@ -108,7 +101,7 @@ void EECodeManager::FixContext( ContextType ctxType, // EE will write Esp to **pShadowSP before jumping to handler PTR_TADDR pBaseSPslots = - GetFirstBaseSPslotPtr(ctx->Ebp, &stateBuf->hdrInfoBody); + GetFirstBaseSPslotPtr(ctx->Ebp, hdrInfoBody); *ppShadowSP = (size_t *)&pBaseSPslots[-(int) nestingLevel ]; pBaseSPslots[-(int)(nestingLevel+1)] = 0; // Zero out the next slot @@ -189,39 +182,34 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, /* Extract the necessary information from the info block header */ - hdrInfo oldInfo, newInfo; - - DecodeGCHdrInfo(pOldCodeInfo->GetGCInfoToken(), - pOldCodeInfo->GetRelOffset(), - &oldInfo); + hdrInfo *oldInfo, *newInfo; - DecodeGCHdrInfo(pNewCodeInfo->GetGCInfoToken(), - pNewCodeInfo->GetRelOffset(), - &newInfo); + pOldCodeInfo->DecodeGCHdrInfo(&oldInfo); + pNewCodeInfo->DecodeGCHdrInfo(&newInfo); //1) Error checking up front. If we get through here, everything // else should work - if (!oldInfo.editNcontinue || !newInfo.editNcontinue) { + if (!oldInfo->editNcontinue || !newInfo->editNcontinue) { LOG((LF_ENC, LL_INFO100, "**Error** EECM::FixContextForEnC EnC_INFOLESS_METHOD\n")); return CORDBG_E_ENC_INFOLESS_METHOD; } - if (!oldInfo.ebpFrame || !newInfo.ebpFrame) { + if (!oldInfo->ebpFrame || !newInfo->ebpFrame) { LOG((LF_ENC, LL_INFO100, "**Error** EECM::FixContextForEnC Esp frames NYI\n")); return E_FAIL; // Esp frames NYI } - if (pCtx->Esp != pCtx->Ebp - oldInfo.stackSize + sizeof(DWORD)) { + if (pCtx->Esp != pCtx->Ebp - oldInfo->stackSize + sizeof(DWORD)) { LOG((LF_ENC, LL_INFO100, "**Error** EECM::FixContextForEnC stack should be empty\n")); return E_FAIL; // stack should be empty - @TODO : Barring localloc } - if (oldInfo.handlers) + if (oldInfo->handlers) { bool hasInnerFilter; TADDR baseSP; - FrameType frameType = GetHandlerFrameInfo(&oldInfo, pCtx->Ebp, + FrameType frameType = GetHandlerFrameInfo(oldInfo, pCtx->Ebp, pCtx->Esp, IGNORE_VAL, &baseSP, NULL, &hasInnerFilter); _ASSERTE(frameType != FR_INVALID); @@ -234,7 +222,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, /* @TODO : What if the new method offset is in a fuclet, and the old is not, or the nesting level changed, etc */ - if (oldInfo.stackSize != newInfo.stackSize) { + if (oldInfo->stackSize != newInfo->stackSize) { LOG((LF_ENC, LL_INFO100, "**Error** EECM::FixContextForEnC stack size mismatch\n")); return CORDBG_E_ENC_IN_FUNCLET; } @@ -242,11 +230,11 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, } /* @TODO: Check if we have grown out of space for locals, in the face of localloc */ - _ASSERTE(!oldInfo.localloc && !newInfo.localloc); + _ASSERTE(!oldInfo->localloc && !newInfo->localloc); // @TODO: If nesting level grows above the MAX_EnC_HANDLER_NESTING_LEVEL, // we should return EnC_NESTED_HANLDERS - _ASSERTE(oldInfo.handlers && newInfo.handlers); + _ASSERTE(oldInfo->handlers && newInfo->handlers); LOG((LF_ENC, LL_INFO100, "EECM::FixContextForEnC: Checks out\n")); @@ -591,15 +579,15 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, /*------------------------------------------------------------------------- * Adjust the stack height */ - pCtx->Esp -= (newInfo.stackSize - oldInfo.stackSize); + pCtx->Esp -= (newInfo->stackSize - oldInfo->stackSize); // Zero-init the local and tempory section of new stack frame being careful to avoid // touching anything in the frame header. // This is necessary to ensure that any JIT temporaries in the old version can't be mistaken // for ObjRefs now. - size_t frameHeaderSize = GetSizeOfFrameHeaderForEnC( &newInfo ); - _ASSERTE( frameHeaderSize <= oldInfo.stackSize ); - _ASSERTE( GetSizeOfFrameHeaderForEnC( &oldInfo ) == frameHeaderSize ); + size_t frameHeaderSize = GetSizeOfFrameHeaderForEnC( newInfo ); + _ASSERTE( frameHeaderSize <= oldInfo->stackSize ); + _ASSERTE( GetSizeOfFrameHeaderForEnC( oldInfo ) == frameHeaderSize ); #elif defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI) @@ -710,7 +698,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, // Normal locals must occur after the header on the stack _ASSERTE( unsigned(-varLoc.vlStk.vlsOffset) >= frameHeaderSize ); // Value must occur before the top of the stack - _ASSERTE( unsigned(-varLoc.vlStk.vlsOffset) < newInfo.stackSize ); + _ASSERTE( unsigned(-varLoc.vlStk.vlsOffset) < newInfo->stackSize ); } // Ideally we'd like to verify that the stack locals (if any) start at exactly the end @@ -774,7 +762,7 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, // Clear the local and temporary stack space #if defined(TARGET_X86) - memset((void*)(size_t)(pCtx->Esp), 0, newInfo.stackSize - frameHeaderSize ); + memset((void*)(size_t)(pCtx->Esp), 0, newInfo->stackSize - frameHeaderSize ); #elif defined(TARGET_AMD64) || defined(TARGET_ARM64) memset((void*)newStackBase, 0, newFixedStackSize - frameHeaderSize); @@ -895,25 +883,18 @@ bool EECodeManager::IsGcSafe( EECodeInfo *pCodeInfo, SUPPORTS_DAC; } CONTRACTL_END; - hdrInfo info; - BYTE * table; + hdrInfo *info; /* Extract the necessary information from the info block header */ - table = (BYTE *)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(), - dwRelOffset, - &info); + pCodeInfo->DecodeGCHdrInfo(&info); /* workaround: prevent interruption within prolog/epilog */ - if (info.prologOffs != hdrInfo::NOT_IN_PROLOG || info.epilogOffs != hdrInfo::NOT_IN_EPILOG) + if (info->prologOffs != hdrInfo::NOT_IN_PROLOG || info->epilogOffs != hdrInfo::NOT_IN_EPILOG) return false; -#if VERIFY_GC_TABLES - _ASSERTE(*castto(table, unsigned short *)++ == 0xBEEF); -#endif - - return (info.interruptible); + return (info->interruptible); } #endif // !USE_GC_INFO_DECODER @@ -1058,23 +1039,14 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) PTR_CBYTE methodStart = PTR_CBYTE(codeInfo.GetSavedMethodCode()); - GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken(); - PTR_VOID methodInfoPtr = gcInfoToken.Info; DWORD curOffs = codeInfo.GetRelOffset(); - CodeManStateBuf stateBuf; - - stateBuf.hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, - curOffs, - &stateBuf.hdrInfoBody); - - PTR_CBYTE table = dac_cast(methodInfoPtr) + stateBuf.hdrInfoSize; - - hdrInfo *info = &stateBuf.hdrInfoBody; + hdrInfo *hdrInfoBody; + PTR_CBYTE table = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); - _ASSERTE(info->epilogOffs == hdrInfo::NOT_IN_EPILOG && info->prologOffs == hdrInfo::NOT_IN_PROLOG); + _ASSERTE(hdrInfoBody->epilogOffs == hdrInfo::NOT_IN_EPILOG && hdrInfoBody->prologOffs == hdrInfo::NOT_IN_PROLOG); - bool isESPFrame = !info->ebpFrame && !info->doubleAlign; + bool isESPFrame = !hdrInfoBody->ebpFrame && !hdrInfoBody->doubleAlign; if (codeInfo.IsFunclet()) { @@ -1085,11 +1057,11 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) if (isESPFrame) { const size_t curESP = (size_t)(pContext->Esp); - return curESP + GetPushedArgSize(info, table, curOffs); + return curESP + GetPushedArgSize(hdrInfoBody, table, curOffs); } const size_t curEBP = (size_t)(pContext->Ebp); - return GetOutermostBaseFP(curEBP, info); + return GetOutermostBaseFP(curEBP, hdrInfoBody); } #endif // TARGET_X86 #endif // FEATURE_EH_FUNCLETS @@ -1108,8 +1080,7 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) + unsigned flags) { CONTRACTL { NOTHROW; @@ -1124,32 +1095,15 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, PCODE breakPC = pRD->ControlPC; _ASSERTE(PCODEToPINSTR(breakPC) == pCodeInfo->GetCodeAddress()); - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - PTR_VOID methodInfoPtr = gcInfoToken.Info; - DWORD curOffs = pCodeInfo->GetRelOffset(); - - _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); - CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; - - if (pState->dwIsSet == 0) - { - /* Extract the necessary information from the info block header */ - - stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, - curOffs, - &stateBuf->hdrInfoBody); - } - - PTR_CBYTE table = dac_cast(methodInfoPtr) + stateBuf->hdrInfoSize; - - hdrInfo * info = &stateBuf->hdrInfoBody; + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - info->isSpeculativeStackWalk = ((flags & SpeculativeStackwalk) != 0); + hdrInfoBody->isSpeculativeStackWalk = ((flags & SpeculativeStackwalk) != 0); return UnwindStackFrameX86(pRD, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), - curOffs, - info, + pCodeInfo->GetRelOffset(), + hdrInfoBody, table, IN_EH_FUNCLETS_COMMA(PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo))) IN_EH_FUNCLETS_COMMA(pCodeInfo->IsFunclet()) @@ -1166,8 +1120,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) + unsigned flags) { CONTRACTL { NOTHROW; @@ -1517,37 +1470,34 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, } CONTRACTL_END; #ifndef USE_GC_INFO_DECODER - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); unsigned relOffset = pCodeInfo->GetRelOffset(); - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - hdrInfo info; + PTR_CBYTE table; + hdrInfo *hdrInfoBody; unsigned stackDepth; TADDR taArgBase; /* Extract the necessary information from the info block header */ - table += DecodeGCHdrInfo(gcInfoToken, - relOffset, - &info); + table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); // We do not have accurate information in the prolog or the epilog - if (info.prologOffs != hdrInfo::NOT_IN_PROLOG || - info.epilogOffs != hdrInfo::NOT_IN_EPILOG) + if (hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || + hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG) { return NULL; } - if (info.interruptible) + if (hdrInfoBody->interruptible) { - stackDepth = scanArgRegTableI(skipToArgReg(info, table), relOffset, relOffset, &info); + stackDepth = scanArgRegTableI(skipToArgReg(*hdrInfoBody, table), relOffset, relOffset, hdrInfoBody); } else { - stackDepth = scanArgRegTable (skipToArgReg(info, table), (unsigned)relOffset, &info); + stackDepth = scanArgRegTable (skipToArgReg(*hdrInfoBody, table), (unsigned)relOffset, hdrInfoBody); } - if (info.ebpFrame) + if (hdrInfoBody->ebpFrame) { _ASSERTE(stackDepth == 0); taArgBase = GetRegdisplayFP(pContext); @@ -1561,14 +1511,14 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, // the type context via "this" need to report "this". // If it's reported for other methods, it's probably // done incorrectly. So flag such cases. - _ASSERTE(info.thisPtrResult == REGI_NA || + _ASSERTE(hdrInfoBody->thisPtrResult == REGI_NA || pCodeInfo->GetMethodDesc()->IsSynchronized() || pCodeInfo->GetMethodDesc()->AcquiresInstMethodTableFromThis()); - if (info.thisPtrResult != REGI_NA) + if (hdrInfoBody->thisPtrResult != REGI_NA) { // the register contains the Object pointer. - TADDR uRegValue = *(reinterpret_cast(getCalleeSavedReg(pContext, info.thisPtrResult))); + TADDR uRegValue = *(reinterpret_cast(getCalleeSavedReg(pContext, hdrInfoBody->thisPtrResult))); return ObjectToOBJECTREF(PTR_Object(uRegValue)); } @@ -1582,7 +1532,7 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, /* The 'this' pointer can never be located in the untracked table */ /* as we only allow pinned and byrefs in the untracked table */ - unsigned count = info.untrackedCnt; + unsigned count = hdrInfoBody->untrackedCnt; while (count-- > 0) { fastSkipSigned(table); @@ -1590,14 +1540,14 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, /* Look for the 'this' pointer in the frame variable lifetime table */ - count = info.varPtrTableSize; + count = hdrInfoBody->varPtrTableSize; unsigned tmpOffs = 0; while (count-- > 0) { unsigned varOfs = fastDecodeUnsigned(table); unsigned begOfs = tmpOffs + fastDecodeUnsigned(table); unsigned endOfs = begOfs + fastDecodeUnsigned(table); - _ASSERTE(!info.ebpFrame || (varOfs!=0)); + _ASSERTE(!hdrInfoBody->ebpFrame || (varOfs!=0)); /* Is this variable live right now? */ if (((unsigned)relOffset >= begOfs) && ((unsigned)relOffset < endOfs)) { @@ -1608,7 +1558,7 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, /* Tracked locals for EBP frames are always at negative offsets */ - if (info.ebpFrame) + if (hdrInfoBody->ebpFrame) taArgBase -= ofs; else taArgBase += ofs; @@ -1627,7 +1577,7 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, if (pCodeInfo->GetMethodDesc()->AcquiresInstMethodTableFromThis()) // Generic Context is "this" { // Untracked table must have at least one entry - this pointer - _ASSERTE(info.untrackedCnt > 0); + _ASSERTE(hdrInfoBody->untrackedCnt > 0); // The first entry must be "this" pointer int stkOffs = fastDecodeSigned(table); @@ -1653,24 +1603,19 @@ GenericParamContextType EECodeManager::GetParamContextType(PREGDISPLAY pCont #ifndef USE_GC_INFO_DECODER /* Extract the necessary information from the info block header */ - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); unsigned relOffset = pCodeInfo->GetRelOffset(); - hdrInfo info; - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += DecodeGCHdrInfo(gcInfoToken, - relOffset, - &info); + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - if (!info.genericsContext || - info.prologOffs != hdrInfo::NOT_IN_PROLOG || - info.epilogOffs != hdrInfo::NOT_IN_EPILOG) + if (!hdrInfoBody->genericsContext || + hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || + hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG) { return GENERIC_PARAM_CONTEXT_NONE; } - if (info.genericsContextIsMethodDesc) + if (hdrInfoBody->genericsContextIsMethodDesc) { return GENERIC_PARAM_CONTEXT_METHODDESC; } @@ -1715,26 +1660,21 @@ PTR_VOID EECodeManager::GetParamTypeArg(PREGDISPLAY pContext, LIMITED_METHOD_DAC_CONTRACT; #ifndef USE_GC_INFO_DECODER - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); unsigned relOffset = pCodeInfo->GetRelOffset(); /* Extract the necessary information from the info block header */ - hdrInfo info; - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += DecodeGCHdrInfo(gcInfoToken, - relOffset, - &info); + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - if (!info.genericsContext || - info.prologOffs != hdrInfo::NOT_IN_PROLOG || - info.epilogOffs != hdrInfo::NOT_IN_EPILOG) + if (!hdrInfoBody->genericsContext || + hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || + hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG) { return NULL; } TADDR fp = GetRegdisplayFP(pContext); - TADDR taParamTypeArg = *PTR_TADDR(fp - GetParamTypeArgOffset(&info)); + TADDR taParamTypeArg = *PTR_TADDR(fp - GetParamTypeArgOffset(hdrInfoBody)); return PTR_VOID(taParamTypeArg); #else // !USE_GC_INFO_DECODER @@ -1820,15 +1760,13 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T baseStackSlot, void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, EECodeInfo * pCodeInfo, - unsigned flags, - CodeManState * pState) + unsigned flags) { CONTRACTL { NOTHROW; GC_NOTRIGGER; } CONTRACTL_END; - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); unsigned relOffset = pCodeInfo->GetRelOffset(); #ifdef FEATURE_EH_FUNCLETS @@ -1847,40 +1785,32 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, #endif #ifndef USE_GC_INFO_DECODER - _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); - - CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; - /* Extract the necessary information from the info block header */ - hdrInfo * info = &stateBuf->hdrInfoBody; - stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // truncation - relOffset, - info); - - pState->dwIsSet = 1; + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - if (info->prologOffs != hdrInfo::NOT_IN_PROLOG || - info->epilogOffs != hdrInfo::NOT_IN_EPILOG || - info->gsCookieOffset == INVALID_GS_COOKIE_OFFSET) + if (hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || + hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG || + hdrInfoBody->gsCookieOffset == INVALID_GS_COOKIE_OFFSET) { return NULL; } - if (info->ebpFrame) + if (hdrInfoBody->ebpFrame) { DWORD curEBP = GetRegdisplayFP(pContext); - return PVOID(SIZE_T(curEBP - info->gsCookieOffset)); + return PVOID(SIZE_T(curEBP - hdrInfoBody->gsCookieOffset)); } else { - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info) + stateBuf->hdrInfoSize; - unsigned argSize = GetPushedArgSize(info, table, relOffset); + unsigned argSize = GetPushedArgSize(hdrInfoBody, table, relOffset); - return PVOID(SIZE_T(pContext->SP + argSize + info->gsCookieOffset)); + return PVOID(SIZE_T(pContext->SP + argSize + hdrInfoBody->gsCookieOffset)); } #else // !USE_GC_INFO_DECODER + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); GcInfoDecoder gcInfoDecoder( gcInfoToken, DECODE_GS_COOKIE @@ -1974,11 +1904,9 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken) } CONTRACTL_END; #ifndef USE_GC_INFO_DECODER - hdrInfo info; - - DecodeGCHdrInfo(gcInfoToken, 0, &info); - - return info.methodSize; + // This is called often on hot paths so use an optimized version of DecodeGCHdrInfo + // that returns just the method size (first word in the table). + return DecodeGCHdrInfoMethodSize(gcInfoToken); #else // !USE_GC_INFO_DECODER GcInfoDecoder gcInfoDecoder( @@ -2315,8 +2243,7 @@ void EECodeManager::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, DWORD dwRelOffset, - DWORD nestingLevel, - CodeManState *pState) + DWORD nestingLevel) { CONTRACTL { NOTHROW; @@ -2324,46 +2251,36 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, SUPPORTS_DAC; } CONTRACTL_END; - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - - _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); - CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - /* Extract the necessary information from the info block header */ - stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, - dwRelOffset, - &stateBuf->hdrInfoBody); - table += stateBuf->hdrInfoSize; - - pState->dwIsSet = 1; + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); #if defined(_DEBUG) && !defined(DACCESS_COMPILE) if (trFixContext) { minipal_log_print_info("GetAmbientSP [%s][%s] for %s.%s: ", - stateBuf->hdrInfoBody.ebpFrame?"ebp":" ", - stateBuf->hdrInfoBody.interruptible?"int":" ", + hdrInfoBody->ebpFrame?"ebp":" ", + hdrInfoBody->interruptible?"int":" ", "UnknownClass","UnknownMethod"); minipal_log_flush_info(); } #endif // _DEBUG && !DACCESS_COMPILE - if ((stateBuf->hdrInfoBody.prologOffs != hdrInfo::NOT_IN_PROLOG) || - (stateBuf->hdrInfoBody.epilogOffs != hdrInfo::NOT_IN_EPILOG)) + if ((hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG) || + (hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG)) { return NULL; } /* make sure that we have an ebp stack frame */ - if (stateBuf->hdrInfoBody.handlers) + if (hdrInfoBody->handlers) { - _ASSERTE(stateBuf->hdrInfoBody.ebpFrame); + _ASSERTE(hdrInfoBody->ebpFrame); TADDR baseSP; - GetHandlerFrameInfo(&stateBuf->hdrInfoBody, + GetHandlerFrameInfo(hdrInfoBody, GetRegdisplayFP(pContext), (DWORD) IGNORE_VAL, nestingLevel, @@ -2376,24 +2293,24 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, _ASSERTE(nestingLevel == 0); - if (stateBuf->hdrInfoBody.ebpFrame) + if (hdrInfoBody->ebpFrame) { - return GetOutermostBaseFP(GetRegdisplayFP(pContext), &stateBuf->hdrInfoBody); + return GetOutermostBaseFP(GetRegdisplayFP(pContext), hdrInfoBody); } TADDR baseSP = GetRegdisplaySP(pContext); - if (stateBuf->hdrInfoBody.interruptible) + if (hdrInfoBody->interruptible) { - baseSP += scanArgRegTableI(skipToArgReg(stateBuf->hdrInfoBody, table), + baseSP += scanArgRegTableI(skipToArgReg(*hdrInfoBody, table), dwRelOffset, dwRelOffset, - &stateBuf->hdrInfoBody); + hdrInfoBody); } else { - baseSP += scanArgRegTable(skipToArgReg(stateBuf->hdrInfoBody, table), + baseSP += scanArgRegTable(skipToArgReg(*hdrInfoBody, table), dwRelOffset, - &stateBuf->hdrInfoBody); + hdrInfoBody); } return baseSP; @@ -2423,19 +2340,10 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo) } #endif // FEATURE_EH_FUNCLETS - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - unsigned dwOffset = pCodeInfo->GetRelOffset(); - - CodeManState state; - state.dwIsSet = 0; - - _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(state.stateBuf)); - CodeManStateBuf * pStateBuf = reinterpret_cast(state.stateBuf); - - hdrInfo * pHdrInfo = &(pStateBuf->hdrInfoBody); - pStateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, dwOffset, pHdrInfo); + hdrInfo * hdrInfoBody; + pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - return (ULONG32)::GetStackParameterSize(pHdrInfo); + return (ULONG32)::GetStackParameterSize(hdrInfoBody); #else return 0; @@ -2469,8 +2377,7 @@ static void VirtualUnwindInterpreterCallFrame(TADDR sp, T_CONTEXT *pContext) bool InterpreterCodeManager::UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) + unsigned flags) { if (pRD->IsCallerContextValid) { diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index a4d7a61a31bddb..9c5ae1437dba48 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -3931,9 +3931,9 @@ extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollid GcInfoDecoder gcInfoDecoder(pThis->m_crawl.GetCodeInfo()->GetGCInfoToken(), DECODE_REVERSE_PINVOKE_VAR); invalidRevPInvoke = gcInfoDecoder.GetReversePInvokeFrameStackSlot() != NO_REVERSE_PINVOKE_FRAME; #else // USE_GC_INFO_DECODER - hdrInfo gcHdrInfo; - DecodeGCHdrInfo(pThis->m_crawl.GetCodeInfo()->GetGCInfoToken(), 0, &gcHdrInfo); - invalidRevPInvoke = gcHdrInfo.revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET; + hdrInfo *hdrInfoBody; + pThis->m_crawl.GetCodeInfo()->DecodeGCHdrInfo(&hdrInfoBody); + invalidRevPInvoke = hdrInfoBody->revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET; #endif // USE_GC_INFO_DECODER bool isFilterFunclet = false; bool isPropagatingToExternalNativeCode = false; diff --git a/src/coreclr/vm/gc_unwind_x86.inl b/src/coreclr/vm/gc_unwind_x86.inl index c3383574354cfe..10ce8b99a951eb 100644 --- a/src/coreclr/vm/gc_unwind_x86.inl +++ b/src/coreclr/vm/gc_unwind_x86.inl @@ -126,6 +126,11 @@ __forceinline int decodeSigned(PTR_CBYTE& src) #define fastSkipSigned(src) (decodeSigned(src)) #endif +unsigned int DecodeGCHdrInfoMethodSize(GCInfoToken gcInfoToken) +{ + PTR_CBYTE table = (PTR_CBYTE) gcInfoToken.Info; + return fastDecodeUnsigned(table); +} /***************************************************************************** * diff --git a/src/coreclr/vm/gccover.cpp b/src/coreclr/vm/gccover.cpp index 05e767c0325598..b029140d88a97c 100644 --- a/src/coreclr/vm/gccover.cpp +++ b/src/coreclr/vm/gccover.cpp @@ -752,19 +752,15 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) pThread->Thread::InitRegDisplay(®Disp, ©Regs, true); pThread->UnhijackThread(); - CodeManState codeManState; - codeManState.dwIsSet = 0; - // unwind out of the prolog or epilog - gcCover->codeMan->UnwindStackFrame(®Disp, - &codeInfo, UpdateAllRegs, &codeManState); + gcCover->codeMan->UnwindStackFrame(®Disp, &codeInfo, UpdateAllRegs); // Note we always doing the unwind, since that at does some checking (that we // unwind to a valid return address), but we only do the precise checking when // we are certain we have a good caller state if (gcCover->doingEpilogChecks) { // Confirm that we recovered our register state properly - _ASSERTE(regDisp.PCTAddr == TADDR(gcCover->callerRegs.Esp)); + _ASSERTE(GetRegdisplayPCTAddr(®Disp) == TADDR(gcCover->callerRegs.Esp)); // If a GC happened in this function, then the registers will not match // precisely. However there is still checks we can do. Also we can update diff --git a/src/coreclr/vm/gcenv.ee.common.cpp b/src/coreclr/vm/gcenv.ee.common.cpp index 427d02ec20bec2..65ad60e67df6cc 100644 --- a/src/coreclr/vm/gcenv.ee.common.cpp +++ b/src/coreclr/vm/gcenv.ee.common.cpp @@ -303,7 +303,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) #ifdef TARGET_X86 STRESS_LOG3(LF_GCROOTS, LL_INFO1000, "Scanning Frameless method %pM EIP = %p &EIP = %p\n", - pMD, GetControlPC(pCF->GetRegisterSet()), pCF->GetRegisterSet()->PCTAddr); + pMD, GetControlPC(pCF->GetRegisterSet()), GetRegdisplayPCTAddr(pCF->GetRegisterSet())); #else STRESS_LOG2(LF_GCROOTS, LL_INFO1000, "Scanning Frameless method %pM ControlPC = %p\n", pMD, GetControlPC(pCF->GetRegisterSet())); diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index ca3ca6a9c40717..c2c5208abdc4c8 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -177,16 +177,15 @@ void TransitionFrame::UpdateRegDisplayHelper(const PREGDISPLAY pRD, UINT cbStack CalleeSavedRegisters* regs = GetCalleeSavedRegisters(); - pRD->PCTAddr = GetReturnAddressPtr(); + SetRegdisplayPCTAddr(pRD, GetReturnAddressPtr()); - DWORD CallerSP = (DWORD)(pRD->PCTAddr + sizeof(TADDR) + cbStackPop); + DWORD CallerSP = (DWORD)(GetReturnAddressPtr() + sizeof(TADDR) + cbStackPop); #ifdef FEATURE_EH_FUNCLETS pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; - pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr); pRD->pCurrentContext->Esp = CallerSP; UpdateRegDisplayFromCalleeSavedRegisters(pRD, regs); @@ -203,7 +202,6 @@ void TransitionFrame::UpdateRegDisplayHelper(const PREGDISPLAY pRD, UINT cbStack ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); pRD->SP = CallerSP; #endif // FEATURE_EH_FUNCLETS @@ -242,8 +240,7 @@ void HelperMethodFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool update EnsureInit(pUnwoundState); - pRD->PCTAddr = dac_cast(pUnwoundState->pRetAddr()); - pRD->pCurrentContext->Eip = pRD->ControlPC = pUnwoundState->GetRetAddr(); + SetRegdisplayPCTAddr(pRD, dac_cast(pUnwoundState->pRetAddr())); pRD->pCurrentContext->Esp = pRD->SP = pUnwoundState->esp(); // Do not use pUnwoundState->p##regname() here because it returns NULL in this case @@ -262,8 +259,7 @@ void HelperMethodFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool update } #endif // DACCESS_COMPILE - pRD->PCTAddr = dac_cast(m_MachState.pRetAddr()); - pRD->pCurrentContext->Eip = pRD->ControlPC = m_MachState.GetRetAddr(); + SetRegdisplayPCTAddr(pRD, dac_cast(m_MachState.pRetAddr())); pRD->pCurrentContext->Esp = pRD->SP = (DWORD) m_MachState.esp(); #define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContext->regname = *((DWORD*) m_MachState.p##regname()); @@ -300,8 +296,7 @@ void HelperMethodFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool update MachState unwindState; EnsureInit(&unwindState); - pRD->PCTAddr = dac_cast(unwindState.pRetAddr()); - pRD->ControlPC = unwindState.GetRetAddr(); + SetRegdisplayPCTAddr(pRD, dac_cast(unwindState.pRetAddr())); pRD->SP = unwindState._esp; // Get some special host instance memory @@ -339,8 +334,7 @@ void HelperMethodFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool update pRD->pEbx = (DWORD*) m_MachState.pEbx(); pRD->pEbp = (DWORD*) m_MachState.pEbp(); - pRD->PCTAddr = dac_cast(m_MachState.pRetAddr()); - pRD->ControlPC = m_MachState.GetRetAddr(); + SetRegdisplayPCTAddr(pRD, dac_cast(m_MachState.pRetAddr())); pRD->SP = (DWORD) m_MachState.esp(); #endif // FEATURE_EH_FUNCLETS @@ -482,7 +476,7 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u } CONTRACT_END; - pRD->PCTAddr = GetReturnAddressPtr(); + SetRegdisplayPCTAddr(pRD, GetReturnAddressPtr()); #ifdef FEATURE_EH_FUNCLETS @@ -518,7 +512,6 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u #undef CALLEE_SAVED_REGISTER pRD->SP = m_Esp; - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); #endif // FEATURE_EH_FUNCLETS @@ -576,15 +569,13 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF #endif /* The return address is just above the "ESP" */ - pRD->PCTAddr = PTR_HOST_MEMBER_TADDR(InlinedCallFrame, this, - m_pCallerReturnAddress); + SetRegdisplayPCTAddr(pRD, PTR_HOST_MEMBER_TADDR(InlinedCallFrame, this, m_pCallerReturnAddress)); #ifdef FEATURE_EH_FUNCLETS pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr); pRD->pCurrentContext->Esp = (DWORD) dac_cast(m_pCallSiteSP); pRD->pCurrentContext->Ebp = (DWORD) m_pCalleeSavedFP; @@ -605,7 +596,6 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF pRD->pEbp = (DWORD*) &m_pCalleeSavedFP; - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); /* Now we need to pop off the outgoing arguments */ pRD->SP = (DWORD) dac_cast(m_pCallSiteSP) + stackArgSize; @@ -637,14 +627,13 @@ void ResumableFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFlo } CONTRACT_END; - pRD->PCTAddr = dac_cast(m_Regs) + offsetof(CONTEXT, Eip); + SetRegdisplayPCTAddr(pRD, dac_cast(m_Regs) + offsetof(CONTEXT, Eip)); #ifdef FEATURE_EH_FUNCLETS CopyMemory(pRD->pCurrentContext, m_Regs, sizeof(T_CONTEXT)); pRD->SP = m_Regs->Esp; - pRD->ControlPC = m_Regs->Eip; #define ARGUMENT_AND_SCRATCH_REGISTER(reg) pRD->pCurrentContextPointers->reg = &m_Regs->reg; ENUM_ARGUMENT_AND_SCRATCH_REGISTERS(); @@ -715,15 +704,14 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats } CONTRACTL_END; - pRD->PCTAddr = dac_cast(m_Args) + offsetof(HijackArgs, Eip); + SetRegdisplayPCTAddr(pRD, dac_cast(m_Args) + offsetof(HijackArgs, Eip)); #ifdef FEATURE_EH_FUNCLETS pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr); - pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR)); + pRD->pCurrentContext->Esp = (DWORD)(GetRegdisplayPCTAddr(pRD) + sizeof(TADDR)); #define RESTORE_REG(reg) { pRD->pCurrentContext->reg = m_Args->reg; pRD->pCurrentContextPointers->reg = &m_Args->reg; } #define CALLEE_SAVED_REGISTER(reg) RESTORE_REG(reg) @@ -752,8 +740,7 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats #undef ARGUMENT_AND_SCRATCH_REGISTER #undef RESTORE_REG - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); - pRD->SP = (DWORD)(pRD->PCTAddr + sizeof(TADDR)); + pRD->SP = (DWORD)(GetRegdisplayPCTAddr(pRD) + sizeof(TADDR)); #endif // FEATURE_EH_FUNCLETS @@ -793,15 +780,14 @@ void TailCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa } CONTRACT_END; - pRD->PCTAddr = GetReturnAddressPtr(); + SetRegdisplayPCTAddr(pRD, GetReturnAddressPtr()); #ifdef FEATURE_EH_FUNCLETS pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr); - pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR)); + pRD->pCurrentContext->Esp = (DWORD)(GetRegdisplayPCTAddr(pRD) + sizeof(TADDR)); UpdateRegDisplayFromCalleeSavedRegisters(pRD, &m_regs); ClearRegDisplayArgumentAndScratchRegisters(pRD); @@ -817,8 +803,7 @@ void TailCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER - pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr); - pRD->SP = (DWORD)(pRD->PCTAddr + sizeof(TADDR)); + pRD->SP = (DWORD)(GetRegdisplayPCTAddr(pRD) + sizeof(TADDR)); #endif diff --git a/src/coreclr/vm/i386/excepx86.cpp b/src/coreclr/vm/i386/excepx86.cpp index f2ab711d659b19..7b24c632ad4cb1 100644 --- a/src/coreclr/vm/i386/excepx86.cpp +++ b/src/coreclr/vm/i386/excepx86.cpp @@ -2719,8 +2719,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData context.Esp = pCf->GetCodeManager()->GetAmbientSP(regs, pCf->GetCodeInfo(), nativeOffset, - pData->dHandler, - pCf->GetCodeManState() + pData->dHandler ); // // In case we see unknown FS:[0] handlers we delay the interception point until we reach the handler that protects the interception point. @@ -2779,7 +2778,6 @@ void ResumeAtJitEH(CrawlFrame* pCf, EHClausePtr->HandlerStartPC, nestingLevel, throwable, - pCf->GetCodeManState(), &pShadowSP, &pHandlerEnd); @@ -2811,8 +2809,7 @@ void ResumeAtJitEH(CrawlFrame* pCf, // Find the ESP of the caller of the method with the exception handler. bool unwindSuccess = pCf->GetCodeManager()->UnwindStackFrame(pCf->GetRegisterSet(), pCf->GetCodeInfo(), - pCf->GetCodeManagerFlags(), - pCf->GetCodeManState()); + pCf->GetCodeManagerFlags()); _ASSERTE(unwindSuccess); if (((TADDR)pThread->m_pFrame < pCf->GetRegisterSet()->SP)) @@ -2992,7 +2989,7 @@ int CallJitEHFilter(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHCla size_t * pEndFilter = NULL; // Write pCf->GetCodeManager()->FixContext(ICodeManager::FILTER_CONTEXT, &context, pCf->GetCodeInfo(), - EHClausePtr->FilterOffset, nestingLevel, thrownObj, pCf->GetCodeManState(), + EHClausePtr->FilterOffset, nestingLevel, thrownObj, &pShadowSP, &pEndFilter); // End of the filter is the same as start of handler @@ -3041,7 +3038,7 @@ void CallJitEHFinally(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHC size_t * pFinallyEnd = NULL; pCf->GetCodeManager()->FixContext( ICodeManager::FINALLY_CONTEXT, &context, pCf->GetCodeInfo(), - EHClausePtr->HandlerStartPC, nestingLevel, ObjectToOBJECTREF((Object *) NULL), pCf->GetCodeManState(), + EHClausePtr->HandlerStartPC, nestingLevel, ObjectToOBJECTREF((Object *) NULL), &pShadowSP, &pFinallyEnd); if (pFinallyEnd) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index bb0f807ab00500..77ffeec4f70ccc 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -14708,6 +14708,10 @@ EECodeInfo::EECodeInfo() #ifdef FEATURE_EH_FUNCLETS m_pFunctionEntry = NULL; #endif + +#ifdef TARGET_X86 + m_hdrInfoTable = NULL; +#endif } void EECodeInfo::Init(PCODE codeAddress) @@ -14729,6 +14733,10 @@ void EECodeInfo::Init(PCODE codeAddress, ExecutionManager::ScanFlag scanFlag) m_codeAddress = codeAddress; +#ifdef TARGET_X86 + m_hdrInfoTable = NULL; +#endif + RangeSection * pRS = ExecutionManager::FindCodeRange(codeAddress, scanFlag); if (pRS == NULL) goto Invalid; @@ -14873,6 +14881,23 @@ BOOL EECodeInfo::HasFrameRegister() #endif // defined(FEATURE_EH_FUNCLETS) +#if defined(TARGET_X86) + +PTR_CBYTE EECodeInfo::DecodeGCHdrInfo(hdrInfo ** infoPtr) +{ + if (m_hdrInfoTable == NULL) + { + GCInfoToken gcInfoToken = GetGCInfoToken(); + DWORD hdrInfoSize = (DWORD)::DecodeGCHdrInfo(gcInfoToken, m_relOffset, &m_hdrInfoBody); + _ASSERTE(hdrInfoSize != 0); + m_hdrInfoTable = (PTR_CBYTE)gcInfoToken.Info + hdrInfoSize; + } + + *infoPtr = &m_hdrInfoBody; + return m_hdrInfoTable; +} + +#endif // TARGET_X86 #if defined(TARGET_AMD64) // ---------------------------------------------------------------------------- diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index 6e5ae608e26968..ea2647e509d7b9 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -8431,8 +8431,6 @@ HRESULT ProfToEEInterfaceImpl::ProfilerEbpWalker( // about the most likely cases, and it's ok if the unlikely cases result // in truncated stacks, as unlikely cases will be statistically // irrelevant to CPU performance sampling profilers - CodeManState codeManState; - codeManState.dwIsSet = 0; REGDISPLAY rd; FillRegDisplay(&rd, &ctxCur); @@ -8443,8 +8441,7 @@ HRESULT ProfToEEInterfaceImpl::ProfilerEbpWalker( codeInfo.GetCodeManager()->UnwindStackFrame( &rd, &codeInfo, - SpeculativeStackwalk, - &codeManState); + SpeculativeStackwalk); ctxCur.Ebp = *rd.GetEbpLocation(); ctxCur.Esp = rd.SP; diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index c791e5baa7c469..76578fbfbe4faf 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -19,9 +19,6 @@ #endif // FEATURE_INTERPRETER #include "gcinfodecoder.h" -#ifdef FEATURE_EH_FUNCLETS -#define PROCESS_EXPLICIT_FRAME_BEFORE_MANAGED_FRAME -#endif #include "exinfo.h" @@ -119,8 +116,7 @@ TADDR CrawlFrame::GetAmbientSPFromCrawlFrame() GetRegisterSet(), GetCodeInfo(), GetRelOffset(), - nestingLevel, - GetCodeManState() + nestingLevel ); #elif defined(TARGET_ARM) @@ -395,6 +391,7 @@ void ExInfoWalker::WalkToManaged() #endif // defined(ELIMINATE_FEF) #ifdef FEATURE_EH_FUNCLETS + // static UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo /*= NULL*/) { @@ -408,11 +405,11 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / CONTRACTL_END; #ifdef TARGET_X86 - EECodeInfo codeInfo; + EECodeInfo tempCodeInfo; if (pCodeInfo == NULL) { - codeInfo.Init(GetControlPC(pRD)); - pCodeInfo = &codeInfo; + tempCodeInfo.Init(GetControlPC(pRD)); + pCodeInfo = &tempCodeInfo; } #endif @@ -435,15 +432,14 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / else { #ifdef TARGET_X86 - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, pCodeInfo->GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(pRD, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), - &hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + hdrInfoBody, + table, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), true); @@ -507,15 +503,14 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext, rd.pCurrentContext = pContext; rd.pCurrentContextPointers = pContextPointers != NULL ? pContextPointers : &rd.ctxPtrsOne; - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, pCodeInfo->GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(&rd, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), - &hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + hdrInfoBody, + table, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), true); @@ -1385,9 +1380,6 @@ BOOL StackFrameIterator::ResetRegDisp(PREGDISPLAY pRegDisp, // Fields updated by ProcessIp(): // isFrameless, and codeInfo // -// Fields updated by ProcessCurrentFrame(): -// codeManState -// void StackFrameIterator::ResetCrawlFrame() { @@ -2478,8 +2470,7 @@ StackWalkAction StackFrameIterator::NextRaw(void) &m_cachedCodeInfo, m_codeManFlags | m_crawl.GetCodeManagerFlags() - | ((m_flags & PROFILER_DO_STACK_SNAPSHOT) ? SpeculativeStackwalk : 0), - &m_crawl.codeManState)) + | ((m_flags & PROFILER_DO_STACK_SNAPSHOT) ? SpeculativeStackwalk : 0))) { LOG((LF_CORPROF, LL_INFO100, "**PROF: m_crawl.GetCodeManager()->UnwindStackFrame failure leads to SWA_FAILED.\n")); retVal = SWA_FAILED; @@ -2720,6 +2711,16 @@ void StackFrameIterator::ProcessIp(PCODE Ip) m_crawl.codeInfo.Init(Ip, m_scanFlag); m_crawl.isFrameless = !!m_crawl.codeInfo.IsValid(); + +#ifdef TARGET_X86 + if (m_crawl.isFrameless) + { + // Optimization: Ensure that we decode GC info header early. We will reuse + // it several times. + hdrInfo *hdrInfoBody; + m_crawl.codeInfo.DecodeGCHdrInfo(&hdrInfoBody); + } +#endif } // StackFrameIterator::ProcessIp() //--------------------------------------------------------------------------------------- @@ -2857,12 +2858,6 @@ void StackFrameIterator::ProcessCurrentFrame(void) return; } - m_crawl.codeManState.dwIsSet = 0; -#if defined(_DEBUG) - memset((void *)m_crawl.codeManState.stateBuf, 0xCD, - sizeof(m_crawl.codeManState.stateBuf)); -#endif // _DEBUG - #ifdef FEATURE_INTERPRETER if (!m_crawl.isFrameless) { @@ -3076,8 +3071,7 @@ void StackFrameIterator::PreProcessingForManagedFrames(void) m_pCachedGSCookie = (GSCookie*)m_crawl.GetCodeManager()->GetGSCookieAddr( m_crawl.pRD, &m_crawl.codeInfo, - m_codeManFlags, - &m_crawl.codeManState); + m_codeManFlags); #endif // !DACCESS_COMPILE if (!(m_flags & SKIP_GSCOOKIE_CHECK) && m_pCachedGSCookie) @@ -3147,9 +3141,9 @@ void StackFrameIterator::PostProcessingForManagedFrames(void) #endif // ELIMINATE_FEF #ifdef TARGET_X86 - hdrInfo gcHdrInfo; - DecodeGCHdrInfo(m_crawl.codeInfo.GetGCInfoToken(), 0, &gcHdrInfo); - bool hasReversePInvoke = gcHdrInfo.revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET; + hdrInfo *gcHdrInfo; + m_crawl.codeInfo.DecodeGCHdrInfo(&gcHdrInfo); + bool hasReversePInvoke = gcHdrInfo->revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET; #endif // TARGET_X86 ProcessIp(GetControlPC(m_crawl.pRD)); diff --git a/src/coreclr/vm/stackwalk.h b/src/coreclr/vm/stackwalk.h index 9a51a69b97e5cf..1ee3c19f5196e1 100644 --- a/src/coreclr/vm/stackwalk.h +++ b/src/coreclr/vm/stackwalk.h @@ -46,6 +46,7 @@ class AppDomain; #if defined(FEATURE_EH_FUNCLETS) #define RECORD_RESUMABLE_FRAME_SP +#define PROCESS_EXPLICIT_FRAME_BEFORE_MANAGED_FRAME #endif //************************************************************************ @@ -137,7 +138,6 @@ class CrawlFrame */ PTR_VOID GetExactGenericArgsToken(); - inline CodeManState * GetCodeManState() { LIMITED_METHOD_DAC_CONTRACT; return & codeManState; } /* IF YOU USE ANY OF THE SUBSEQUENT FUNCTIONS, YOU NEED TO REALLY UNDERSTAND THE STACK-WALKER (INCLUDING UNWINDING OF METHODS IN MANAGED NATIVE CODE)! @@ -444,8 +444,6 @@ class CrawlFrame friend void QCALLTYPE AppendExceptionStackFrame(QCall::ObjectHandleOnStack exceptionObj, SIZE_T ip, SIZE_T sp, int flags, ExInfo *pExInfo); #endif // FEATURE_EH_FUNCLETS - CodeManState codeManState; - bool isFrameless; bool isFirst; diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index dce5048f0c9cb1..48201d1825d098 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -6689,8 +6689,7 @@ bool Thread::InitRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, bool validCo { SetIP(pctx, 0); #ifdef TARGET_X86 - pRD->ControlPC = pctx->Eip; - pRD->PCTAddr = (TADDR)&(pctx->Eip); + SetRegdisplayPCTAddr(pRD, (TADDR)&(pctx->Eip)); #elif defined(TARGET_AMD64) // nothing more to do here, on Win64 setting the IP to 0 is enough. #elif defined(TARGET_ARM) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index c71b0502f76d24..fb07b1e0fded70 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -4807,7 +4807,7 @@ StackWalkAction SWCB_GetExecutionState(CrawlFrame *pCF, VOID *pData) else { #ifdef TARGET_X86 - STRESS_LOG2(LF_SYNC, LL_INFO1000, "Not in Jitted code at EIP = %p, &EIP = %p\n", GetControlPC(pCF->GetRegisterSet()), pCF->GetRegisterSet()->PCTAddr); + STRESS_LOG2(LF_SYNC, LL_INFO1000, "Not in Jitted code at EIP = %p, &EIP = %p\n", GetControlPC(pCF->GetRegisterSet()), GetRegdisplayPCTAddr(pCF->GetRegisterSet())); #else STRESS_LOG1(LF_SYNC, LL_INFO1000, "Not in Jitted code at pc = %p\n", GetControlPC(pCF->GetRegisterSet())); #endif @@ -4837,7 +4837,7 @@ StackWalkAction SWCB_GetExecutionState(CrawlFrame *pCF, VOID *pData) { // pPC points to the return address sitting on the stack, as our // current EIP for the penultimate stack frame. - pES->m_ppvRetAddrPtr = (void **) pRDT->PCTAddr; + pES->m_ppvRetAddrPtr = (void **) GetRegdisplayPCTAddr(pRDT); STRESS_LOG2(LF_SYNC, LL_INFO1000, "Partially Int case hijack address = 0x%x val = 0x%x\n", pES->m_ppvRetAddrPtr, *pES->m_ppvRetAddrPtr); }