Skip to content

Commit cec44d6

Browse files
authored
Interpreter EH support in the runtime (#114649)
* Interpreter EH support in the runtime This change adds support for exception handling for cases when interpreter frames participate in the process. That means when an exception is thrown from an interpreter frame or when it is propagated over interpreter frames. This doesn't add all the exception handling support to the interpreter itself, there is a follow up PR that contains that code. * Fix arm64 build * Fix few issues * Fix non-windows amd64 builds ifdef-out setting m_SSP in the InterpreterFrame * Fix x86, arm and arm64 build break * Fix incorrect assert We cannot try to get the code manager from a crawl frame when it is not on a frameless frame. * Resuming after catch via native exception This commit moves the resuming after catch to using native exception handling instead of fragile context capturing, which was not correct anyways. It also adds handling of exceptions comming out of native runtime methods called from the interpreter. * Remove some unneeded stuff and fix Unix build * Move the saved InterpExecMethod context regs * Move the saved registers to the StackFrameIterator * Fix MUSL build * Add {Get/Set}{First/Second}ArgumentRegister to all architectures and use those in ExecuteFunctionBelowContext. * Few fixes * Fix builds with disabled interpreter * One more MUSL build fix * Implement proper GetFuncletStartAddress for interpreter * Fix problem with missing managed FEATURE_INTERPRETER define * Revert "Implement proper GetFuncletStartAddress for interpreter" This reverts commit d967861.
1 parent 5cd7566 commit cec44d6

File tree

26 files changed

+1692
-1170
lines changed

26 files changed

+1692
-1170
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,14 @@ class AsmOffsets
5858

5959
#if TARGET_64BIT
6060
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x8;
61+
#if FEATURE_INTERPRETER
62+
public const int SIZEOF__StackFrameIterator = 0x170;
63+
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x168;
64+
#else
6165
public const int SIZEOF__StackFrameIterator = 0x150;
62-
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x132;
6366
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x148;
67+
#endif
68+
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x132;
6469
#elif TARGET_X86
6570
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
6671
public const int SIZEOF__StackFrameIterator = 0x3cc;
@@ -119,9 +124,14 @@ class AsmOffsets
119124

120125
#if TARGET_64BIT
121126
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x8;
127+
#if FEATURE_INTERPRETER
128+
public const int SIZEOF__StackFrameIterator = 0x168;
129+
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x160;
130+
#else
122131
public const int SIZEOF__StackFrameIterator = 0x148;
123-
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x12a;
124132
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x140;
133+
#endif
134+
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0x12a;
125135
#elif TARGET_X86
126136
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
127137
public const int SIZEOF__StackFrameIterator = 0x3c4;

src/coreclr/clr.featuredefines.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
<FeatureEHFunclets>true</FeatureEHFunclets>
2727
</PropertyGroup>
2828

29+
<PropertyGroup Condition="('$(Platform)' == 'x64' OR '$(Platform)' == 'arm64') AND ('$(Configuration)' == 'debug' OR '$(Configuration)' == 'checked')">
30+
<FeatureInterpreter>true</FeatureInterpreter>
31+
</PropertyGroup>
32+
2933
<PropertyGroup>
3034
<DefineConstants Condition="'$(FeatureComWrappers)' == 'true'">$(DefineConstants);FEATURE_COMWRAPPERS</DefineConstants>
3135
<DefineConstants Condition="'$(FeatureCominterop)' == 'true'">$(DefineConstants);FEATURE_COMINTEROP</DefineConstants>
@@ -36,6 +40,7 @@
3640
<DefineConstants Condition="'$(FeatureXplatEventSource)' == 'true'">$(DefineConstants);FEATURE_EVENTSOURCE_XPLAT</DefineConstants>
3741
<DefineConstants Condition="'$(FeatureTypeEquivalence)' == 'true'">$(DefineConstants);FEATURE_TYPEEQUIVALENCE</DefineConstants>
3842
<DefineConstants Condition="'$(FeatureEHFunclets)' == 'true'">$(DefineConstants);FEATURE_EH_FUNCLETS</DefineConstants>
43+
<DefineConstants Condition="'$(FeatureInterpreter)' == 'true'">$(DefineConstants);FEATURE_INTERPRETER</DefineConstants>
3944

4045
<DefineConstants Condition="'$(ProfilingSupportedBuild)' == 'true'">$(DefineConstants);PROFILING_SUPPORTED</DefineConstants>
4146
</PropertyGroup>

src/coreclr/inc/eetwain.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ virtual void LeaveCatch(GCInfoToken gcInfoToken,
307307
PCONTEXT pCtx)=0;
308308
#else // FEATURE_EH_FUNCLETS
309309
virtual DWORD_PTR CallFunclet(OBJECTREF throwable, void* pHandler, REGDISPLAY *pRD, ExInfo *pExInfo, bool isFilter) = 0;
310+
virtual void ResumeAfterCatch(CONTEXT *pContext, size_t targetSSP, bool fIntercepted) = 0;
311+
#if defined(HOST_AMD64) && defined(HOST_WINDOWS)
312+
virtual void UpdateSSP(PREGDISPLAY pRD) = 0;
313+
#endif // HOST_AMD64 && HOST_WINDOWS
310314
#endif // FEATURE_EH_FUNCLETS
311315

312316
#ifdef FEATURE_REMAP_FUNCTION
@@ -553,6 +557,11 @@ virtual void LeaveCatch(GCInfoToken gcInfoToken,
553557
PCONTEXT pCtx);
554558
#else // FEATURE_EH_FUNCLETS
555559
virtual DWORD_PTR CallFunclet(OBJECTREF throwable, void* pHandler, REGDISPLAY *pRD, ExInfo *pExInfo, bool isFilter);
560+
virtual void ResumeAfterCatch(CONTEXT *pContext, size_t targetSSP, bool fIntercepted);
561+
562+
#if defined(HOST_AMD64) && defined(HOST_WINDOWS)
563+
virtual void UpdateSSP(PREGDISPLAY pRD);
564+
#endif // HOST_AMD64 && HOST_WINDOWS
556565
#endif // FEATURE_EH_FUNCLETS
557566

558567
#ifdef FEATURE_REMAP_FUNCTION
@@ -762,6 +771,10 @@ virtual void LeaveCatch(GCInfoToken gcInfoToken,
762771
}
763772
#else // FEATURE_EH_FUNCLETS
764773
virtual DWORD_PTR CallFunclet(OBJECTREF throwable, void* pHandler, REGDISPLAY *pRD, ExInfo *pExInfo, bool isFilter);
774+
virtual void ResumeAfterCatch(CONTEXT *pContext, size_t targetSSP, bool fIntercepted);
775+
#if defined(HOST_AMD64) && defined(HOST_WINDOWS)
776+
virtual void UpdateSSP(PREGDISPLAY pRD);
777+
#endif // HOST_AMD64 && HOST_WINDOWS
765778
#endif // FEATURE_EH_FUNCLETS
766779

767780
#ifdef FEATURE_REMAP_FUNCTION

src/coreclr/interpreter/compiler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3263,6 +3263,12 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
32633263
}
32643264
break;
32653265

