Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4291,7 +4291,7 @@ PhaseStatus Compiler::lvaMarkLocalVars()

#endif // !FEATURE_EH_FUNCLETS

// PSPSym and LocAllocSPvar are not used by the NativeAOT ABI
// PSPSym is not used by the NativeAOT ABI
if (!IsTargetAbi(CORINFO_NATIVEAOT_ABI))
{
#if defined(FEATURE_EH_FUNCLETS)
Expand All @@ -4303,29 +4303,29 @@ PhaseStatus Compiler::lvaMarkLocalVars()
lvaSetVarDoNotEnregister(lvaPSPSym DEBUGARG(DoNotEnregisterReason::VMNeedsStackAddr));
}
#endif // FEATURE_EH_FUNCLETS
}

#ifdef JIT32_GCENCODER
// LocAllocSPvar is only required by the implicit frame layout expected by the VM on x86. Whether
// a function contains a Localloc is conveyed in the GC information, in the InfoHdrSmall.localloc
// field. The function must have an EBP frame. Then, the VM finds the LocAllocSP slot by assuming
// the following stack layout:
//
// -- higher addresses --
// saved EBP <-- EBP points here
// other callee-saved registers // InfoHdrSmall.savedRegsCountExclFP specifies this size
// optional GS cookie // InfoHdrSmall.security is 1 if this exists
// LocAllocSP slot
// -- lower addresses --
//
// See also eetwain.cpp::GetLocallocSPOffset() and its callers.
if (compLocallocUsed)
{
lvaLocAllocSPvar = lvaGrabTempWithImplicitUse(false DEBUGARG("LocAllocSPvar"));
LclVarDsc* locAllocSPvar = lvaGetDesc(lvaLocAllocSPvar);
locAllocSPvar->lvType = TYP_I_IMPL;
}
#endif // JIT32_GCENCODER
// LocAllocSPvar is only required by the implicit frame layout expected by the VM on x86. Whether
// a function contains a Localloc is conveyed in the GC information, in the InfoHdrSmall.localloc
// field. The function must have an EBP frame. Then, the VM finds the LocAllocSP slot by assuming
// the following stack layout:
//
// -- higher addresses --
// saved EBP <-- EBP points here
// other callee-saved registers // InfoHdrSmall.savedRegsCountExclFP specifies this size
// optional GS cookie // InfoHdrSmall.security is 1 if this exists
// LocAllocSP slot
// -- lower addresses --
//
// See also eetwain.cpp::GetLocallocSPOffset() and its callers.
if (compLocallocUsed)
{
lvaLocAllocSPvar = lvaGrabTempWithImplicitUse(false DEBUGARG("LocAllocSPvar"));
LclVarDsc* locAllocSPvar = lvaGetDesc(lvaLocAllocSPvar);
locAllocSPvar->lvType = TYP_I_IMPL;
}
#endif // JIT32_GCENCODER

// Ref counting is now enabled normally.
lvaRefCountState = RCS_NORMAL;
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/ICodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ class ICodeManager
virtual PTR_VOID GetFramePointer(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet) PURE_VIRTUAL

#ifdef TARGET_X86
virtual uintptr_t GetResumeSp(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet) PURE_VIRTUAL
#endif

virtual void EnumGcRefs(MethodInfo * pMethodInfo,
PTR_VOID safePointAddress,
REGDISPLAY * pRegisterSet,
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1677,6 +1677,13 @@ void StackFrameIterator::CalculateCurrentMethodState()
m_effectiveSafePointAddress = m_ControlPC;
m_FramePointer = GetCodeManager()->GetFramePointer(&m_methodInfo, &m_RegDisplay);

#ifdef TARGET_X86
if (m_dwFlags & UpdateResumeSp)
{
m_RegDisplay.ResumeSP = GetCodeManager()->GetResumeSp(&m_methodInfo, &m_RegDisplay);
}
#endif

m_dwFlags |= MethodStateCalculated;
}

Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/nativeaot/Runtime/StackFrameIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,11 @@ class StackFrameIterator
// When encountering a reverse P/Invoke, unwind directly to the P/Invoke frame using the saved transition frame.
SkipNativeFrames = 0x80,

// Set SP to an address that is valid for funclet resumption (x86 only)
UpdateResumeSp = 0x100,

GcStackWalkFlags = (CollapseFunclets | RemapHardwareFaultsToSafePoint | SkipNativeFrames),
EHStackWalkFlags = ApplyReturnAddressAdjustment,
EHStackWalkFlags = (ApplyReturnAddressAdjustment | UpdateResumeSp),
StackTraceStackWalkFlags = GcStackWalkFlags
};

