diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index cb736cdde589..6e74fd70d24f 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -914,7 +914,9 @@ enum CORINFO_EH_CLAUSE_FLAGS CORINFO_EH_CLAUSE_NONE = 0, CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter 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_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_SAMEBLOCK = 0x0010, // This clause covers same try block as the previous one. (Used by CoreRT ABI.) }; // This enumeration is passed to InternalThrow diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp index f2de5d18b468..eaf2a1ce744e 100644 --- a/src/jit/codegencommon.cpp +++ b/src/jit/codegencommon.cpp @@ -3319,6 +3319,8 @@ void CodeGen::genReportEH() EHblkDsc* HBtab; EHblkDsc* HBtabEnd; + bool isCoreRTABI = compiler->IsTargetAbi(CORINFO_CORERT_ABI); + unsigned EHCount = compiler->compHndBBtabCount; #if FEATURE_EH_FUNCLETS @@ -3328,7 +3330,7 @@ void CodeGen::genReportEH() unsigned enclosingTryIndex; // Duplicate clauses are not used by CoreRT ABI - if (!compiler->IsTargetAbi(CORINFO_CORERT_ABI)) + if (!isCoreRTABI) { for (XTnum = 0; XTnum < compiler->compHndBBtabCount; XTnum++) { @@ -3347,7 +3349,7 @@ void CodeGen::genReportEH() unsigned clonedFinallyCount = 0; // Duplicate clauses are not used by CoreRT ABI - if (!compiler->IsTargetAbi(CORINFO_CORERT_ABI)) + if (!isCoreRTABI) { // We don't keep track of how many cloned finally there are. So, go through and count. // We do a quick pass first through the EH table to see if there are any try/finally @@ -3429,6 +3431,18 @@ void CodeGen::genReportEH() CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(HBtab->ebdHandlerType); + if (isCoreRTABI && (XTnum > 0)) + { + // For CoreRT, CORINFO_EH_CLAUSE_SAMEBLOCK 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 + // blocks have different offsets. + EHblkDsc* HBtabPrev = HBtab - 1; + if ((HBtab->ebdTryBeg == HBtabPrev->ebdTryBeg) && (HBtab->ebdTryLast == HBtabPrev->ebdTryLast)) + flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | CORINFO_EH_CLAUSE_SAMEBLOCK); + } + // Note that we reuse the CORINFO_EH_CLAUSE type, even though the names of // the fields aren't accurate. @@ -3634,9 +3648,7 @@ void CodeGen::genReportEH() CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(encTab->ebdHandlerType); // Tell the VM this is an extra clause caused by moving funclets out of line. - // It seems weird this is from the CorExceptionFlag enum in corhdr.h, - // not the CORINFO_EH_CLAUSE_FLAGS enum in corinfo.h. - flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | COR_ILEXCEPTION_CLAUSE_DUPLICATED); + flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | CORINFO_EH_CLAUSE_DUPLICATE); // Note that the JIT-EE interface reuses the CORINFO_EH_CLAUSE type, even though the names of // the fields aren't really accurate. For example, we set "TryLength" to the offset of the @@ -3703,7 +3715,7 @@ void CodeGen::genReportEH() CORINFO_EH_CLAUSE clause; clause.ClassToken = 0; // unused - clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(CORINFO_EH_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_DUPLICATED); + clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(CORINFO_EH_CLAUSE_FINALLY | CORINFO_EH_CLAUSE_DUPLICATE); clause.TryOffset = hndBeg; clause.TryLength = hndBeg; clause.HandlerOffset = hndBeg; diff --git a/src/jit/jiteh.cpp b/src/jit/jiteh.cpp index b20c2f8a9a6f..cbcbb76bacef 100644 --- a/src/jit/jiteh.cpp +++ b/src/jit/jiteh.cpp @@ -2979,7 +2979,7 @@ void Compiler::dispOutgoingEHClause(unsigned num, const CORINFO_EH_CLAUSE& claus // Note: the flags field is kind of weird. It should be compared for equality // to determine the type of clause, even though it looks like a bitfield. In // Particular, CORINFO_EH_CLAUSE_NONE is zero, so you can "&" to check it. - // You do need to mask off the bits, though, because COR_ILEXCEPTION_CLAUSE_DUPLICATED + // You do need to mask off the bits, though, because CORINFO_EH_CLAUSE_DUPLICATE // is and'ed in. const DWORD CORINFO_EH_CLAUSE_TYPE_MASK = 0x7; switch (clause.Flags & CORINFO_EH_CLAUSE_TYPE_MASK) @@ -3013,15 +3013,19 @@ void Compiler::dispOutgoingEHClause(unsigned num, const CORINFO_EH_CLAUSE& claus } if ((clause.TryOffset == clause.TryLength) && (clause.TryOffset == clause.HandlerOffset) && - ((clause.Flags & (COR_ILEXCEPTION_CLAUSE_DUPLICATED | COR_ILEXCEPTION_CLAUSE_FINALLY)) == - (COR_ILEXCEPTION_CLAUSE_DUPLICATED | COR_ILEXCEPTION_CLAUSE_FINALLY))) + ((clause.Flags & (CORINFO_EH_CLAUSE_DUPLICATE | CORINFO_EH_CLAUSE_FINALLY)) == + (CORINFO_EH_CLAUSE_DUPLICATE | CORINFO_EH_CLAUSE_FINALLY))) { printf(" cloned finally"); } - else if (clause.Flags & COR_ILEXCEPTION_CLAUSE_DUPLICATED) + else if (clause.Flags & CORINFO_EH_CLAUSE_DUPLICATE) { printf(" duplicated"); } + else if (clause.Flags & CORINFO_EH_CLAUSE_SAMEBLOCK) + { + printf(" same block"); + } printf("\n"); }