summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2016-05-04 10:13:32 -0700
committerBruce Forstall <brucefo@microsoft.com>2016-05-04 10:13:32 -0700
commit4047cc5464c287cacf981fdc4c2a2996ed4e6e86 (patch)
tree659366913a812be50cec5b750148aad8fe579485
parent09d6a5d6536adc498917728d3224b1ee7f779d65 (diff)
parent8f71b159a1edb4fbb187bcc95c6e20bc9e2ea4d8 (diff)
downloadcoreclr-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.h21
-rw-r--r--src/jit/compiler.h8
-rw-r--r--src/jit/ee_il_dll.cpp44
-rw-r--r--src/jit/error.cpp9
-rw-r--r--src/jit/error.h12
-rw-r--r--src/jit/flowgraph.cpp7
-rw-r--r--src/jit/importer.cpp7
-rw-r--r--src/vm/jitinterface.cpp75
-rw-r--r--src/vm/jitinterface.h2
-rw-r--r--src/zap/zapinfo.cpp5
-rw-r--r--src/zap/zapinfo.h2
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, &param)
+ 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()
+ }, &param);
+ 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, &param)
+ bool success = eeRunWithErrorTrap<Param>([](Param* pParam)
{
DWORD dwRestrictions = 0;
CorInfoInitClassResult initClassResult;
@@ -15741,12 +15741,11 @@ void Compiler::impCheckCanInline(GenTreePtr call,
_exit:
;
- }
- impErrorTrap()
+ }, &param);
+ 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);