Skip to content

Commit 41b1091

Browse files
Replace FEATURE_EH_FUNCLETS in JIT with runtime switch (#99191)
* Replace FEATURE_EH_FUNCLETS/FEATURE_EH_CALLFINALLY_THUNKS in JIT with runtime switch * Cache Native AOT ABI check to see if TP improves --------- Co-authored-by: Bruce Forstall <[email protected]>
1 parent e1f5378 commit 41b1091

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1104
-1311
lines changed

docs/design/coreclr/botr/clr-abi.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,13 @@ This section describes the conventions the JIT needs to follow when generating c
177177

178178
## Funclets
179179

180-
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.
180+
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.
181181

182182
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.
183183

184-
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.
184+
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.
185+
186+
For Windows/x86 on NativeAOT and Linux/x86, funclets are used just like on other platforms.
185187

186188
## Cloned finallys
187189

src/coreclr/clrdefinitions.cmake

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,4 @@ function(set_target_definitions_to_custom_os_and_arch)
288288
if (TARGETDETAILS_ARCH STREQUAL "armel")
289289
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE ARM_SOFTFP)
290290
endif()
291-
292-
if (NOT (TARGETDETAILS_ARCH STREQUAL "x86") OR (TARGETDETAILS_OS MATCHES "^unix") OR (TARGETDETAILS_OS MATCHES "win_aot"))
293-
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE FEATURE_EH_FUNCLETS)
294-
endif (NOT (TARGETDETAILS_ARCH STREQUAL "x86") OR (TARGETDETAILS_OS MATCHES "^unix") OR (TARGETDETAILS_OS MATCHES "win_aot"))
295291
endfunction()

src/coreclr/crosscomponents.cmake

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS OR CLR_CMAKE_TARGET_IOS OR CL
2525
DESTINATIONS .
2626
COMPONENT crosscomponents
2727
)
28-
if (CLR_CMAKE_TARGET_ARCH_I386)
29-
install_clr (TARGETS
30-
clrjit_win_aot_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME}
31-
DESTINATIONS .
32-
COMPONENT crosscomponents
33-
)
34-
endif()
3528
endif()
3629
endif()
3730
endif()

src/coreclr/inc/clrnt.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ typedef struct _DISPATCHER_CONTEXT {
201201
#define RUNTIME_FUNCTION__BeginAddress(prf) (prf)->BeginAddress
202202
#define RUNTIME_FUNCTION__SetBeginAddress(prf,addr) ((prf)->BeginAddress = (addr))
203203

204-
#ifdef FEATURE_EH_FUNCLETS
205204
#include "win64unwind.h"
206205
#include "daccess.h"
207206

@@ -235,7 +234,6 @@ RtlVirtualUnwind (
235234
__inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers
236235
);
237236
#endif // HOST_X86
238-
#endif // FEATURE_EH_FUNCLETS
239237

240238
#endif // TARGET_X86
241239

src/coreclr/inc/gcinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const unsigned OFFSET_MASK = 0x3; // mask to access the low 2 bits
2525
//
2626
const unsigned byref_OFFSET_FLAG = 0x1; // the offset is an interior ptr
2727
const unsigned pinned_OFFSET_FLAG = 0x2; // the offset is a pinned ptr
28-
#if defined(TARGET_X86) && !defined(FEATURE_EH_FUNCLETS)
28+
#if defined(TARGET_X86)
2929
// JIT32_ENCODER has additional restriction on x86 without funclets:
3030
// - for untracked locals the flags allowed are "pinned" and "byref"
3131
// - for tracked locals the flags allowed are "this" and "byref"

src/coreclr/jit/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ function(create_standalone_jit)
2323

2424
if(TARGETDETAILS_OS STREQUAL "unix_osx" OR TARGETDETAILS_OS STREQUAL "unix_anyos")
2525
set(JIT_ARCH_LINK_LIBRARIES gcinfo_unix_${TARGETDETAILS_ARCH})
26-
elseif(TARGETDETAILS_OS STREQUAL "win_aot")
27-
set(JIT_ARCH_LINK_LIBRARIES gcinfo_win_${TARGETDETAILS_ARCH})
2826
else()
2927
set(JIT_ARCH_LINK_LIBRARIES gcinfo_${TARGETDETAILS_OS}_${TARGETDETAILS_ARCH})
3028
endif()
@@ -658,7 +656,6 @@ else()
658656
create_standalone_jit(TARGET clrjit_universal_arm_${ARCH_HOST_NAME} OS universal ARCH arm DESTINATIONS .)
659657
target_compile_definitions(clrjit_universal_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI)
660658
create_standalone_jit(TARGET clrjit_win_x86_${ARCH_HOST_NAME} OS win ARCH x86 DESTINATIONS .)
661-
create_standalone_jit(TARGET clrjit_win_aot_x86_${ARCH_HOST_NAME} OS win_aot ARCH x86 DESTINATIONS .)
662659
endif (CLR_CMAKE_TARGET_ARCH_RISCV64)
663660

664661
if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX)

