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

Test #100655

Closed
wants to merge 3 commits into from
Closed

Test #100655

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
6 changes: 4 additions & 2 deletions docs/design/coreclr/botr/clr-abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,13 @@ This section describes the conventions the JIT needs to follow when generating c

## Funclets

For all platforms except Windows/x86, all managed EH handlers (finally, fault, filter, filter-handler, and catch) are extracted into their own 'funclets'. To the OS they are treated just like first class functions (separate PDATA and XDATA (`RUNTIME_FUNCTION` entry), etc.). The CLR currently treats them just like part of the parent function in many ways. The main function and all funclets must be allocated in a single code allocation (see hot cold splitting). They 'share' GC info. Only the main function prolog can be hot patched.
For all platforms except Windows/x86 on CoreCLR, all managed EH handlers (finally, fault, filter, filter-handler, and catch) are extracted into their own 'funclets'. To the OS they are treated just like first class functions (separate PDATA and XDATA (`RUNTIME_FUNCTION` entry), etc.). The CLR currently treats them just like part of the parent function in many ways. The main function and all funclets must be allocated in a single code allocation (see hot cold splitting). They 'share' GC info. Only the main function prolog can be hot patched.

The only way to enter a handler funclet is via a call. In the case of an exception, the call is from the VM's EH subsystem as part of exception dispatch/unwind. In the non-exceptional case, this is called local unwind or a non-local exit. In C# this is accomplished by simply falling-through/out of a try body or an explicit goto. In IL this is always accomplished via a LEAVE opcode, within a try body, targeting an IL offset outside the try body. In such cases the call is from the JITed code of the parent function.

For Windows/x86, all handlers are generated within the method body, typically in lexical order. A nested try/catch is generated completely within the EH region in which it is nested. These handlers are essentially "in-line funclets", but they do not look like normal functions: they do not have a normal prolog or epilog, although they do have special entry/exit and register conventions. Also, nested handlers are not un-nested as for funclets: the code for a nested handler is generated within the handler in which it is nested.
For Windows/x86 on CoreCLR, all handlers are generated within the method body, typically in lexical order. A nested try/catch is generated completely within the EH region in which it is nested. These handlers are essentially "in-line funclets", but they do not look like normal functions: they do not have a normal prolog or epilog, although they do have special entry/exit and register conventions. Also, nested handlers are not un-nested as for funclets: the code for a nested handler is generated within the handler in which it is nested.

For Windows/x86 on NativeAOT and Linux/x86, funclets are used just like on other platforms.

## Cloned finallys

Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,4 @@ function(set_target_definitions_to_custom_os_and_arch)
if (TARGETDETAILS_ARCH STREQUAL "armel")
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE ARM_SOFTFP)
endif()

if (NOT (TARGETDETAILS_ARCH STREQUAL "x86") OR (TARGETDETAILS_OS MATCHES "^unix") OR (TARGETDETAILS_OS MATCHES "win_aot"))
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE FEATURE_EH_FUNCLETS)
endif (NOT (TARGETDETAILS_ARCH STREQUAL "x86") OR (TARGETDETAILS_OS MATCHES "^unix") OR (TARGETDETAILS_OS MATCHES "win_aot"))
endfunction()
7 changes: 0 additions & 7 deletions src/coreclr/crosscomponents.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS OR CLR_CMAKE_TARGET_IOS OR CL
DESTINATIONS .
COMPONENT crosscomponents
)
if (CLR_CMAKE_TARGET_ARCH_I386)
install_clr (TARGETS
clrjit_win_aot_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME}
DESTINATIONS .
COMPONENT crosscomponents
)
endif()
endif()
endif()
endif()
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/inc/clrnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ typedef struct _DISPATCHER_CONTEXT {
#define RUNTIME_FUNCTION__BeginAddress(prf) (prf)->BeginAddress
#define RUNTIME_FUNCTION__SetBeginAddress(prf,addr) ((prf)->BeginAddress = (addr))

#ifdef FEATURE_EH_FUNCLETS
#include "win64unwind.h"
#include "daccess.h"

Expand Down Expand Up @@ -235,7 +234,6 @@ RtlVirtualUnwind (
__inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers
);
#endif // HOST_X86
#endif // FEATURE_EH_FUNCLETS

#endif // TARGET_X86

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/inc/gcinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const unsigned OFFSET_MASK = 0x3; // mask to access the low 2 bits
//
const unsigned byref_OFFSET_FLAG = 0x1; // the offset is an interior ptr
const unsigned pinned_OFFSET_FLAG = 0x2; // the offset is a pinned ptr
#if defined(TARGET_X86) && !defined(FEATURE_EH_FUNCLETS)
#if defined(TARGET_X86)
// JIT32_ENCODER has additional restriction on x86 without funclets:
// - for untracked locals the flags allowed are "pinned" and "byref"
// - for tracked locals the flags allowed are "this" and "byref"
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ function(create_standalone_jit)

if(TARGETDETAILS_OS STREQUAL "unix_osx" OR TARGETDETAILS_OS STREQUAL "unix_anyos")
set(JIT_ARCH_LINK_LIBRARIES gcinfo_unix_${TARGETDETAILS_ARCH})
elseif(TARGETDETAILS_OS STREQUAL "win_aot")
set(JIT_ARCH_LINK_LIBRARIES gcinfo_win_${TARGETDETAILS_ARCH})
else()
set(JIT_ARCH_LINK_LIBRARIES gcinfo_${TARGETDETAILS_OS}_${TARGETDETAILS_ARCH})
endif()
Expand Down Expand Up @@ -658,7 +656,6 @@ else()
create_standalone_jit(TARGET clrjit_universal_arm_${ARCH_HOST_NAME} OS universal ARCH arm DESTINATIONS .)
target_compile_definitions(clrjit_universal_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI)
create_standalone_jit(TARGET clrjit_win_x86_${ARCH_HOST_NAME} OS win ARCH x86 DESTINATIONS .)
create_standalone_jit(TARGET clrjit_win_aot_x86_${ARCH_HOST_NAME} OS win_aot ARCH x86 DESTINATIONS .)
endif (CLR_CMAKE_TARGET_ARCH_RISCV64)

if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX)
Expand Down
13 changes: 1 addition & 12 deletions src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1812,9 +1812,7 @@ bool BasicBlock::hasEHBoundaryIn() const
bool returnVal = (bbCatchTyp != BBCT_NONE);
if (!returnVal)
{
#if FEATURE_EH_FUNCLETS
assert(!HasFlag(BBF_FUNCLET_BEG));
#endif // FEATURE_EH_FUNCLETS
}
return returnVal;
}
Expand All @@ -1833,16 +1831,7 @@ bool BasicBlock::hasEHBoundaryIn() const
//
bool BasicBlock::hasEHBoundaryOut() const
{
bool returnVal = KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET);

