From ef940d09f8df1562c20fc521eebd5e3d7818d71c Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 2 Apr 2025 17:10:29 +0200 Subject: [PATCH 1/3] Replace CodeManState with cache in EECodeInfo for x86. On all other platforms CodeManState was unused and taking space in StackFrameIterator. Optimize some code paths to cache GC info early or decode the method size without decoding the whole table. Move PCTAddr (Eip pointer) into KNONVOLATILE_CONTEXT_POINTERS_EX to avoid recomputing it when switching between callee and caller contexts. --- .../Runtime/ExceptionServices/AsmOffsets.cs | 52 ++-- src/coreclr/debug/ee/controller.cpp | 2 +- src/coreclr/debug/ee/debugger.cpp | 4 +- src/coreclr/inc/crosscomp.h | 1 + src/coreclr/inc/eetwain.h | 57 +--- src/coreclr/inc/gc_unwind_x86.h | 4 +- src/coreclr/inc/regdisp.h | 27 +- src/coreclr/pal/inc/pal.h | 1 + src/coreclr/unwinder/i386/unwinder.cpp | 9 +- src/coreclr/vm/codeman.h | 10 + src/coreclr/vm/eetwain.cpp | 285 +++++++----------- src/coreclr/vm/exceptionhandling.cpp | 6 +- src/coreclr/vm/gc_unwind_x86.inl | 5 + src/coreclr/vm/gccover.cpp | 8 +- src/coreclr/vm/gcenv.ee.common.cpp | 2 +- src/coreclr/vm/i386/cgenx86.cpp | 43 +-- src/coreclr/vm/i386/excepx86.cpp | 11 +- src/coreclr/vm/jitinterface.cpp | 23 ++ src/coreclr/vm/proftoeeinterfaceimpl.cpp | 5 +- src/coreclr/vm/stackwalk.cpp | 60 ++-- src/coreclr/vm/stackwalk.h | 4 +- src/coreclr/vm/threads.cpp | 3 +- src/coreclr/vm/threadsuspend.cpp | 4 +- 23 files changed, 270 insertions(+), 356 deletions(-) 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..1610b1691ce0c1 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 @@ -39,9 +39,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0x3ec; public const int OFFSETOF__REGDISPLAY__ControlPC = 0x3f0; #elif TARGET_X86 - public const int SIZEOF__REGDISPLAY = 0x5fc; - public const int OFFSETOF__REGDISPLAY__SP = 0x5f0; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f4; + public const int SIZEOF__REGDISPLAY = 0x600; + public const int OFFSETOF__REGDISPLAY__SP = 0x5f8; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5fc; #elif TARGET_RISCV64 public const int SIZEOF__REGDISPLAY = 0x6C0; public const int OFFSETOF__REGDISPLAY__SP = 0x628; @@ -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 @@ -91,9 +96,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0x3e8; public const int OFFSETOF__REGDISPLAY__ControlPC = 0x3ec; #elif TARGET_X86 - public const int SIZEOF__REGDISPLAY = 0x5f8; - public const int OFFSETOF__REGDISPLAY__SP = 0x5ec; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f0; + public const int SIZEOF__REGDISPLAY = 0x5fc; + public const int OFFSETOF__REGDISPLAY__SP = 0x5f4; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f8; #elif TARGET_RISCV64 public const int SIZEOF__REGDISPLAY = 0x6B0; public const int OFFSETOF__REGDISPLAY__SP = 0x620; @@ -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/crosscomp.h b/src/coreclr/inc/crosscomp.h index f6e65f3f8cf57e..a92b0529b3e348 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -691,6 +691,7 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS_EX PDWORD Eax; PDWORD Ebp; + PDWORD Eip; } KNONVOLATILE_CONTEXT_POINTERS_EX, *PKNONVOLATILE_CONTEXT_POINTERS_EX; 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..e6aa40629e39a0 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -86,6 +86,8 @@ struct REGDISPLAY : public REGDISPLAY_BASE { DWORD * pEax; DWORD * pEbp; + + TADDR PCTAddr; #endif // !FEATURE_EH_FUNCLETS #ifndef FEATURE_EH_FUNCLETS @@ -104,6 +106,7 @@ struct REGDISPLAY : public REGDISPLAY_BASE { pCurrentContext->reg = *p##reg; \ } + REG_METHODS(Eip) #endif // FEATURE_EH_FUNCLETS REG_METHODS(Eax) @@ -116,8 +119,6 @@ struct REGDISPLAY : public REGDISPLAY_BASE { REG_METHODS(Ebp) #undef REG_METHODS - - TADDR PCTAddr; }; inline TADDR GetRegdisplayFP(REGDISPLAY *display) { @@ -135,9 +136,22 @@ inline LPVOID GetRegdisplayFPAddress(REGDISPLAY *display) { return (LPVOID)display->GetEbpLocation(); } +inline TADDR GetRegdisplayPCTAddr(REGDISPLAY *display) +{ +#ifdef FEATURE_EH_FUNCLETS + return (TADDR)display->GetEipLocation(); +#else + return display->PCTAddr; +#endif +} + inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr) { +#ifdef FEATURE_EH_FUNCLETS + display->SetEipLocation((PDWORD)addr); +#else display->PCTAddr = addr; +#endif display->ControlPC = *PTR_PCODE(addr); } @@ -146,12 +160,12 @@ inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr) 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) @@ -444,6 +458,7 @@ inline void FillContextPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pCtxPtrs, PT_CO { *(&pCtxPtrs->Edi + i) = (&pCtx->Edi + i); } + pCtxPtrs->Eip = &pCtx->Eip; #elif defined(TARGET_RISCV64) // TARGET_X86 *(&pCtxPtrs->S1) = &pCtx->S1; *(&pCtxPtrs->S2) = &pCtx->S2; @@ -523,10 +538,6 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC // This will setup the PC and SP SyncRegDisplayToCurrentContext(pRD); -#ifdef TARGET_X86 - pRD->PCTAddr = (UINT_PTR)&(pctx->Eip); -#endif - #if !defined(DACCESS_COMPILE) #if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) pRD->SSP = GetSSP(pctx); diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 293d9ab41b156c..28169a9304b230 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -1223,6 +1223,7 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PDWORD Eax; PDWORD Ebp; + PDWORD Eip; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; diff --git a/src/coreclr/unwinder/i386/unwinder.cpp b/src/coreclr/unwinder/i386/unwinder.cpp index deb385c2659f6f..0b99ebf331ea97 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; @@ -27,13 +24,13 @@ BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTE codeInfo.Init((PCODE) ControlPc); GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, codeInfo.GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + DWORD hdrInfoSize = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); if (!UnwindStackFrameX86(&rd, PTR_CBYTE(codeInfo.GetSavedMethodCode()), codeInfo.GetRelOffset(), - &hdrInfoBody, + hdrInfoBody, dac_cast(gcInfoToken.Info) + hdrInfoSize, PTR_CBYTE(codeInfo.GetJitManager()->GetFuncletStartAddress(&codeInfo)), codeInfo.IsFunclet(), diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 986ad82abd3dba..54114abad2bfb0 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()); } + + DWORD 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 + DWORD m_hdrInfoSize; + 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..503b7bfbc3a989 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; + DWORD hdrInfoSize = 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; + hdrInfo *oldInfo, *newInfo; - DecodeGCHdrInfo(pOldCodeInfo->GetGCInfoToken(), - pOldCodeInfo->GetRelOffset(), - &oldInfo); - - 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 @@ -1062,19 +1043,14 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) PTR_VOID methodInfoPtr = gcInfoToken.Info; DWORD curOffs = codeInfo.GetRelOffset(); - CodeManStateBuf stateBuf; + hdrInfo *hdrInfoBody; + DWORD hdrInfoSize = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); - stateBuf.hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, - curOffs, - &stateBuf.hdrInfoBody); + PTR_CBYTE table = dac_cast(methodInfoPtr) + hdrInfoSize; - PTR_CBYTE table = dac_cast(methodInfoPtr) + stateBuf.hdrInfoSize; + _ASSERTE(hdrInfoBody->epilogOffs == hdrInfo::NOT_IN_EPILOG && hdrInfoBody->prologOffs == hdrInfo::NOT_IN_PROLOG); - hdrInfo *info = &stateBuf.hdrInfoBody; - - _ASSERTE(info->epilogOffs == hdrInfo::NOT_IN_EPILOG && info->prologOffs == hdrInfo::NOT_IN_PROLOG); - - bool isESPFrame = !info->ebpFrame && !info->doubleAlign; + bool isESPFrame = !hdrInfoBody->ebpFrame && !hdrInfoBody->doubleAlign; if (codeInfo.IsFunclet()) { @@ -1085,11 +1061,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 +1084,7 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext ) bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) + unsigned flags) { CONTRACTL { NOTHROW; @@ -1126,30 +1101,19 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, 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); - } + hdrInfo *hdrInfoBody; + DWORD hdrInfoSize; - PTR_CBYTE table = dac_cast(methodInfoPtr) + stateBuf->hdrInfoSize; + hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - hdrInfo * info = &stateBuf->hdrInfoBody; + PTR_CBYTE table = dac_cast(methodInfoPtr) + hdrInfoSize; - 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 +1130,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, EECodeInfo *pCodeInfo, - unsigned flags, - CodeManState *pState) + unsigned flags) { CONTRACTL { NOTHROW; @@ -1521,33 +1484,31 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, unsigned relOffset = pCodeInfo->GetRelOffset(); PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - hdrInfo info; + 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 +1522,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 +1543,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 +1551,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 +1569,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 +1588,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); @@ -1657,20 +1618,18 @@ GenericParamContextType EECodeManager::GetParamContextType(PREGDISPLAY pCont PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); unsigned relOffset = pCodeInfo->GetRelOffset(); - hdrInfo info; + hdrInfo *hdrInfoBody; PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += DecodeGCHdrInfo(gcInfoToken, - relOffset, - &info); + 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; } @@ -1720,21 +1679,19 @@ PTR_VOID EECodeManager::GetParamTypeArg(PREGDISPLAY pContext, unsigned relOffset = pCodeInfo->GetRelOffset(); /* Extract the necessary information from the info block header */ - hdrInfo info; + hdrInfo *hdrInfoBody; PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += DecodeGCHdrInfo(gcInfoToken, - relOffset, - &info); + 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,8 +1777,7 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T baseStackSlot, void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, EECodeInfo * pCodeInfo, - unsigned flags, - CodeManState * pState) + unsigned flags) { CONTRACTL { NOTHROW; @@ -1847,37 +1803,29 @@ 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; + DWORD hdrInfoSize = 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); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info) + hdrInfoSize; + 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 @@ -1974,11 +1922,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 +2261,7 @@ void EECodeManager::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, EECodeInfo *pCodeInfo, DWORD dwRelOffset, - DWORD nestingLevel, - CodeManState *pState) + DWORD nestingLevel) { CONTRACTL { NOTHROW; @@ -2325,45 +2270,38 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, } 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; + 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 +2314,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; @@ -2426,16 +2364,10 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo) 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 +2401,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..d913a2dde714ef 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)((TADDR)pRD->pCurrentContextPointers->Eip + 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,7 +740,6 @@ 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)); #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..b2f12866a99cb5 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_hdrInfoSize = 0; +#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_hdrInfoSize = 0; +#endif + RangeSection * pRS = ExecutionManager::FindCodeRange(codeAddress, scanFlag); if (pRS == NULL) goto Invalid; @@ -14873,6 +14881,21 @@ BOOL EECodeInfo::HasFrameRegister() #endif // defined(FEATURE_EH_FUNCLETS) +#if defined(TARGET_X86) + +DWORD EECodeInfo::DecodeGCHdrInfo(hdrInfo ** infoPtr) +{ + if (m_hdrInfoSize == 0) + { + m_hdrInfoSize = (DWORD)::DecodeGCHdrInfo(GetGCInfoToken(), m_relOffset, &m_hdrInfoBody); + _ASSERTE(m_hdrInfoSize != 0); + } + + *infoPtr = &m_hdrInfoBody; + return m_hdrInfoSize; +} + +#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..c44aef072e8696 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 @@ -427,22 +424,18 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / PT_KNONVOLATILE_CONTEXT_POINTERS tempPtrs = pRD->pCurrentContextPointers; pRD->pCurrentContextPointers = pRD->pCallerContextPointers; pRD->pCallerContextPointers = tempPtrs; - -#ifdef TARGET_X86 - pRD->PCTAddr = pRD->pCurrentContext->Esp - pCodeInfo->GetCodeManager()->GetStackParameterSize(pCodeInfo) - sizeof(DWORD); -#endif } else { #ifdef TARGET_X86 GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, pCodeInfo->GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + DWORD hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(pRD, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), - &hdrInfoBody, + hdrInfoBody, dac_cast(gcInfoToken.Info) + hdrInfoSize, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), @@ -508,13 +501,13 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext, rd.pCurrentContextPointers = pContextPointers != NULL ? pContextPointers : &rd.ctxPtrsOne; GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - hdrInfo hdrInfoBody; - DWORD hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, pCodeInfo->GetRelOffset(), &hdrInfoBody); + hdrInfo *hdrInfoBody; + DWORD hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(&rd, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), - &hdrInfoBody, + hdrInfoBody, dac_cast(gcInfoToken.Info) + hdrInfoSize, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), @@ -1385,9 +1378,6 @@ BOOL StackFrameIterator::ResetRegDisp(PREGDISPLAY pRegDisp, // Fields updated by ProcessIp(): // isFrameless, and codeInfo // -// Fields updated by ProcessCurrentFrame(): -// codeManState -// void StackFrameIterator::ResetCrawlFrame() { @@ -2478,8 +2468,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 +2709,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 +2856,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 +3069,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 +3139,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); } From 363f5f7bdf4ce81d8bc8c1f15fd795caa1e5ffc8 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 8 Apr 2025 16:10:57 +0200 Subject: [PATCH 2/3] Revert the PCTAddr move into KNONVOLATILE_CONTEXT_POINTERS->Eip but keep the helpers --- .../Runtime/ExceptionServices/AsmOffsets.cs | 12 +++++------ src/coreclr/inc/crosscomp.h | 1 - src/coreclr/inc/regdisp.h | 20 ++++++++----------- src/coreclr/pal/inc/pal.h | 1 - src/coreclr/vm/i386/cgenx86.cpp | 4 ++-- src/coreclr/vm/stackwalk.cpp | 4 ++++ 6 files changed, 20 insertions(+), 22 deletions(-) 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 1610b1691ce0c1..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 @@ -39,9 +39,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0x3ec; public const int OFFSETOF__REGDISPLAY__ControlPC = 0x3f0; #elif TARGET_X86 - public const int SIZEOF__REGDISPLAY = 0x600; - public const int OFFSETOF__REGDISPLAY__SP = 0x5f8; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5fc; + public const int SIZEOF__REGDISPLAY = 0x5fc; + public const int OFFSETOF__REGDISPLAY__SP = 0x5f0; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f4; #elif TARGET_RISCV64 public const int SIZEOF__REGDISPLAY = 0x6C0; public const int OFFSETOF__REGDISPLAY__SP = 0x628; @@ -96,9 +96,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0x3e8; public const int OFFSETOF__REGDISPLAY__ControlPC = 0x3ec; #elif TARGET_X86 - public const int SIZEOF__REGDISPLAY = 0x5fc; - public const int OFFSETOF__REGDISPLAY__SP = 0x5f4; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f8; + public const int SIZEOF__REGDISPLAY = 0x5f8; + public const int OFFSETOF__REGDISPLAY__SP = 0x5ec; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x5f0; #elif TARGET_RISCV64 public const int SIZEOF__REGDISPLAY = 0x6B0; public const int OFFSETOF__REGDISPLAY__SP = 0x620; diff --git a/src/coreclr/inc/crosscomp.h b/src/coreclr/inc/crosscomp.h index a92b0529b3e348..f6e65f3f8cf57e 100644 --- a/src/coreclr/inc/crosscomp.h +++ b/src/coreclr/inc/crosscomp.h @@ -691,7 +691,6 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS_EX PDWORD Eax; PDWORD Ebp; - PDWORD Eip; } KNONVOLATILE_CONTEXT_POINTERS_EX, *PKNONVOLATILE_CONTEXT_POINTERS_EX; diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index e6aa40629e39a0..59944c23c5cefa 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -86,8 +86,6 @@ struct REGDISPLAY : public REGDISPLAY_BASE { DWORD * pEax; DWORD * pEbp; - - TADDR PCTAddr; #endif // !FEATURE_EH_FUNCLETS #ifndef FEATURE_EH_FUNCLETS @@ -106,7 +104,6 @@ struct REGDISPLAY : public REGDISPLAY_BASE { pCurrentContext->reg = *p##reg; \ } - REG_METHODS(Eip) #endif // FEATURE_EH_FUNCLETS REG_METHODS(Eax) @@ -119,6 +116,8 @@ struct REGDISPLAY : public REGDISPLAY_BASE { REG_METHODS(Ebp) #undef REG_METHODS + + TADDR PCTAddr; }; inline TADDR GetRegdisplayFP(REGDISPLAY *display) { @@ -138,19 +137,14 @@ inline LPVOID GetRegdisplayFPAddress(REGDISPLAY *display) { inline TADDR GetRegdisplayPCTAddr(REGDISPLAY *display) { -#ifdef FEATURE_EH_FUNCLETS - return (TADDR)display->GetEipLocation(); -#else return display->PCTAddr; -#endif } inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr) { -#ifdef FEATURE_EH_FUNCLETS - display->SetEipLocation((PDWORD)addr); -#else display->PCTAddr = addr; +#ifdef FEATURE_EH_FUNCLETS + display->pCurrentContext->Eip = *PTR_PCODE(addr); #endif display->ControlPC = *PTR_PCODE(addr); } @@ -159,7 +153,6 @@ 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 < GetRegdisplayPCTAddr(display); } inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) { @@ -458,7 +451,6 @@ inline void FillContextPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pCtxPtrs, PT_CO { *(&pCtxPtrs->Edi + i) = (&pCtx->Edi + i); } - pCtxPtrs->Eip = &pCtx->Eip; #elif defined(TARGET_RISCV64) // TARGET_X86 *(&pCtxPtrs->S1) = &pCtx->S1; *(&pCtxPtrs->S2) = &pCtx->S2; @@ -538,6 +530,10 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC // This will setup the PC and SP SyncRegDisplayToCurrentContext(pRD); +#ifdef TARGET_X86 + pRD->PCTAddr = (UINT_PTR)&(pctx->Eip); +#endif + #if !defined(DACCESS_COMPILE) #if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) pRD->SSP = GetSSP(pctx); diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 28169a9304b230..293d9ab41b156c 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -1223,7 +1223,6 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { PDWORD Eax; PDWORD Ebp; - PDWORD Eip; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp index d913a2dde714ef..c2c5208abdc4c8 100644 --- a/src/coreclr/vm/i386/cgenx86.cpp +++ b/src/coreclr/vm/i386/cgenx86.cpp @@ -711,7 +711,7 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats pRD->IsCallerContextValid = FALSE; pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - pRD->pCurrentContext->Esp = (DWORD)((TADDR)pRD->pCurrentContextPointers->Eip + 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) @@ -740,7 +740,7 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats #undef ARGUMENT_AND_SCRATCH_REGISTER #undef RESTORE_REG - pRD->SP = (DWORD)(pRD->PCTAddr + sizeof(TADDR)); + pRD->SP = (DWORD)(GetRegdisplayPCTAddr(pRD) + sizeof(TADDR)); #endif // FEATURE_EH_FUNCLETS diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index c44aef072e8696..ef0679199552e0 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -424,6 +424,10 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / PT_KNONVOLATILE_CONTEXT_POINTERS tempPtrs = pRD->pCurrentContextPointers; pRD->pCurrentContextPointers = pRD->pCallerContextPointers; pRD->pCallerContextPointers = tempPtrs; + +#ifdef TARGET_X86 + pRD->PCTAddr = pRD->pCurrentContext->Esp - pCodeInfo->GetCodeManager()->GetStackParameterSize(pCodeInfo) - sizeof(DWORD); +#endif } else { From 1aaf657b6448a749c86595d612cc33036b4d30a9 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 8 Apr 2025 23:36:44 +0200 Subject: [PATCH 3/3] Improve the GC info cache by caching the table pointer instead of size and thus avoid repeated GetGCInfoToken() calls --- src/coreclr/unwinder/i386/unwinder.cpp | 5 ++- src/coreclr/vm/codeman.h | 4 +-- src/coreclr/vm/eetwain.cpp | 46 ++++++-------------------- src/coreclr/vm/jitinterface.cpp | 16 +++++---- src/coreclr/vm/stackwalk.cpp | 10 +++--- 5 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/coreclr/unwinder/i386/unwinder.cpp b/src/coreclr/unwinder/i386/unwinder.cpp index 0b99ebf331ea97..4ad7cfeccc0ff6 100644 --- a/src/coreclr/unwinder/i386/unwinder.cpp +++ b/src/coreclr/unwinder/i386/unwinder.cpp @@ -23,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 = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); if (!UnwindStackFrameX86(&rd, PTR_CBYTE(codeInfo.GetSavedMethodCode()), codeInfo.GetRelOffset(), hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + 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 54114abad2bfb0..f15202bc321eff 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -2906,7 +2906,7 @@ class EECodeInfo return GetCodeManager()->GetFrameSize(GetGCInfoToken()); } - DWORD DecodeGCHdrInfo(hdrInfo ** infoPtr); + PTR_CBYTE DecodeGCHdrInfo(hdrInfo ** infoPtr); #endif // TARGET_X86 #if defined(TARGET_WASM) @@ -2932,7 +2932,7 @@ ULONG GetFixedStackSize(); #endif // FEATURE_EH_FUNCLETS #ifdef TARGET_X86 - DWORD m_hdrInfoSize; + PTR_CBYTE m_hdrInfoTable; hdrInfo m_hdrInfoBody; #endif diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 503b7bfbc3a989..743511eea2092a 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -69,7 +69,7 @@ void EECodeManager::FixContext( ContextType ctxType, /* Extract the necessary information from the info block header */ hdrInfo *hdrInfoBody; - DWORD hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); #ifdef _DEBUG if (trFixContext) { @@ -1039,14 +1039,10 @@ 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(); - hdrInfo *hdrInfoBody; - DWORD hdrInfoSize = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); - - PTR_CBYTE table = dac_cast(methodInfoPtr) + hdrInfoSize; + hdrInfo *hdrInfoBody; + PTR_CBYTE table = codeInfo.DecodeGCHdrInfo(&hdrInfoBody); _ASSERTE(hdrInfoBody->epilogOffs == hdrInfo::NOT_IN_EPILOG && hdrInfoBody->prologOffs == hdrInfo::NOT_IN_PROLOG); @@ -1099,14 +1095,8 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pRD, PCODE breakPC = pRD->ControlPC; _ASSERTE(PCODEToPINSTR(breakPC) == pCodeInfo->GetCodeAddress()); - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - PTR_VOID methodInfoPtr = gcInfoToken.Info; hdrInfo *hdrInfoBody; - DWORD hdrInfoSize; - - hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); - - PTR_CBYTE table = dac_cast(methodInfoPtr) + hdrInfoSize; + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); hdrInfoBody->isSpeculativeStackWalk = ((flags & SpeculativeStackwalk) != 0); @@ -1480,17 +1470,16 @@ 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); + PTR_CBYTE table; hdrInfo *hdrInfoBody; unsigned stackDepth; TADDR taArgBase; /* Extract the necessary information from the info block header */ - table += pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); // We do not have accurate information in the prolog or the epilog if (hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -1614,13 +1603,10 @@ 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 *hdrInfoBody; - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); if (!hdrInfoBody->genericsContext || hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -1674,14 +1660,11 @@ 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 *hdrInfoBody; - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - table += pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); if (!hdrInfoBody->genericsContext || hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -1784,7 +1767,6 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, GC_NOTRIGGER; } CONTRACTL_END; - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); unsigned relOffset = pCodeInfo->GetRelOffset(); #ifdef FEATURE_EH_FUNCLETS @@ -1805,7 +1787,7 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, #ifndef USE_GC_INFO_DECODER /* Extract the necessary information from the info block header */ hdrInfo *hdrInfoBody; - DWORD hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); if (hdrInfoBody->prologOffs != hdrInfo::NOT_IN_PROLOG || hdrInfoBody->epilogOffs != hdrInfo::NOT_IN_EPILOG || @@ -1822,13 +1804,13 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, } else { - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info) + hdrInfoSize; unsigned argSize = GetPushedArgSize(hdrInfoBody, table, relOffset); return PVOID(SIZE_T(pContext->SP + argSize + hdrInfoBody->gsCookieOffset)); } #else // !USE_GC_INFO_DECODER + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); GcInfoDecoder gcInfoDecoder( gcInfoToken, DECODE_GS_COOKIE @@ -2269,13 +2251,10 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, SUPPORTS_DAC; } CONTRACTL_END; - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); - /* Extract the necessary information from the info block header */ hdrInfo *hdrInfoBody; - table += pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); #if defined(_DEBUG) && !defined(DACCESS_COMPILE) if (trFixContext) @@ -2361,9 +2340,6 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo) } #endif // FEATURE_EH_FUNCLETS - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); - unsigned dwOffset = pCodeInfo->GetRelOffset(); - hdrInfo * hdrInfoBody; pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b2f12866a99cb5..77ffeec4f70ccc 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -14710,7 +14710,7 @@ EECodeInfo::EECodeInfo() #endif #ifdef TARGET_X86 - m_hdrInfoSize = 0; + m_hdrInfoTable = NULL; #endif } @@ -14734,7 +14734,7 @@ void EECodeInfo::Init(PCODE codeAddress, ExecutionManager::ScanFlag scanFlag) m_codeAddress = codeAddress; #ifdef TARGET_X86 - m_hdrInfoSize = 0; + m_hdrInfoTable = NULL; #endif RangeSection * pRS = ExecutionManager::FindCodeRange(codeAddress, scanFlag); @@ -14883,16 +14883,18 @@ BOOL EECodeInfo::HasFrameRegister() #if defined(TARGET_X86) -DWORD EECodeInfo::DecodeGCHdrInfo(hdrInfo ** infoPtr) +PTR_CBYTE EECodeInfo::DecodeGCHdrInfo(hdrInfo ** infoPtr) { - if (m_hdrInfoSize == 0) + if (m_hdrInfoTable == NULL) { - m_hdrInfoSize = (DWORD)::DecodeGCHdrInfo(GetGCInfoToken(), m_relOffset, &m_hdrInfoBody); - _ASSERTE(m_hdrInfoSize != 0); + 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_hdrInfoSize; + return m_hdrInfoTable; } #endif // TARGET_X86 diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index ef0679199552e0..76578fbfbe4faf 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -432,15 +432,14 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo / else { #ifdef TARGET_X86 - GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); hdrInfo *hdrInfoBody; - DWORD hdrInfoSize = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(pRD, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + table, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), true); @@ -504,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 = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); + PTR_CBYTE table = pCodeInfo->DecodeGCHdrInfo(&hdrInfoBody); ::UnwindStackFrameX86(&rd, PTR_CBYTE(pCodeInfo->GetSavedMethodCode()), pCodeInfo->GetRelOffset(), hdrInfoBody, - dac_cast(gcInfoToken.Info) + hdrInfoSize, + table, PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)), pCodeInfo->IsFunclet(), true);