Differentiate between `IMPL_LIMITATION` and `NO_WAY` in the JIT by making `IMPL_LIMITATION` return `CORJIT_IMPLLIMITATION` and handle that value such that crossgen2 behavior behaves better in the presence of an `IMPL_LIMITATION`.
Also, change a `NO_WAY` in the X86 JIT to `IMPL_LIMITATION` to better reflect the issue in code.
The effect of these changes is that a test which encounters an `IMPL_LIMITATION` while running crossgen2 in our test suite will not cause the test to fail, but instead will only cause it to fail if the limitation is also present at runtime. This addresses the last issue known to cause the Pri0 X86 Crossgen2 tests to fail.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
-constexpr GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */
- 0xa5eec3a4,
- 0x4176,
- 0x43a7,
- {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49}
+constexpr GUID JITEEVersionIdentifier = { /* 062114d0-bd20-483f-8a3e-c4ee39706ae8 */
+ 0x062114d0,
+ 0xbd20,
+ 0x483f,
+ {0x8a, 0x3e, 0xc4, 0xee, 0x39, 0x70, 0x6a, 0xe8}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
CORJIT_INTERNALERROR = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 3),
CORJIT_SKIPPED = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 4),
CORJIT_RECOVERABLEERROR = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 5),
+ CORJIT_IMPLLIMITATION= MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 6),
};
/*****************************************************************************/
fprintf(fout, "---------------------------------------------------\n");
fprintf(fout, " badCode: %u\n", fatal_badCode);
fprintf(fout, " noWay: %u\n", fatal_noWay);
+ fprintf(fout, " implLimitation: %u\n", fatal_implLimitation);
fprintf(fout, " NOMEM: %u\n", fatal_NOMEM);
fprintf(fout, " noWayAssertBody: %u\n", fatal_noWayAssertBody);
#ifdef DEBUG
result = param.result;
- if (!inlineInfo && (result == CORJIT_INTERNALERROR || result == CORJIT_RECOVERABLEERROR) && !jitFallbackCompile)
+ if (!inlineInfo &&
+ (result == CORJIT_INTERNALERROR || result == CORJIT_RECOVERABLEERROR || result == CORJIT_IMPLLIMITATION) &&
+ !jitFallbackCompile)
{
// If we failed the JIT, reattempt with debuggable code.
jitFallbackCompile = true;
#if MEASURE_FATAL
extern unsigned fatal_badCode;
extern unsigned fatal_noWay;
+extern unsigned fatal_implLimitation;
extern unsigned fatal_NOMEM;
extern unsigned fatal_noWayAssertBody;
#ifdef DEBUG
#if MEASURE_FATAL
unsigned fatal_badCode;
unsigned fatal_noWay;
+unsigned fatal_implLimitation;
unsigned fatal_NOMEM;
unsigned fatal_noWayAssertBody;
#ifdef DEBUG
}
/*****************************************************************************/
+void DECLSPEC_NORETURN implLimitation()
+{
+#if MEASURE_FATAL
+ fatal_implLimitation += 1;
+#endif // MEASURE_FATAL
+
+ fatal(CORJIT_IMPLLIMITATION);
+}
+
+/*****************************************************************************/
void DECLSPEC_NORETURN NOMEM()
{
#if MEASURE_FATAL
extern void DECLSPEC_NORETURN badCode();
extern void DECLSPEC_NORETURN badCode3(const char* msg, const char* msg2, int arg, __in_z const char* file, unsigned line);
extern void DECLSPEC_NORETURN noWay();
+extern void DECLSPEC_NORETURN implLimitation();
extern void DECLSPEC_NORETURN NOMEM();
extern void DECLSPEC_NORETURN fatal(int errCode);
#define NOWAY_MSG(msg) noWayAssertBodyConditional(msg, __FILE__, __LINE__)
+// IMPL_LIMITATION is called when we encounter valid IL that is not
+// supported by our current implementation because of various
+// limitations (that could be removed in the future)
+#define IMPL_LIMITATION(msg) (debugError(msg, __FILE__, __LINE__), implLimitation())
+
#else // !DEBUG
#define NO_WAY(msg) noWay()
#define BADCODE(msg) badCode()
#define BADCODE3(msg, msg2, arg) badCode()
+// IMPL_LIMITATION is called when we encounter valid IL that is not
+// supported by our current implementation because of various
+// limitations (that could be removed in the future)
+#define IMPL_LIMITATION(msg) implLimitation()
+
#ifdef FEATURE_TRACELOGGING
#define NOWAY_ASSERT_BODY_ARGUMENTS __FILE__, __LINE__
#else
#endif // !DEBUG
-// IMPL_LIMITATION is called when we encounter valid IL that is not
-// supported by our current implementation because of various
-// limitations (that could be removed in the future)
-#define IMPL_LIMITATION(msg) NO_WAY(msg)
#if 1 // All platforms currently enable NYI; this should be a tighter condition to exclude some platforms from NYI
but it will be very difficult for fully interruptible code */
if (compArgSize != (size_t)(unsigned short)compArgSize)
- NO_WAY("Too many arguments for the \"ret\" instruction to pop");
+ IMPL_LIMITATION("Too many arguments for the \"ret\" instruction to pop");
#endif
}
{
ThrowHelper.ThrowInvalidProgramException();
}
+ if (result == CorJitResult.CORJIT_IMPLLIMITATION)
+ {
+#if READYTORUN
+ throw new RequiresRuntimeJitException("JIT implementation limitation");
+#else
+ ThrowHelper.ThrowInvalidProgramException();
+#endif
+ }
if (result != CorJitResult.CORJIT_OK)
{
#if SUPPORT_JIT
CORJIT_OUTOFMEM = unchecked((int)0x80000002)/*MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, 2)*/,
CORJIT_INTERNALERROR = unchecked((int)0x80000003)/*MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, 3)*/,
CORJIT_SKIPPED = unchecked((int)0x80000004)/*MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, 4)*/,
- CORJIT_RECOVERABLEERROR = unchecked((int)0x80000005)/*MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, 5)*/
+ CORJIT_RECOVERABLEERROR = unchecked((int)0x80000005)/*MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NULL, 5)*/,
+ CORJIT_IMPLLIMITATION = unchecked((int)0x80000006)/*MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 6)*/,
};
public enum TypeCompareState
uint64_t corJitFlags;
};
-static const GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */
- 0xa5eec3a4,
- 0x4176,
- 0x43a7,
- {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49}
+static const GUID JITEEVersionIdentifier = { /* 062114d0-bd20-483f-8a3e-c4ee39706ae8 */
+ 0x062114d0,
+ 0xbd20,
+ 0x483f,
+ {0x8a, 0x3e, 0xc4, 0xee, 0x39, 0x70, 0x6a, 0xe8}
};
class Jit
break;
case CORJIT_BADCODE:
+ case CORJIT_IMPLLIMITATION:
default:
COMPlusThrow(kInvalidProgramException);
break;