#if FEATURE_EH_FUNCLETS
if (bbKind == BBJ_EHCATCHRET)
{
returnVal = true;
}
#endif // FEATURE_EH_FUNCLETS

return returnVal;
return KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHCATCHRET);
}

//------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ enum BBKinds : BYTE
BBJ_EHFINALLYRET,// block ends with 'endfinally' (for finally)
BBJ_EHFAULTRET, // block ends with 'endfinally' (IL alias for 'endfault') (for fault)
BBJ_EHFILTERRET, // block ends with 'endfilter'
BBJ_EHCATCHRET, // block ends with a leave out of a catch (only #if defined(FEATURE_EH_FUNCLETS))
BBJ_EHCATCHRET, // block ends with a leave out of a catch
BBJ_THROW, // block ends with 'throw'
BBJ_RETURN, // block ends with 'ret'
BBJ_ALWAYS, // block always jumps to the target
Expand Down
19 changes: 2 additions & 17 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,6 @@ class CodeGen final : public CodeGenInterface
void genFnProlog();
void genFnEpilog(BasicBlock* block);

#if defined(FEATURE_EH_FUNCLETS)

void genReserveFuncletProlog(BasicBlock* block);
void genReserveFuncletEpilog(BasicBlock* block);
void genFuncletProlog(BasicBlock* block);
Expand Down Expand Up @@ -640,16 +638,6 @@ class CodeGen final : public CodeGenInterface

void genUpdateCurrentFunclet(BasicBlock* block);

#else // !FEATURE_EH_FUNCLETS

// This is a no-op when there are no funclets!
void genUpdateCurrentFunclet(BasicBlock* block)
{
return;
}

#endif // !FEATURE_EH_FUNCLETS

void genGeneratePrologsAndEpilogs();

#if defined(DEBUG)
Expand Down Expand Up @@ -744,9 +732,7 @@ class CodeGen final : public CodeGenInterface
void siOpenScopesForNonTrackedVars(const BasicBlock* block, unsigned int lastBlockILEndOffset);

protected:
#if defined(FEATURE_EH_FUNCLETS)
bool siInFuncletRegion; // Have we seen the start of the funclet region?
#endif // FEATURE_EH_FUNCLETS

IL_OFFSET siLastEndOffs; // IL offset of the (exclusive) end of the last block processed

Expand Down Expand Up @@ -1291,11 +1277,10 @@ class CodeGen final : public CodeGenInterface
void genCodeForBfiz(GenTreeOp* tree);
#endif // TARGET_ARM64

#if defined(FEATURE_EH_FUNCLETS)
void genEHCatchRet(BasicBlock* block);
#else // !FEATURE_EH_FUNCLETS
#if defined(FEATURE_EH_WINDOWS_X86)
void genEHFinallyOrFilterRet(BasicBlock* block);
#endif // !FEATURE_EH_FUNCLETS
#endif // FEATURE_EH_WINDOWS_X86

void genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode);
void genMultiRegStoreToLocal(GenTreeLclVar* lclNode);
Expand Down
Loading