X86 GcEncode: Support V1 and V2 encodings
authorSwaroop Sridhar <swaroops@microsoft.com>
Fri, 16 Sep 2016 21:32:06 +0000 (14:32 -0700)
committerSwaroop Sridhar <swaroops@microsoft.com>
Mon, 19 Sep 2016 05:30:14 +0000 (22:30 -0700)
The RYU+LegacyBackend Desktop JIT for X86 is still on V1.
So, permit both V1 and V2 encodings in gcencode.cpp.

src/inc/gcdecoder.cpp
src/inc/gcinfotypes.h
src/jit/gcencode.cpp

index ae67236..a2a2e8c 100644 (file)
@@ -92,12 +92,11 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header
 
     BYTE nextByte = *table++;
     BYTE encoding = nextByte & 0x7f;
-    const BYTE maskHaveMoreBytesBit = MORE_BYTES_TO_FOLLOW - 1;
     GetInfoHdr(encoding, header);
     while (nextByte & MORE_BYTES_TO_FOLLOW)
     {
         nextByte = *table++;
-        encoding = nextByte & maskHaveMoreBytesBit;
+        encoding = nextByte & ADJ_ENCODING_MAX;
         // encoding here always corresponds to codes in InfoHdrAdjust set
 
         if (encoding < NEXT_FOUR_START)
@@ -199,7 +198,7 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header
             case NEXT_OPCODE:
                 _ASSERTE((nextByte & MORE_BYTES_TO_FOLLOW) && "Must have another code");
                 nextByte = *table++;
-                encoding = nextByte & maskHaveMoreBytesBit;
+                encoding = nextByte & ADJ_ENCODING_MAX;
                 // encoding here always corresponds to codes in InfoHdrAdjust2 set
 
                 if (encoding < SET_RET_KIND_MAX)
index 1edb5f3..6ed7d50 100644 (file)
@@ -378,6 +378,8 @@ enum infoHdrAdjustConstants {
     SET_EPILOGCNT_MAX = 4,
     SET_UNTRACKED_MAX = 3,
     SET_RET_KIND_MAX = 4,   // 2 bits for ReturnKind
+    ADJ_ENCODING_MAX = 0x7f, // Maximum valid encoding in a byte
+                             // Also used to mask off next bit from each encoding byte.
     MORE_BYTES_TO_FOLLOW = 0x80 // If the High-bit of a header or adjustment byte 
                                // is set, then there are more adjustments to follow.
 };
index f2627e0..d243396 100644 (file)
@@ -635,9 +635,8 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE &code
         goto DO_RETURN;
     }
 
-    if (state->returnKind != header.returnKind)
+    if (GCInfoEncodesReturnKind() && (state->returnKind != header.returnKind))
     {
-        _ASSERTE(GCInfoEncodesReturnKind());
         state->returnKind = header.returnKind;
         codeSet = 2; // Two byte encoding
         encoding = header.returnKind;
@@ -685,9 +684,8 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE &code
         }
     }
 
-    if (state->revPInvokeOffset != header.revPInvokeOffset)
+    if (GCInfoEncodesRevPInvokeFrame() && (state->revPInvokeOffset != header.revPInvokeOffset))
     {
-        _ASSERTE(GCInfoEncodesRevPInvokeFrame());
         assert(state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET || state->revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET);
 
         if (state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET)
@@ -1298,13 +1296,17 @@ size_t GCInfo::gcInfoBlockHdrSave(
     header->genericsContext = compiler->lvaReportParamTypeArg();
     header->genericsContextIsMethodDesc =
         header->genericsContext && (compiler->info.compMethodInfo->options & (CORINFO_GENERICS_CTXT_FROM_METHODDESC));
-    header->gsCookieOffset = INVALID_GS_COOKIE_OFFSET;
 
-    ReturnKind returnKind = getReturnKind();
-    _ASSERTE(IsValidReturnKind(returnKind) && "Return Kind must be valid");
-    _ASSERTE(!IsStructReturnKind(returnKind) && "Struct Return Kinds Unexpected for JIT32");
-    header->returnKind = returnKind;
+    if (GCInfoEncodesReturnKind()) 
+    {
+        ReturnKind returnKind = getReturnKind();
+        _ASSERTE(IsValidReturnKind(returnKind) && "Return Kind must be valid");
+        _ASSERTE(!IsStructReturnKind(returnKind) && "Struct Return Kinds Unexpected for JIT32");
+        _ASSERTE((returnKind < SET_RET_KIND_MAX) && "ReturnKind has no legal encoding");
+        header->returnKind = returnKind;
+    }
 
+    header->gsCookieOffset = INVALID_GS_COOKIE_OFFSET;
     if (compiler->getNeedsGSSecurityCookie())
     {
         assert(compiler->lvaGSSecurityCookie != BAD_VAR_NUM);
@@ -1329,6 +1331,7 @@ size_t GCInfo::gcInfoBlockHdrSave(
         // synchronized methods can't have more than 1 epilog
         assert(header->epilogCount <= 1);
     }
+
     header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
 
     assert((compiler->compArgSize & 0x3) == 0);