3266+
case CEE_THROW:
3267+
AddIns(INTOP_THROW);
3268+
m_pLastNewIns->SetSVar(m_pStackPointer[-1].var);
3269+
m_ip += 1;
3270+
break;
3271+
32663272
default:
32673273
assert(0);
32683274
break;

src/coreclr/interpreter/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class InterpCompiler
272272
CORINFO_METHOD_INFO* m_methodInfo;
273273
#ifdef DEBUG
274274
const char *m_methodName;
275-
bool m_verbose;
275+
bool m_verbose = false;
276276
#endif
277277

278278
static int32_t InterpGetMovForType(InterpType interpType, bool signExtend);

src/coreclr/interpreter/intops.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ OPDEF(INTOP_CALL_HELPER_PP, "call.helper.pp", 5, 1, 0, InterpOpThreeInts)
261261
OPDEF(INTOP_ZEROBLK_IMM, "zeroblk.imm", 3, 0, 1, InterpOpInt)
262262
OPDEF(INTOP_LOCALLOC, "localloc", 3, 1, 1, InterpOpNoArgs)
263263
OPDEF(INTOP_BREAKPOINT, "breakpoint", 1, 0, 0, InterpOpNoArgs)
264+
265+
OPDEF(INTOP_THROW, "throw", 4, 0, 1, InterpOpInt)
266+
264267
OPDEF(INTOP_FAILFAST, "failfast", 1, 0, 0, InterpOpNoArgs)
265268
OPDEF(INTOP_GC_COLLECT, "gc.collect", 1, 0, 0, InterpOpNoArgs)
266269