Expand Down
17 changes: 8 additions & 9 deletions src/coreclr/nativeaot/Runtime/i386/AsmOffsetsCpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,42 @@
//
// NOTE: the offsets MUST be in hex notation WITHOUT the 0x prefix

PLAT_ASM_SIZEOF(c0, ExInfo)
PLAT_ASM_SIZEOF(c4, ExInfo)
PLAT_ASM_OFFSET(0, ExInfo, m_pPrevExInfo)
PLAT_ASM_OFFSET(4, ExInfo, m_pExContext)
PLAT_ASM_OFFSET(8, ExInfo, m_exception)
PLAT_ASM_OFFSET(0c, ExInfo, m_kind)
PLAT_ASM_OFFSET(0d, ExInfo, m_passNumber)
PLAT_ASM_OFFSET(10, ExInfo, m_idxCurClause)
PLAT_ASM_OFFSET(14, ExInfo, m_frameIter)
PLAT_ASM_OFFSET(bc, ExInfo, m_notifyDebuggerSP)
PLAT_ASM_OFFSET(c0, ExInfo, m_notifyDebuggerSP)

PLAT_ASM_OFFSET(0, PInvokeTransitionFrame, m_RIP)
PLAT_ASM_OFFSET(4, PInvokeTransitionFrame, m_FramePointer)
PLAT_ASM_OFFSET(8, PInvokeTransitionFrame, m_pThread)
PLAT_ASM_OFFSET(0c, PInvokeTransitionFrame, m_Flags)
PLAT_ASM_OFFSET(10, PInvokeTransitionFrame, m_PreservedRegs)

PLAT_ASM_SIZEOF(a8, StackFrameIterator)
PLAT_ASM_SIZEOF(ac, StackFrameIterator)
PLAT_ASM_OFFSET(08, StackFrameIterator, m_FramePointer)
PLAT_ASM_OFFSET(0c, StackFrameIterator, m_ControlPC)
PLAT_ASM_OFFSET(10, StackFrameIterator, m_RegDisplay)
PLAT_ASM_OFFSET(a0, StackFrameIterator, m_OriginalControlPC)
PLAT_ASM_OFFSET(a4, StackFrameIterator, m_pPreviousTransitionFrame)
PLAT_ASM_OFFSET(a4, StackFrameIterator, m_OriginalControlPC)
PLAT_ASM_OFFSET(a8, StackFrameIterator, m_pPreviousTransitionFrame)

PLAT_ASM_SIZEOF(1c, PAL_LIMITED_CONTEXT)
PLAT_ASM_OFFSET(0, PAL_LIMITED_CONTEXT, IP)

PLAT_ASM_OFFSET(4, PAL_LIMITED_CONTEXT, Rsp)
PLAT_ASM_OFFSET(8, PAL_LIMITED_CONTEXT, Rbp)
PLAT_ASM_OFFSET(0c, PAL_LIMITED_CONTEXT, Rdi)
PLAT_ASM_OFFSET(10, PAL_LIMITED_CONTEXT, Rsi)
PLAT_ASM_OFFSET(14, PAL_LIMITED_CONTEXT, Rax)
PLAT_ASM_OFFSET(18, PAL_LIMITED_CONTEXT, Rbx)

PLAT_ASM_SIZEOF(28, REGDISPLAY)
PLAT_ASM_OFFSET(1c, REGDISPLAY, SP)

PLAT_ASM_SIZEOF(2c, REGDISPLAY)
PLAT_ASM_OFFSET(0c, REGDISPLAY, pRbx)
PLAT_ASM_OFFSET(10, REGDISPLAY, pRbp)
PLAT_ASM_OFFSET(14, REGDISPLAY, pRsi)
PLAT_ASM_OFFSET(18, REGDISPLAY, pRdi)
PLAT_ASM_OFFSET(1c, REGDISPLAY, SP)
PLAT_ASM_OFFSET(28, REGDISPLAY, ResumeSP)
2 changes: 1 addition & 1 deletion src/coreclr/nativeaot/Runtime/i386/ExceptionHandling.asm
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ FASTCALL_FUNC RhpCallCatchFunclet, 16

mov ecx, [esp + esp_offsetof_ExInfo] ;; ecx <- current ExInfo *
mov eax, [esp + esp_offsetof_RegDisplay] ;; eax <- REGDISPLAY*
mov eax, [eax + OFFSETOF__REGDISPLAY__SP] ;; eax <- resume SP value
mov eax, [eax + OFFSETOF__REGDISPLAY__ResumeSP] ;; eax <- resume SP value

