Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI run only] Use funclets and new EH on win-x86 #113576

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
5 changes: 1 addition & 4 deletions src/coreclr/clr.featuredefines.props
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
<PropertyGroup>
<FeatureCoreCLR>true</FeatureCoreCLR>
<FeaturePerfTracing>true</FeaturePerfTracing>
<FeatureEHFunclets>true</FeatureEHFunclets>
<ProfilingSupportedBuild>true</ProfilingSupportedBuild>
</PropertyGroup>

@@ -22,10 +23,6 @@
<FeatureObjCMarshal>true</FeatureObjCMarshal>
</PropertyGroup>

<PropertyGroup Condition="!('$(TargetsWindows)' == 'true' AND '$(Platform)' == 'x86')">
<FeatureEHFunclets>true</FeatureEHFunclets>
</PropertyGroup>

<PropertyGroup>
<DefineConstants Condition="'$(FeatureComWrappers)' == 'true'">$(DefineConstants);FEATURE_COMWRAPPERS</DefineConstants>
<DefineConstants Condition="'$(FeatureCominterop)' == 'true'">$(DefineConstants);FEATURE_COMINTEROP</DefineConstants>
4 changes: 1 addition & 3 deletions src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
@@ -205,9 +205,7 @@ if(CLR_CMAKE_TARGET_WIN32)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
endif(CLR_CMAKE_TARGET_WIN32)

if (NOT CLR_CMAKE_TARGET_ARCH_I386 OR NOT CLR_CMAKE_TARGET_WIN32)
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:FEATURE_EH_FUNCLETS>)
endif (NOT CLR_CMAKE_TARGET_ARCH_I386 OR NOT CLR_CMAKE_TARGET_WIN32)
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:FEATURE_EH_FUNCLETS>)

if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64))
add_definitions(-DFEATURE_SPECIAL_USER_MODE_APC)
2 changes: 1 addition & 1 deletion src/coreclr/debug/ee/debugger.h
Original file line number Diff line number Diff line change
@@ -3994,7 +3994,7 @@ HANDLE OpenWin32EventOrThrow(
// Returns true if the specified IL offset has a special meaning (eg. prolog, etc.)
bool DbgIsSpecialILOffset(DWORD offset);

#if defined(TARGET_WINDOWS)
#if defined(TARGET_WINDOWS) && !defined(TARGET_X86)
void FixupDispatcherContext(T_DISPATCHER_CONTEXT* pDispatcherContext, T_CONTEXT* pContext, PEXCEPTION_ROUTINE pUnwindPersonalityRoutine = NULL);
#endif

5 changes: 2 additions & 3 deletions src/coreclr/debug/ee/funceval.cpp
Original file line number Diff line number Diff line change
@@ -3990,7 +3990,7 @@ void * STDCALL FuncEvalHijackWorker(DebuggerEval *pDE)
}


#if defined(FEATURE_EH_FUNCLETS) && !defined(TARGET_UNIX)
#if defined(FEATURE_EH_FUNCLETS) && !defined(TARGET_UNIX) && !defined(TARGET_X86)

EXTERN_C EXCEPTION_DISPOSITION
FuncEvalHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
@@ -4028,7 +4028,6 @@ FuncEvalHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
return ExceptionCollidedUnwind;
}


#endif // FEATURE_EH_FUNCLETS && !TARGET_UNIX
#endif // FEATURE_EH_FUNCLETS && !TARGET_UNIX && !TARGET_X86

#endif // ifndef DACCESS_COMPILE
2 changes: 1 addition & 1 deletion src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ add_dependencies(coreclr coreclr_exports)
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})

if (CLR_CMAKE_HOST_UNIX)
if (CLR_CMAKE_HOST_UNIX OR CLR_CMAKE_TARGET_ARCH_I386)
set(LIB_UNWINDER unwinder_wks)
endif (CLR_CMAKE_HOST_UNIX)