src/coreclr/jit/block.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,9 +1812,7 @@ bool BasicBlock::hasEHBoundaryIn() const
18121812
bool returnVal = (bbCatchTyp != BBCT_NONE);
18131813
if (!returnVal)
18141814
{
1815-
#if FEATURE_EH_FUNCLETS
18161815
assert(!HasFlag(BBF_FUNCLET_BEG));
1817-
#endif // FEATURE_EH_FUNCLETS
18181816
}
18191817
return returnVal;
18201818
}
@@ -1833,16 +1831,7 @@ bool BasicBlock::hasEHBoundaryIn() const
18331831
//
18341832
bool BasicBlock::hasEHBoundaryOut() const
18351833
{
1836-
bool returnVal = KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET);
1837-
1838-
#if FEATURE_EH_FUNCLETS
1839-
if (bbKind == BBJ_EHCATCHRET)
1840-
{
1841-
returnVal = true;
1842-
}
1843-
#endif // FEATURE_EH_FUNCLETS
1844-
1845-
return returnVal;
1834+
return KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHCATCHRET);
18461835
}
18471836

18481837
//------------------------------------------------------------------------

src/coreclr/jit/block.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ enum BBKinds : BYTE
6666
BBJ_EHFINALLYRET,// block ends with 'endfinally' (for finally)
6767
BBJ_EHFAULTRET, // block ends with 'endfinally' (IL alias for 'endfault') (for fault)
6868
BBJ_EHFILTERRET, // block ends with 'endfilter'
69-
BBJ_EHCATCHRET, // block ends with a leave out of a catch (only #if defined(FEATURE_EH_FUNCLETS))
69+
BBJ_EHCATCHRET, // block ends with a leave out of a catch
7070
BBJ_THROW, // block ends with 'throw'
7171
BBJ_RETURN, // block ends with 'ret'
7272
BBJ_ALWAYS, // block always jumps to the target

src/coreclr/jit/codegen.h

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,6 @@ class CodeGen final : public CodeGenInterface
559559
void genFnProlog();
560560
void genFnEpilog(BasicBlock* block);
561561

562-
#if defined(FEATURE_EH_FUNCLETS)
563-
564562
void genReserveFuncletProlog(BasicBlock* block);
565563
void genReserveFuncletEpilog(BasicBlock* block);
566564
void genFuncletProlog(BasicBlock* block);
@@ -643,16 +641,6 @@ class CodeGen final : public CodeGenInterface
643641

644642
void genUpdateCurrentFunclet(BasicBlock* block);
645643

646-
#else // !FEATURE_EH_FUNCLETS
647-
648-
// This is a no-op when there are no funclets!
649-
void genUpdateCurrentFunclet(BasicBlock* block)
650-
{
651-
return;
652-
}
653-
654-
#endif // !FEATURE_EH_FUNCLETS
655-
656644
void genGeneratePrologsAndEpilogs();
657645

658646
#if defined(DEBUG)
@@ -747,9 +735,7 @@ class CodeGen final : public CodeGenInterface
747735
void siOpenScopesForNonTrackedVars(const BasicBlock* block, unsigned int lastBlockILEndOffset);
748736

749737
protected:
750-
#if defined(FEATURE_EH_FUNCLETS)
751738
bool siInFuncletRegion; // Have we seen the start of the funclet region?
752-
#endif // FEATURE_EH_FUNCLETS
753739

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

@@ -1294,11 +1280,10 @@ class CodeGen final : public CodeGenInterface
12941280
void genCodeForBfiz(GenTreeOp* tree);
12951281
#endif // TARGET_ARM64
12961282

1297-
#if defined(FEATURE_EH_FUNCLETS)
12981283
void genEHCatchRet(BasicBlock* block);
1299-
#else // !FEATURE_EH_FUNCLETS
1284+
#if defined(FEATURE_EH_WINDOWS_X86)
13001285
void genEHFinallyOrFilterRet(BasicBlock* block);
1301-
#endif // !FEATURE_EH_FUNCLETS
1286+
#endif // FEATURE_EH_WINDOWS_X86
13021287

13031288
void genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode);
13041289
void genMultiRegStoreToLocal(GenTreeLclVar* lclNode);

0 commit comments

Comments
 (0)