diff options
author | Bruce Forstall <brucefo@microsoft.com> | 2016-05-04 10:13:32 -0700 |
---|---|---|
committer | Bruce Forstall <brucefo@microsoft.com> | 2016-05-04 10:13:32 -0700 |
commit | 4047cc5464c287cacf981fdc4c2a2996ed4e6e86 (patch) | |
tree | 659366913a812be50cec5b750148aad8fe579485 | |
parent | 09d6a5d6536adc498917728d3224b1ee7f779d65 (diff) | |
parent | 8f71b159a1edb4fbb187bcc95c6e20bc9e2ea4d8 (diff) | |
download | coreclr-4047cc5464c287cacf981fdc4c2a2996ed4e6e86.tar.gz coreclr-4047cc5464c287cacf981fdc4c2a2996ed4e6e86.tar.bz2 coreclr-4047cc5464c287cacf981fdc4c2a2996ed4e6e86.zip |
Merge pull request #4760 from dotnet-bot/from-tfs
Merge changes from TFS
-rw-r--r-- | src/inc/corinfo.h | 21 | ||||
-rw-r--r-- | src/jit/compiler.h | 8 | ||||
-rw-r--r-- | src/jit/ee_il_dll.cpp | 44 | ||||
-rw-r--r-- | src/jit/error.cpp | 9 | ||||
-rw-r--r-- | src/jit/error.h | 12 | ||||
-rw-r--r-- | src/jit/flowgraph.cpp | 7 | ||||
-rw-r--r-- | src/jit/importer.cpp | 7 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 75 | ||||
-rw-r--r-- | src/vm/jitinterface.h | 2 | ||||
-rw-r--r-- | src/zap/zapinfo.cpp | 5 | ||||
-rw-r--r-- | src/zap/zapinfo.h | 2 |
11 files changed, 160 insertions, 32 deletions
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index 8978b951a5..0eca760f38 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use #if COR_JIT_EE_VERSION > 460 // Update this one -SELECTANY const GUID JITEEVersionIdentifier = { /* 8c8e61ca-2b88-4bc5-b03f-d390acdc7fc3 */ - 0x8c8e61ca, - 0x2b88, - 0x4bc5, - { 0xb0, 0x3f, 0xd3, 0x90, 0xac, 0xdc, 0x7f, 0xc3 } +SELECTANY const GUID JITEEVersionIdentifier = { /* 57813506-0058-41df-8b1b-e0b68c3a9da3 */ + 0x57813506, + 0x58, + 0x41df, + { 0x8b, 0x1b, 0xe0, 0xb6, 0x8c, 0x3a, 0x9d, 0xa3 } }; #else @@ -2723,6 +2723,17 @@ public: virtual void ThrowExceptionForHelper( const CORINFO_HELPER_DESC * throwHelper) = 0; +#if COR_JIT_EE_VERSION > 460 + // Runs the given function under an error trap. This allows the JIT to make calls + // to interface functions that may throw exceptions without needing to be aware of + // the EH ABI, exception types, etc. Returns true if the given function completed + // successfully and false otherwise. + virtual bool runWithErrorTrap( + void (*function)(void*), // The function to run + void* parameter // The context parameter that will be passed to the function and the handler + ) = 0; +#endif + /***************************************************************************** * ICorStaticInfo contains EE interface methods which return values that are * constant from invocation to invocation. Thus they may be embedded in diff --git a/src/jit/compiler.h b/src/jit/compiler.h index e1c0046575..818408a35d 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -6456,6 +6456,14 @@ public : bool eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken); + template<typename ParamType> + bool eeRunWithErrorTrap(void (*function)(ParamType*), ParamType* param) + { + return eeRunWithErrorTrapImp(reinterpret_cast<void (*)(void*)>(function), reinterpret_cast<void*>(param)); + } + + bool eeRunWithErrorTrapImp(void (*function)(void*), void* param); + // Utility functions #if defined(DEBUG) diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp index 8193b1573b..004642e4a8 100644 --- a/src/jit/ee_il_dll.cpp +++ b/src/jit/ee_il_dll.cpp @@ -1227,6 +1227,45 @@ bool Compiler::eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken) return param.m_success; } +struct TrapParam +{ + ICorJitInfo* m_corInfo; + EXCEPTION_POINTERS m_exceptionPointers; + + void (*m_function)(void*); + void* m_param; + bool m_success; +}; + +static LONG __EEFilter(PEXCEPTION_POINTERS exceptionPointers, void* param) +{ + auto* trapParam = reinterpret_cast<TrapParam*>(param); + trapParam->m_exceptionPointers = *exceptionPointers; + return trapParam->m_corInfo->FilterException(exceptionPointers); +} + +bool Compiler::eeRunWithErrorTrapImp(void (*function)(void*), void* param) +{ + TrapParam trapParam; + trapParam.m_corInfo = info.compCompHnd; + trapParam.m_function = function; + trapParam.m_param = param; + trapParam.m_success = true; + + PAL_TRY(TrapParam*, __trapParam, &trapParam) + { + __trapParam->m_function(__trapParam->m_param); + } + PAL_EXCEPT_FILTER(__EEFilter) + { + trapParam.m_corInfo->HandleException(&trapParam.m_exceptionPointers); + trapParam.m_success = false; + } + PAL_ENDTRY + + return trapParam.m_success; +} + #else // CORJIT_EE_VER <= 460 bool Compiler::eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken) @@ -1234,6 +1273,11 @@ bool Compiler::eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken) return info.compCompHnd->tryResolveToken(resolvedToken); } +bool Compiler::eeRunWithErrorTrapImp(void (*function)(void*), void* param) +{ + return info.compCompHnd->runWithErrorTrap(function, param); +} + #endif // CORJIT_EE_VER > 460 /***************************************************************************** diff --git a/src/jit/error.cpp b/src/jit/error.cpp index 91b4f7a056..a52f9e5836 100644 --- a/src/jit/error.cpp +++ b/src/jit/error.cpp @@ -197,15 +197,6 @@ void notYetImplemented(const char * msg, const char * filename, unsigned line) #endif // #if !defined(_TARGET_X86_) || !defined(LEGACY_BACKEND) /*****************************************************************************/ -LONG __EEfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam) -{ - ErrorTrapParam *pErrorTrapParam = (ErrorTrapParam *)lpvParam; - ICorJitInfo * m_jitInfo = pErrorTrapParam->jitInfo; - pErrorTrapParam->exceptionPointers = *pExceptionPointers; - return m_jitInfo->FilterException(pExceptionPointers); -} - -/*****************************************************************************/ LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam) { DWORD exceptCode = pExceptionPointers->ExceptionRecord->ExceptionCode; diff --git a/src/jit/error.h b/src/jit/error.h index d883fb08c9..fa4ba0d636 100644 --- a/src/jit/error.h +++ b/src/jit/error.h @@ -21,8 +21,7 @@ struct ErrorTrapParam ErrorTrapParam() { jitInfo = NULL; } }; -extern LONG __EEfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam); - // Only catch JIT internal errors (will not catch EE generated Errors) +// Only catch JIT internal errors (will not catch EE generated Errors) extern LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam); #define setErrorTrap(compHnd, ParamType, paramDef, paramRef) \ @@ -37,20 +36,13 @@ extern LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVO { \ ParamType paramDef = __JITpParam->param; - // Catch only JitGeneratedErrors +// Only catch JIT internal errors (will not catch EE generated Errors) #define impJitErrorTrap() \ } \ PAL_EXCEPT_FILTER(__JITfilter) \ { \ int __errc = __JITparam.errc; (void) __errc; - // Catch all errors (including recoverable ones from the EE) -#define impErrorTrap() \ - } \ - PAL_EXCEPT_FILTER(__EEfilter) \ - { \ - __JITparam.jitInfo->HandleException(&__JITparam.exceptionPointers); - #define endErrorTrap() \ } \ PAL_ENDTRY diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index a847091f51..2cfed2e23c 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -21922,7 +21922,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, param.fncHandle = fncHandle; param.inlineCandidateInfo = inlineCandidateInfo; param.inlineInfo = &inlineInfo; - setErrorTrap(info.compCompHnd, Param*, pParam, ¶m) + bool success = eeRunWithErrorTrap<Param>([](Param* pParam) { // Init the local var info of the inlinee pParam->pThis->impInlineInitVars(pParam->inlineInfo); @@ -21988,8 +21988,8 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, } } } - } - impErrorTrap() + }, ¶m); + if (!success) { #ifdef DEBUG if (verbose) @@ -22006,7 +22006,6 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, inlineResult->NoteFatal(InlineObservation::CALLSITE_COMPILATION_ERROR); } } - endErrorTrap(); if (inlineResult->IsFailure()) { diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 7c24aa87e4..707f4fe417 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -15605,7 +15605,7 @@ void Compiler::impCheckCanInline(GenTreePtr call, param.result = inlineResult; param.ppInlineCandidateInfo = ppInlineCandidateInfo; - setErrorTrap(info.compCompHnd, Param *, pParam, ¶m) + bool success = eeRunWithErrorTrap<Param>([](Param* pParam) { DWORD dwRestrictions = 0; CorInfoInitClassResult initClassResult; @@ -15741,12 +15741,11 @@ void Compiler::impCheckCanInline(GenTreePtr call, _exit: ; - } - impErrorTrap() + }, ¶m); + if (!success) { param.result->NoteFatal(InlineObservation::CALLSITE_COMPILATION_ERROR); } - endErrorTrap(); } void Compiler::impInlineRecordArgInfo(InlineInfo * pInlineInfo, diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index ab7940cc47..bad7e3765b 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -10068,6 +10068,81 @@ DWORD CEEInfo::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) } /*********************************************************************/ +#if !defined(PLATFORM_UNIX) + +struct RunWithErrorTrapFilterParam +{ + ICorDynamicInfo* m_corInfo; + void (*m_function)(void*); + void* m_param; + EXCEPTION_POINTERS m_exceptionPointers; +}; + +static LONG RunWithErrorTrapFilter(struct _EXCEPTION_POINTERS* exceptionPointers, void* theParam) +{ + WRAPPER_NO_CONTRACT; + + auto* param = reinterpret_cast<RunWithErrorTrapFilterParam*>(theParam); + param->m_exceptionPointers = *exceptionPointers; + return param->m_corInfo->FilterException(exceptionPointers); +} + +#endif // !defined(PLATFORM_UNIX) + +bool CEEInfo::runWithErrorTrap(void (*function)(void*), void* param) +{ + // No dynamic contract here because SEH is used + STATIC_CONTRACT_THROWS; + STATIC_CONTRACT_GC_TRIGGERS; + STATIC_CONTRACT_SO_INTOLERANT; + STATIC_CONTRACT_MODE_PREEMPTIVE; + + // NOTE: the lack of JIT/EE transition markers in this method is intentional. Any + // transitions into the EE proper should occur either via the call to + // `EEFilterException` (which is appropraitely marked) or via JIT/EE + // interface calls made by `function`. + + bool success = true; + +#if !defined(PLATFORM_UNIX) + + RunWithErrorTrapFilterParam trapParam; + trapParam.m_corInfo = m_pOverride == nullptr ? this : m_pOverride; + trapParam.m_function = function; + trapParam.m_param = param; + + PAL_TRY(RunWithErrorTrapFilterParam*, pTrapParam, &trapParam) + { + pTrapParam->m_function(pTrapParam->m_param); + } + PAL_EXCEPT_FILTER(RunWithErrorTrapFilter) + { + HandleException(&trapParam.m_exceptionPointers); + success = false; + } + PAL_ENDTRY + +#else // !defined(PLATFORM_UNIX) + + // We shouldn't need PAL_TRY on *nix: any exceptions that we are able to catch + // ought to originate from the runtime itself and should be catchable inside of + // EX_TRY/EX_CATCH, including emulated SEH exceptions. + EX_TRY + { + function(param); + } + EX_CATCH + { + success = false; + } + EX_END_CATCH(RethrowTerminalExceptions); + +#endif + + return success; +} + +/*********************************************************************/ IEEMemoryManager* CEEInfo::getMemoryManager() { CONTRACTL { diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h index e31a07d17b..ace9608f0e 100644 --- a/src/vm/jitinterface.h +++ b/src/vm/jitinterface.h @@ -1097,6 +1097,8 @@ public: DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes); + bool runWithErrorTrap(void (*function)(void*), void* param); + private: // Shrinking these buffers drastically reduces the amount of stack space // required for each instance of the interpreter, and thereby reduces SOs. diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index d9c984c93b..2a2760f76a 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -867,6 +867,11 @@ IEEMemoryManager* ZapInfo::getMemoryManager() { return GetEEMemoryManager(); } + +bool ZapInfo::runWithErrorTrap(void (*function)(void*), void* param) +{ + return m_pEEJitInfo->runWithErrorTrap(function, param); +} HRESULT ZapInfo::allocBBProfileBuffer ( ULONG cBlock, diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h index 7fc93820d2..b472d4870b 100644 --- a/src/zap/zapinfo.h +++ b/src/zap/zapinfo.h @@ -317,6 +317,8 @@ public: DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes); + bool runWithErrorTrap(void (*function)(void*), void* param); + // ICorDynamicInfo DWORD getThreadTLSIndex(void **ppIndirection); |