4 changes: 4 additions & 0 deletions src/coreclr/gcdump/i386/gcdumpx86.cpp
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@
#endif
#include "gcdump.h"

// FIXME
#ifndef FEATURE_EH_FUNCLETS
#define FEATURE_EH_FUNCLETS
#endif

/*****************************************************************************/

30 changes: 30 additions & 0 deletions src/coreclr/inc/crosscomp.h
Original file line number Diff line number Diff line change
@@ -667,6 +667,36 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
#define T_DISPATCHER_CONTEXT DISPATCHER_CONTEXT
#define PT_DISPATCHER_CONTEXT PDISPATCHER_CONTEXT

#if defined(TARGET_WINDOWS) && defined(TARGET_X86)
typedef struct _KNONVOLATILE_CONTEXT {

DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Ebp;

} KNONVOLATILE_CONTEXT, *PKNONVOLATILE_CONTEXT;

typedef struct _KNONVOLATILE_CONTEXT_POINTERS_EX
{
// The ordering of these fields should be aligned with that
// of corresponding fields in CONTEXT
//
// (See FillRegDisplay in inc/regdisp.h for details)
PDWORD Edi;
PDWORD Esi;
PDWORD Ebx;
PDWORD Edx;
PDWORD Ecx;
PDWORD Eax;

PDWORD Ebp;

} KNONVOLATILE_CONTEXT_POINTERS_EX, *PKNONVOLATILE_CONTEXT_POINTERS_EX;

#define KNONVOLATILE_CONTEXT_POINTERS KNONVOLATILE_CONTEXT_POINTERS_EX
#define PKNONVOLATILE_CONTEXT_POINTERS PKNONVOLATILE_CONTEXT_POINTERS_EX
#endif
#define T_KNONVOLATILE_CONTEXT_POINTERS KNONVOLATILE_CONTEXT_POINTERS
#define PT_KNONVOLATILE_CONTEXT_POINTERS PKNONVOLATILE_CONTEXT_POINTERS

10 changes: 0 additions & 10 deletions src/coreclr/inc/regdisp.h
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@
#ifndef __REGDISP_H
#define __REGDISP_H


#ifdef DEBUG_REGDISPLAY
class Thread;
struct REGDISPLAY;
@@ -146,21 +145,12 @@ inline void SetRegdisplayPCTAddr(REGDISPLAY *display, TADDR addr)
inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) {
LIMITED_METHOD_CONTRACT;

#ifdef FEATURE_EH_FUNCLETS
return stackPointer < ((LPVOID)(display->SP));
#else
return (TADDR)stackPointer < display->PCTAddr;
#endif
}
inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
LIMITED_METHOD_DAC_CONTRACT;

#ifdef FEATURE_EH_FUNCLETS
_ASSERTE(GetRegdisplaySP(display) == GetSP(display->pCurrentContext));
return GetRegdisplaySP(display);
#else
return display->PCTAddr;
#endif
}

#elif defined(TARGET_64BIT)
6 changes: 4 additions & 2 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
@@ -190,17 +190,19 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
// then RSP at this point is the same value as that stored in the PSPSym. So just copy RSP
// instead of loading the PSPSym in this case, or if PSPSym is not used (NativeAOT ABI).

// x86 funclet ABI doesn't store the stack pointer in ECX. It's recovered from the context
// instead after executing the funclet.
#ifndef TARGET_X86
if ((compiler->lvaPSPSym == BAD_VAR_NUM) ||
(!compiler->compLocallocUsed && (compiler->funCurrentFunc()->funKind == FUNC_ROOT)))
{
#ifndef UNIX_X86_ABI
inst_Mov(TYP_I_IMPL, REG_ARG_0, REG_SPBASE, /* canSkip */ false);
#endif // !UNIX_X86_ABI
}
else
{
GetEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_ARG_0, compiler->lvaPSPSym, 0);
}
#endif // !TARGET_X86

