Differentiate between IMPL_LIMITATION and NO_WAY (#43070)
authorDavid Wrighton <davidwr@microsoft.com>
Fri, 9 Oct 2020 22:38:49 +0000 (15:38 -0700)
committerGitHub <noreply@github.com>
Fri, 9 Oct 2020 22:38:49 +0000 (15:38 -0700)
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.

src/coreclr/src/inc/corinfo.h
src/coreclr/src/inc/corjit.h
src/coreclr/src/jit/compiler.cpp
src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/error.cpp
src/coreclr/src/jit/error.h
src/coreclr/src/jit/lclvars.cpp
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp
src/coreclr/src/vm/jitinterface.cpp

index 7870683..e1ddd17 100644 (file)
@@ -208,11 +208,11 @@ TODO: Talk about initializing strutures before use
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-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}
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
index 06948e9..609bfc6 100644 (file)
@@ -45,6 +45,7 @@ enum CorJitResult
     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),
 };
 
 /*****************************************************************************/
index 130eb9f..3f0c2f7 100644 (file)
@@ -1689,6 +1689,7 @@ void Compiler::compShutdown()
     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
@@ -6822,7 +6823,9 @@ START:
 
         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;
index 0f0460f..d42dfe2 100644 (file)
@@ -11003,6 +11003,7 @@ extern Histogram     genTreeNsizHist;
 #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
index a77a217..8a52465 100644 (file)
@@ -19,6 +19,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 #if MEASURE_FATAL
 unsigned fatal_badCode;
 unsigned fatal_noWay;
+unsigned fatal_implLimitation;
 unsigned fatal_NOMEM;
 unsigned fatal_noWayAssertBody;
 #ifdef DEBUG
@@ -66,6 +67,16 @@ void DECLSPEC_NORETURN noWay()
 }
 
 /*****************************************************************************/
+void DECLSPEC_NORETURN implLimitation()
+{
+#if MEASURE_FATAL
+    fatal_implLimitation += 1;
+#endif // MEASURE_FATAL
+
+    fatal(CORJIT_IMPLLIMITATION);
+}
+
+/*****************************************************************************/
 void DECLSPEC_NORETURN NOMEM()
 {
 #if MEASURE_FATAL
index 082ac2e..520dba7 100644 (file)
@@ -63,6 +63,7 @@ extern void debugError(const char* msg, const char* file, unsigned line);
 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);
 
@@ -118,12 +119,22 @@ extern void RecordNowayAssertGlobal(const char* filename, unsigned line, const c
 
 #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
@@ -145,10 +156,6 @@ extern void RecordNowayAssertGlobal(const char* filename, unsigned line, const c
 
 #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
 
index f75f7c6..a45ffcb 100644 (file)
@@ -401,7 +401,7 @@ void Compiler::lvaInitArgs(InitVarDscInfo* varDscInfo)
        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
 }
 
index 8997165..bc9a9d3 100644 (file)
@@ -198,6 +198,14 @@ namespace Internal.JitInterface
             {
                 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
index e07c0f7..01add8f 100644 (file)
@@ -1241,7 +1241,8 @@ namespace Internal.JitInterface
         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
index 1a1ef6f..cf21e76 100644 (file)
@@ -26,11 +26,11 @@ private:
     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
index 8731238..5d2a97d 100644 (file)
@@ -12694,6 +12694,7 @@ void ThrowExceptionForJit(HRESULT res)
             break;
 
         case CORJIT_BADCODE:
+        case CORJIT_IMPLLIMITATION:
         default:
             COMPlusThrow(kInvalidProgramException);
             break;