@@: mov ecx, [ecx + OFFSETOF__ExInfo__m_pPrevExInfo] ;; ecx <- next ExInfo
cmp ecx, 0
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/regdisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct REGDISPLAY

#ifdef TARGET_X86
TADDR PCTAddr;
// SP for use by catch funclet when resuming execution
uintptr_t ResumeSP;

inline unsigned long *GetEaxLocation() { return (unsigned long *)pRax; }
inline unsigned long *GetEcxLocation() { return (unsigned long *)pRcx; }
Expand Down
36 changes: 34 additions & 2 deletions src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ static PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntim
#endif
}


CoffNativeCodeManager::CoffNativeCodeManager(TADDR moduleBase,
PTR_VOID pvManagedCodeStartRange, uint32_t cbManagedCodeRange,
PTR_RUNTIME_FUNCTION pRuntimeFunctionTable, uint32_t nRuntimeFunctionTable,
Expand Down Expand Up @@ -323,7 +322,7 @@ bool CoffNativeCodeManager::IsFilter(MethodInfo * pMethInfo)
}

PTR_VOID CoffNativeCodeManager::GetFramePointer(MethodInfo * pMethInfo,
REGDISPLAY * pRegisterSet)
REGDISPLAY * pRegisterSet)
{
CoffNativeMethodInfo * pMethodInfo = (CoffNativeMethodInfo *)pMethInfo;

Expand All @@ -341,6 +340,39 @@ PTR_VOID CoffNativeCodeManager::GetFramePointer(MethodInfo * pMethInfo,
return NULL;
}

#ifdef TARGET_X86
uintptr_t CoffNativeCodeManager::GetResumeSp(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet)
{
PTR_uint8_t gcInfo;
uint32_t codeOffset = GetCodeOffset(pMethodInfo, (PTR_VOID)pRegisterSet->IP, &gcInfo);

hdrInfo infoBuf;
size_t infoSize = DecodeGCHdrInfo(GCInfoToken(gcInfo), codeOffset, &infoBuf);
PTR_CBYTE table = gcInfo + infoSize;

_ASSERTE(infoBuf.epilogOffs == hdrInfo::NOT_IN_EPILOG && infoBuf.prologOffs == hdrInfo::NOT_IN_PROLOG);

bool isESPFrame = !infoBuf.ebpFrame && !infoBuf.doubleAlign;

CoffNativeMethodInfo * pNativeMethodInfo = (CoffNativeMethodInfo *)pMethodInfo;
if (pNativeMethodInfo->mainRuntimeFunction != pNativeMethodInfo->runtimeFunction)
{
// Treat funclet's frame as ESP frame
isESPFrame = true;
}

if (isESPFrame)
{
const uintptr_t curESP = pRegisterSet->SP;
return curESP + GetPushedArgSize(&infoBuf, table, codeOffset);
}

const uintptr_t curEBP = pRegisterSet->GetFP();
return GetOutermostBaseFP(curEBP, &infoBuf);
}
#endif // TARGET_X86

uint32_t CoffNativeCodeManager::GetCodeOffset(MethodInfo* pMethodInfo, PTR_VOID address, /*out*/ PTR_uint8_t* gcInfo)
{
CoffNativeMethodInfo * pNativeMethodInfo = (CoffNativeMethodInfo *)pMethodInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class CoffNativeCodeManager : public ICodeManager
PTR_VOID GetFramePointer(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet);

#ifdef TARGET_X86
uintptr_t GetResumeSp(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet);
#endif

uint32_t GetCodeOffset(MethodInfo * pMethodInfo, PTR_VOID address, /*out*/ PTR_uint8_t* gcInfo);

bool IsSafePoint(PTR_VOID pvAddress);
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/gc_unwind_x86.inl
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ size_t GetLocallocSPOffset(hdrInfo * info)
return position * sizeof(TADDR);
}

#ifndef FEATURE_NATIVEAOT
inline
size_t GetParamTypeArgOffset(hdrInfo * info)
{
Expand Down Expand Up @@ -451,6 +450,7 @@ TADDR GetOutermostBaseFP(TADDR ebp, hdrInfo * info)
}
}

#ifndef FEATURE_NATIVEAOT
/*****************************************************************************
*
* For functions with handlers, checks if it is currently in a handler.
Expand Down Expand Up @@ -662,7 +662,7 @@ inline size_t GetSizeOfFrameHeaderForEnC(hdrInfo * info)
return sizeof(TADDR) +
GetEndShadowSPSlotsOffset(info, MAX_EnC_HANDLER_NESTING_LEVEL);
}
#endif
#endif // FEATURE_NATIVEAOT

/*****************************************************************************/
static
Expand Down