if (block->HasFlag(BBF_RETLESS_CALL))
{
3 changes: 0 additions & 3 deletions src/coreclr/jit/targetx86.h
Original file line number Diff line number Diff line change
@@ -52,9 +52,6 @@
// target
#define FEATURE_EH 1 // To aid platform bring-up, eliminate exceptional EH clauses (catch, filter,
// filter-handler, fault) and directly execute 'finally' clauses.
#if !defined(UNIX_X86_ABI)
#define FEATURE_EH_WINDOWS_X86 1 // Enable support for SEH regions
#endif
#define ETW_EBP_FRAMED 1 // if 1 we cannot use EBP as a scratch register and must create EBP based
// frames for most methods
#define CSE_CONSTS 1 // Enable if we want to CSE constants
2 changes: 1 addition & 1 deletion src/coreclr/unwinder/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ set(UNWINDER_SOURCES

convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES})

if(CLR_CMAKE_HOST_UNIX)
if(CLR_CMAKE_HOST_UNIX OR CLR_CMAKE_TARGET_ARCH_I386)
add_library_clr(unwinder_wks OBJECT ${UNWINDER_SOURCES})
add_unwinder_include_directories(unwinder_wks)
add_dependencies(unwinder_wks eventing_headers)
6 changes: 1 addition & 5 deletions src/coreclr/unwinder/i386/unwinder.cpp
Original file line number Diff line number Diff line change
@@ -44,15 +44,11 @@ BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTE

pContextRecord->ContextFlags |= CONTEXT_UNWOUND_TO_CALL;

#define ARGUMENT_AND_SCRATCH_REGISTER(reg) if (rd.pCurrentContextPointers->reg) pContextRecord->reg = *rd.pCurrentContextPointers->reg;
ENUM_ARGUMENT_AND_SCRATCH_REGISTERS();
#undef ARGUMENT_AND_SCRATCH_REGISTER

#define CALLEE_SAVED_REGISTER(reg) if (rd.pCurrentContextPointers->reg) pContextRecord->reg = *rd.pCurrentContextPointers->reg;
ENUM_CALLEE_SAVED_REGISTERS();
#undef CALLEE_SAVED_REGISTER

pContextRecord->Esp = rd.SP - codeInfo.GetCodeManager()->GetStackParameterSize(&codeInfo);
pContextRecord->Esp = rd.SP;
pContextRecord->Eip = rd.ControlPC;

return TRUE;
10 changes: 0 additions & 10 deletions src/coreclr/vm/amd64/cgenamd64.cpp
Original file line number Diff line number Diff line change
@@ -349,16 +349,6 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats
pRD->pCurrentContextPointers->Rax = (PULONG64)&m_Args->Rax;

SyncRegDisplayToCurrentContext(pRD);

/*
// This only describes the top-most frame
pRD->pContext = NULL;
pRD->PCTAddr = dac_cast<TADDR>(m_Args) + offsetof(HijackArgs, Rip);
//pRD->pPC = PTR_SLOT(pRD->PCTAddr);
pRD->SP = (ULONG64)(pRD->PCTAddr + sizeof(TADDR));
*/
}
#endif // FEATURE_HIJACK

6 changes: 6 additions & 0 deletions src/coreclr/vm/codeman.cpp
Original file line number Diff line number Diff line change
@@ -6533,6 +6533,11 @@ BOOL ReadyToRunJitManager::IsFilterFunclet(EECodeInfo * pCodeInfo)
if (!pCodeInfo->IsFunclet())
return FALSE;

#ifdef TARGET_X86
// x86 doesn't use personality routines in unwind data, so we have to fallback to
// the slow implementation
return IJitManager::IsFilterFunclet(pCodeInfo);
#else
// Get address of the personality routine for the function being queried.
SIZE_T size;
PTR_VOID pUnwindData = GetUnwindDataBlob(pCodeInfo->GetModuleBase(), pCodeInfo->GetFunctionEntry(), &size);
@@ -6557,6 +6562,7 @@ BOOL ReadyToRunJitManager::IsFilterFunclet(EECodeInfo * pCodeInfo)
_ASSERTE(fRet == IJitManager::IsFilterFunclet(pCodeInfo));

