summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-12-02 03:06:55 -0800
committerGitHub <noreply@github.com>2016-12-02 03:06:55 -0800
commitfcc57b23e2f2072e07d69154faab61f7d52e594b (patch)
tree17881c8f5c665cac621534010f546f95665bb723 /src/jit
parentcb4ac230e8d0a55a7a972fa7e433703fc25629f1 (diff)
downloadcoreclr-fcc57b23e2f2072e07d69154faab61f7d52e594b.tar.gz
coreclr-fcc57b23e2f2072e07d69154faab61f7d52e594b.tar.bz2
coreclr-fcc57b23e2f2072e07d69154faab61f7d52e594b.zip
Introduce CORINFO_EH_CLAUSE_SAMETRY flag for CoreRT ABI (#8422)
CORINFO_EH_CLAUSE_SAMEBLOCK flag is returned on mutually protecting EH clauses for CoreRT ABI. It is set on EH clauses that cover same try block as the previous one. The runtime cannot reliably infer this information from native code offsets without full description of duplicate clauses 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.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegencommon.cpp33
-rw-r--r--src/jit/jiteh.cpp12
2 files changed, 33 insertions, 12 deletions
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index f2de5d18b4..7e54fbf4c5 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,23 @@ void CodeGen::genReportEH()
CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(HBtab->ebdHandlerType);
+ if (isCoreRTABI && (XTnum > 0))
+ {
+ // For CoreRT, 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
+ // blocks have different offsets.
+ if (EHblkDsc::ebdIsSameTry(HBtab, HBtab - 1))
+ {
+ // The SAMETRY bit should only be set on catch clauses. This is ensured in IL, where only 'catch' is
+ // allowed to be mutually-protect. E.g., the C# "try {} catch {} catch {} finally {}" actually exists in
+ // IL as "try { try {} catch {} catch {} } finally {}".
+ assert(HBtab->HasCatchHandler());
+ flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | CORINFO_EH_CLAUSE_SAMETRY);
+ }
+ }
+
// Note that we reuse the CORINFO_EH_CLAUSE type, even though the names of
// the fields aren't accurate.
@@ -3634,9 +3653,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,9 +3720,9 @@ 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.TryOffset = hndBeg;
- clause.TryLength = hndBeg;
+ clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(CORINFO_EH_CLAUSE_FINALLY | CORINFO_EH_CLAUSE_DUPLICATE);
+ clause.TryOffset = hndBeg;
+ clause.TryLength = hndBeg;
clause.HandlerOffset = hndBeg;
clause.HandlerLength = hndEnd;
diff --git a/src/jit/jiteh.cpp b/src/jit/jiteh.cpp
index b20c2f8a9a..4b3ceaecf6 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_SAMETRY)
+ {
+ printf(" same try");
+ }
printf("\n");
}