src/coreclr/vm/amd64/cgencpu.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,46 @@ inline TADDR GetFP(const CONTEXT * context)
450450
return (TADDR)(context->Rbp);
451451
}
452452

453+
inline void SetFirstArgReg(CONTEXT *context, TADDR value)
454+
{
455+
LIMITED_METHOD_DAC_CONTRACT;
456+
#ifdef UNIX_AMD64_ABI
457+
context->Rdi = (DWORD64)value;
458+
#else
459+
context->Rcx = (DWORD64)value;
460+
#endif
461+
}
462+
463+
inline TADDR GetFirstArgReg(CONTEXT *context)
464+
{
465+
LIMITED_METHOD_DAC_CONTRACT;
466+
#ifdef UNIX_AMD64_ABI
467+
return (TADDR)(context->Rdi);
468+
#else
469+
return (TADDR)(context->Rcx);
470+
#endif
471+
}
472+
473+
inline void SetSecondArgReg(CONTEXT *context, TADDR value)
474+
{
475+
LIMITED_METHOD_DAC_CONTRACT;
476+
#ifdef UNIX_AMD64_ABI
477+
context->Rsi = (DWORD64)value;
478+
#else
479+
context->Rdx = (DWORD64)value;
480+
#endif
481+
}
482+
483+
inline TADDR GetSecondArgReg(CONTEXT *context)
484+
{
485+
LIMITED_METHOD_DAC_CONTRACT;
486+
#ifdef UNIX_AMD64_ABI
487+
return (TADDR)(context->Rsi);
488+
#else
489+
return (TADDR)(context->Rdx);
490+
#endif
491+
}
492+
453493
extern "C" TADDR GetCurrentSP();
454494

455495
// Emits:

src/coreclr/vm/arm/cgencpu.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,30 @@ inline TADDR GetFP(const T_CONTEXT * context)
255255
return (TADDR)(context->R11);
256256
}
257257

258+
inline void SetFirstArgReg(T_CONTEXT *context, TADDR value)
259+
{
260+
LIMITED_METHOD_DAC_CONTRACT;
261+
context->R0 = DWORD(value);
262+
}
263+
264+
inline TADDR GetFirstArgReg(T_CONTEXT *context)
265+
{
266+
LIMITED_METHOD_DAC_CONTRACT;
267+
return (TADDR)(context->R0);
268+
}
269+
270+
inline void SetSecondArgReg(T_CONTEXT *context, TADDR value)
271+
{
272+
LIMITED_METHOD_DAC_CONTRACT;
273+
context->R1 = DWORD(value);
274+
}
275+
276+
inline TADDR GetSecondArgReg(T_CONTEXT *context)
277+
{
278+
LIMITED_METHOD_DAC_CONTRACT;
279+
return (TADDR)(context->R1);
280+
}
281+
258282
inline void ClearITState(T_CONTEXT *context) {
259283
LIMITED_METHOD_DAC_CONTRACT;
260284
context->Cpsr = context->Cpsr & 0xf9ff03ff;

src/coreclr/vm/arm64/cgencpu.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,29 @@ inline TADDR GetFP(const T_CONTEXT * context)
279279
return (TADDR)(context->Fp);
280280
}
281281

282+
inline void SetFirstArgReg(T_CONTEXT *context, TADDR value)
283+
{
284+
LIMITED_METHOD_DAC_CONTRACT;
285+
SetReg(context, 0, value);
286+
}
287+
288+
inline TADDR GetFirstArgReg(T_CONTEXT *context)
289+
{
290+
LIMITED_METHOD_DAC_CONTRACT;
291+
return GetReg(context, 0);
292+
}
293+
294+
inline void SetSecondArgReg(T_CONTEXT *context, TADDR value)
295+
{
296+
LIMITED_METHOD_DAC_CONTRACT;
297+
SetReg(context, 1, value);
298+
}
299+
300+
inline TADDR GetSecondArgReg(T_CONTEXT *context)
301+
{
302+
LIMITED_METHOD_DAC_CONTRACT;
303+
return GetReg(context, 1);
304+
}
282305

283306
inline TADDR GetMem(PCODE address, SIZE_T size, bool signExtend)
284307
{

0 commit comments

Comments
 (0)