return fRet;
#endif
}

#endif // FEATURE_EH_FUNCLETS
66 changes: 48 additions & 18 deletions src/coreclr/vm/eetwain.cpp
Original file line number Diff line number Diff line change
@@ -1086,7 +1086,7 @@ size_t EECodeManager::GetResumeSp( PCONTEXT pContext )
#endif // TARGET_X86
#endif // FEATURE_EH_FUNCLETS

#ifndef FEATURE_EH_FUNCLETS
#ifdef TARGET_X86

/*****************************************************************************
*
@@ -1109,7 +1109,30 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
SUPPORTS_DAC;
} CONTRACTL_END;

#ifdef TARGET_X86
#ifdef FEATURE_EH_FUNCLETS
if (pContext->IsCallerContextValid)
{
// We already have the caller's frame context
// We just switch the pointers
PT_CONTEXT temp = pContext->pCurrentContext;
pContext->pCurrentContext = pContext->pCallerContext;
pContext->pCallerContext = temp;

PT_KNONVOLATILE_CONTEXT_POINTERS tempPtrs = pContext->pCurrentContextPointers;
pContext->pCurrentContextPointers = pContext->pCallerContextPointers;
pContext->pCallerContextPointers = tempPtrs;

SyncRegDisplayToCurrentContext(pContext);

pContext->PCTAddr = pContext->SP - GetStackParameterSize(pCodeInfo) - sizeof(DWORD);

pContext->IsCallerContextValid = FALSE;
pContext->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.

return true;
}
#endif

bool updateAllRegs = flags & UpdateAllRegs;

// Address where the method has been interrupted
@@ -1138,22 +1161,31 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,

info->isSpeculativeStackWalk = ((flags & SpeculativeStackwalk) != 0);

return UnwindStackFrameX86(pContext,
PTR_CBYTE(pCodeInfo->GetSavedMethodCode()),
curOffs,
info,
table,
IN_EH_FUNCLETS_COMMA(PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)))
IN_EH_FUNCLETS_COMMA(pCodeInfo->IsFunclet())
updateAllRegs);
#else // TARGET_X86
PORTABILITY_ASSERT("EECodeManager::UnwindStackFrame");
return false;
#endif // _TARGET_???_
if (!UnwindStackFrameX86(pContext,
PTR_CBYTE(pCodeInfo->GetSavedMethodCode()),
curOffs,
info,
table,
IN_EH_FUNCLETS_COMMA(PTR_CBYTE(pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo)))
IN_EH_FUNCLETS_COMMA(pCodeInfo->IsFunclet())
updateAllRegs))
{
return false;
}

#ifdef FEATURE_EH_FUNCLETS
pContext->pCurrentContext->ContextFlags |= CONTEXT_UNWOUND_TO_CALL;
pContext->pCurrentContext->Esp = pContext->SP;
pContext->pCurrentContext->Eip = pContext->ControlPC;
pContext->IsCallerContextValid = FALSE;
pContext->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
#endif

return true;
}

/*****************************************************************************/
#else // !FEATURE_EH_FUNCLETS
#else // !TARGET_X86
/*****************************************************************************/

bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
@@ -1181,7 +1213,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
}

/*****************************************************************************/
#endif // FEATURE_EH_FUNCLETS
#endif // TARGET_X86

/*****************************************************************************/

@@ -2267,8 +2299,6 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
hdrInfo * pHdrInfo = &(pStateBuf->hdrInfoBody);
pStateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, dwOffset, pHdrInfo);

// We need to subtract 4 here because ESPIncrOnReturn() includes the stack slot containing the return
// address.
return (ULONG32)::GetStackParameterSize(pHdrInfo);

#else
Loading