Set the CORINFO_EH_CLAUSE_SAMETRY on CORINFO_EH_CLAUSE (#88072)
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 26 Jul 2023 16:48:32 +0000 (18:48 +0200)
committerGitHub <noreply@github.com>
Wed, 26 Jul 2023 16:48:32 +0000 (18:48 +0200)
* Set the CORINFO_EH_CLAUSE_SAMETRY on CORINFO_EH_CLAUSE

This change makes setting the `CORINFO_EH_CLAUSE_SAMETRY` on
`CORINFO_EH_CLAUSE` to happen for coreclr to. It is a prerequisity for the
port of exception handling from nativeaot to coreclr and it is a noop on
coreclr with the old exception handling.

* Fix comments

* Add clr-abi note and r2rdump support for the flag

* Fix markdown LINT error

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

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

* Update the ABI doc

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
docs/design/coreclr/botr/clr-abi.md
src/coreclr/inc/corinfo.h
src/coreclr/jit/codegencommon.cpp
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/EHInfo.cs

index 1846ee0..825ad58 100644 (file)
@@ -585,6 +585,11 @@ The native EH clauses would be listed as follows:
 
 If the handlers were in a different order, then clause 6 might appear before clauses 4 and 5, but never in between.
 
+## Clauses covering the same try region
+
+Several consecutive clauses may cover the same `try` block. A clause covering the same region as the previous one is marked by the `COR_ILEXCEPTION_CLAUSE_SAMETRY` flag. When exception ex1 is thrown while running handler for another exception ex2 and the exception ex2 escapes the ex1's handler frame, this enables the runtime to skip clauses that cover the same `try` block as the clause that handled the ex1.
+This flag is used by the NativeAOT and also a new exception handling mechanism in CoreCLR. The NativeAOT doesn't store that flag in the encoded clause data, but rather injects a dummy clause between the clauses with same `try` block. CoreCLR keeps that flag as part of the runtime representation of the clause data. The current CoreCLR exception handling doesn't use it, but [a new exception handling mechanism](https://github.com/dotnet/runtime/issues/77568) that's being developed is taking advantage of it.
+
 ## GC Interruptibility and EH
 
 The VM assumes that anytime a thread is stopped, it must be at a GC safe point, or the current frame is non-resumable (i.e. a throw that will never be caught in the same frame). Thus effectively all methods with EH must be fully interruptible (or at a minimum all try bodies). Currently the GC info appears to support mixing of partially interruptible and fully-interruptible regions within the same method, but no JIT uses this, so use at your own risk.
index 25634ca..5145e73 100644 (file)
@@ -906,7 +906,7 @@ enum CORINFO_EH_CLAUSE_FLAGS
     CORINFO_EH_CLAUSE_FINALLY   = 0x0002, // This clause is a finally clause
     CORINFO_EH_CLAUSE_FAULT     = 0x0004, // This clause is a fault clause
     CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
-    CORINFO_EH_CLAUSE_SAMETRY   = 0x0010, // This clause covers same try block as the previous one. (Used by NativeAOT ABI.)
+    CORINFO_EH_CLAUSE_SAMETRY   = 0x0010, // This clause covers same try block as the previous one
 };
 
 // This enumeration is passed to InternalThrow
index 596b332..84760ee 100644 (file)
@@ -2317,9 +2317,9 @@ void CodeGen::genReportEH()
 
         CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(HBtab->ebdHandlerType);
 
-        if (isNativeAOT && (XTnum > 0))
+        if (XTnum > 0)
         {
-            // For NativeAOT, CORINFO_EH_CLAUSE_SAMETRY flag means that the current clause covers same
+            // CORINFO_EH_CLAUSE_SAMETRY flag means that the current clause covers same
             // try block as the previous one. The runtime cannot reliably infer this information from
             // native code offsets because of different try blocks can have same offsets. Alternative
             // solution to this problem would be inserting extra nops to ensure that different try
index 841da46..0c8b796 100644 (file)
@@ -26,6 +26,7 @@ namespace ILCompiler.Reflection.ReadyToRun
         COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002,        // This clause is a finally clause
         COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004,          // Fault clause (finally that is called on exception only)
         COR_ILEXCEPTION_CLAUSE_DUPLICATED = 0x0008,     // duplicated clause. This clause was duplicated to a funclet which was pulled out of line
+        COR_ILEXCEPTION_CLAUSE_SAMETRY = 0x0010,        // This clause covers same try block as the previous one
 
         COR_ILEXCEPTION_CLAUSE_KIND_MASK = COR_ILEXCEPTION_CLAUSE_FILTER | COR_ILEXCEPTION_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_FAULT,
     }
@@ -154,6 +155,11 @@ namespace ILCompiler.Reflection.ReadyToRun
             {
                 writer.Write(" DUPLICATED");
             }
+
+            if ((Flags & CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_SAMETRY) != (CorExceptionFlag)0)
+            {
+                writer.Write(" SAMETRY");
+            }
         }
     }