diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2018-02-01 20:50:30 +0300 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2018-02-01 20:50:30 +0300 |
commit | 15a932b833fa3d6199a982088d43cecac2721ea1 (patch) | |
tree | 2566d2d45d12f66b8587b8d151c5e99eb1d51827 /src/Runtime.Base | |
parent | a8911b0ef6a127c04495f79db6c88c8b96a63887 (diff) |
Resolve bug 535897, roll back changeset 1683373 to make exception handling faster on all platforms.
[tfs-changeset: 1687628]
Diffstat (limited to 'src/Runtime.Base')
-rw-r--r-- | src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs | 51 | ||||
-rw-r--r-- | src/Runtime.Base/src/System/Runtime/ThunkPool.cs | 4 |
2 files changed, 34 insertions, 21 deletions
diff --git a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index 8a007c1ba..4d3cdf674 100644 --- a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -9,6 +9,9 @@ using System.Runtime.InteropServices; using Internal.Runtime; +// Disable: Filter expression is a constant. We know. We just can't do an unfiltered catch. +#pragma warning disable 7095 + namespace System.Runtime { public enum RhFailFastReason @@ -166,7 +169,7 @@ namespace System.Runtime // Invoke the classlib fail fast function. CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, IntPtr.Zero, IntPtr.Zero); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -214,7 +217,7 @@ namespace System.Runtime { CalliIntrinsics.CallVoid(pOnFirstChanceFunction, exception); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -246,7 +249,7 @@ namespace System.Runtime { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, exInfo._pExContext->IP, (IntPtr)pContext); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -276,7 +279,7 @@ namespace System.Runtime { CalliIntrinsics.CallVoid(pAppendStackFrame, exception, IP, flags); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -303,7 +306,7 @@ namespace System.Runtime { e = CalliIntrinsics.Call<Exception>(pGetRuntimeExceptionFunction, id); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -339,7 +342,7 @@ namespace System.Runtime { e = CalliIntrinsics.Call<Exception>(pGetRuntimeExceptionFunction, id); } - catch + catch when (true) { // disallow all exceptions leaking out of callbacks } @@ -861,28 +864,38 @@ namespace System.Runtime return false; } +#if DEBUG && !INPLACE_RUNTIME private static EEType* s_pLowLevelObjectType; - - private static bool ShouldTypedClauseCatchThisException(object exception, EEType* pClauseType) + private static void AssertNotRuntimeObject(EEType* pClauseType) { - if (TypeCast.IsInstanceOfClass(exception, pClauseType) != null) - return true; + // + // The C# try { } catch { } clause expands into a typed catch of System.Object. + // Since runtime has its own definition of System.Object, try { } catch { } might not do what + // was intended (catch all exceptions). + // + // This assertion is making sure we don't use try { } catch { } within the runtime. + // The runtime codebase should either use try { } catch (Exception) { } for exception types + // from the runtime or a try { } catch when (true) { } to catch all exceptions. + // if (s_pLowLevelObjectType == null) { - // TODO: Avoid allocating here as that may fail + // Allocating might fail, but since this is just a debug assert, it's probably fine. s_pLowLevelObjectType = new System.Object().EEType; } - // This allows the typical try { } catch { }--which expands to a typed catch of System.Object--to work on - // all objects when the clause is in the low level runtime code. This special case is needed because - // objects from foreign type systems are sometimes throw back up at runtime code and this is the only way - // to catch them outside of having a filter with no type check in it, which isn't currently possible to - // write in C#. See https://github.com/dotnet/roslyn/issues/4388 - if (pClauseType->IsEquivalentTo(s_pLowLevelObjectType)) - return true; + Debug.Assert(!pClauseType->IsEquivalentTo(s_pLowLevelObjectType)); + } +#endif // DEBUG && !INPLACE_RUNTIME - return false; + + private static bool ShouldTypedClauseCatchThisException(object exception, EEType* pClauseType) + { +#if DEBUG && !INPLACE_RUNTIME + AssertNotRuntimeObject(pClauseType); +#endif + + return TypeCast.IsInstanceOfClass(exception, pClauseType) != null; } private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart) diff --git a/src/Runtime.Base/src/System/Runtime/ThunkPool.cs b/src/Runtime.Base/src/System/Runtime/ThunkPool.cs index 404494451..76df73e4d 100644 --- a/src/Runtime.Base/src/System/Runtime/ThunkPool.cs +++ b/src/Runtime.Base/src/System/Runtime/ThunkPool.cs @@ -135,7 +135,7 @@ namespace System.Runtime if (newHeap._nextAvailableThunkPtr != IntPtr.Zero) return newHeap; } - catch { } + catch (Exception) { } return null; } @@ -156,7 +156,7 @@ namespace System.Runtime { newBlockInfo = new AllocatedBlock(); } - catch + catch (Exception) { return false; } |