summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSwaroop Sridhar <swaroops@microsoft.com>2016-08-22 15:06:44 -0700
committerSwaroop Sridhar <swaroops@microsoft.com>2016-09-14 10:16:00 -0700
commit4871121dbb7d1ee3282f9beb950cd73fb4f8a95b (patch)
treee45e0025e4c54366cedd61d402fd9b62ef324c6a
parent21e4eb9cd224c6fa257c810d270e3ff45b12a63e (diff)
downloadcoreclr-4871121dbb7d1ee3282f9beb950cd73fb4f8a95b.tar.gz
coreclr-4871121dbb7d1ee3282f9beb950cd73fb4f8a95b.tar.bz2
coreclr-4871121dbb7d1ee3282f9beb950cd73fb4f8a95b.zip
Implement GcInfo v2 for X86
This commit includes the following changes: 1) Thread GcInfo version through X86 specific APIs 2) Add ReturnKind and ReversePinvokeOffset fields to InfoHdr structure GcInfo v1 and v2 use the same InfoHdr structures, because: InfoHdrSmall: ReturnKind is encoded within previously unused bits. InfoHdr: revPInvokeOffset will never be written to the image, since ReversePinvokeOffset==INVALID_REV_PINVOKE_OFFSET for V1. 3) Update the Pre-computed header table to include bits for the above [The default setting of ReturnKind=RT_Scalar is used for all entries in the table. Optimizing this table based in most frequent usage scenarios is to be done separately] 4) Change the GC encoder/decoder to handle the above two fields 5) Use the ReturnKind in the GCInfo from thread-suspension code. GcInfo version is changed for CoreCLR X86 only, not for Desktop JIT Fixes #4379
-rw-r--r--src/debug/daccess/nidump.cpp8
-rw-r--r--src/gcdump/gcdumpnonx86.cpp2
-rw-r--r--src/gcdump/i386/gcdumpx86.cpp24
-rw-r--r--src/inc/eetwain.h54
-rw-r--r--src/inc/gcdecoder.cpp373
-rw-r--r--src/inc/gcdump.h12
-rw-r--r--src/inc/gcinfo.h19
-rw-r--r--src/inc/gcinfotypes.h53
-rw-r--r--src/jit/gcencode.cpp250
-rw-r--r--src/jit/jitgcinfo.h3
-rw-r--r--src/vm/codeman.h2
-rw-r--r--src/vm/debughelp.cpp8
-rw-r--r--src/vm/eedbginterfaceimpl.cpp4
-rw-r--r--src/vm/eetwain.cpp209
-rw-r--r--src/vm/excep.cpp18
-rw-r--r--src/vm/gccover.cpp6
-rw-r--r--src/vm/gcenv.ee.cpp2
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp5
-rw-r--r--src/vm/stackwalk.cpp4
-rw-r--r--src/vm/threadsuspend.cpp12
20 files changed, 633 insertions, 435 deletions
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 32eab498d3..5c6c4e49cb 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -3120,7 +3120,7 @@ void NativeImageDumper::DumpCompleteMethod(PTR_Module module, MethodIterator& mi
#ifdef _TARGET_X86_
InfoHdr hdr;
stringOutFn( "method info Block:\n" );
- curGCInfoPtr += gcDump.DumpInfoHdr(PTR_CBYTE(gcInfoToken.Info), &hdr, &methodSize, 0);
+ curGCInfoPtr += gcDump.DumpInfoHdr(curGCInfoPtr, &hdr, &methodSize, 0);
stringOutFn( "\n" );
#endif
@@ -9439,10 +9439,12 @@ void NativeImageDumper::DumpReadyToRunMethod(PCODE pEntryPoint, PTR_RUNTIME_FUNC
g_holdStringOutData.Clear();
GCDump gcDump(GCINFO_VERSION);
gcDump.gcPrintf = stringOutFn;
-#if !defined(_TARGET_X86_) && defined(USE_GC_INFO_DECODER)
UINT32 r2rversion = m_pReadyToRunHeader->MajorVersion;
UINT32 gcInfoVersion = GCInfoToken::ReadyToRunVersionToGcInfoVersion(r2rversion);
- GcInfoDecoder gcInfoDecoder({ curGCInfoPtr, gcInfoVersion }, DECODE_CODE_LENGTH);
+ GCInfoToken gcInfoToken = { curGCInfoPtr, gcInfoVersion };
+
+#if !defined(_TARGET_X86_) && defined(USE_GC_INFO_DECODER)
+ GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_CODE_LENGTH);
methodSize = gcInfoDecoder.GetCodeLength();
#endif
diff --git a/src/gcdump/gcdumpnonx86.cpp b/src/gcdump/gcdumpnonx86.cpp
index 7343ac9771..c2f41c933a 100644
--- a/src/gcdump/gcdumpnonx86.cpp
+++ b/src/gcdump/gcdumpnonx86.cpp
@@ -505,7 +505,7 @@ size_t GCDump::DumpGCTable(PTR_CBYTE gcInfoBlock,
/*****************************************************************************/
-void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
+void GCDump::DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
diff --git a/src/gcdump/i386/gcdumpx86.cpp b/src/gcdump/i386/gcdumpx86.cpp
index 70334dee65..0c903970e1 100644
--- a/src/gcdump/i386/gcdumpx86.cpp
+++ b/src/gcdump/i386/gcdumpx86.cpp
@@ -60,12 +60,13 @@ const char * CalleeSavedRegName(unsigned reg)
/*****************************************************************************/
-unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
+unsigned GCDump::DumpInfoHdr (PTR_CBYTE gcInfoBlock,
InfoHdr* header,
unsigned * methodSize,
bool verifyGCTables)
{
unsigned count;
+ PTR_CBYTE table = gcInfoBlock;
PTR_CBYTE tableStart = table;
PTR_CBYTE bp = table;
@@ -76,7 +77,7 @@ unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
table += decodeUnsigned(table, methodSize);
- table = decodeHeader(table, header);
+ table = decodeHeader(table, gcInfoVersion, header);
BOOL hasArgTabOffset = FALSE;
if (header->untrackedCnt == HAS_UNTRACKED)
@@ -107,6 +108,12 @@ unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
header->syncEndOffset = count;
}
+ if (header->revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ table += decodeUnsigned(table, &count);
+ header->revPInvokeOffset = count;
+ }
+
//
// First print out all the basic information
//
@@ -931,12 +938,12 @@ DONE_REGTAB:
/*****************************************************************************/
-void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
+void GCDump::DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
{
- PTR_CBYTE table = infoBlock;
+ PTR_CBYTE table = gcInfoBlock;
size_t methodSize;
size_t stackSize;
@@ -963,7 +970,7 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
// Typically only uses one-byte to store everything.
//
InfoHdr header;
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoVersion, &header);
if (header.untrackedCnt == HAS_UNTRACKED)
{
@@ -994,6 +1001,13 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
header.syncEndOffset = offset;
_ASSERTE(offset != INVALID_SYNC_OFFSET);
}
+ if (header.revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ unsigned offset;
+ table += decodeUnsigned(table, &offset);
+ header.revPInvokeOffset = offset;
+ _ASSERTE(offset != INVALID_REV_PINVOKE_OFFSET);
+ }
prologSize = header.prologSize;
epilogSize = header.epilogSize;
diff --git a/src/inc/eetwain.h b/src/inc/eetwain.h
index 6e183c5546..502d181962 100644
--- a/src/inc/eetwain.h
+++ b/src/inc/eetwain.h
@@ -278,16 +278,16 @@ virtual void * GetGSCookieAddr(PREGDISPLAY pContext,
Returns true if the given IP is in the given method's prolog or an epilog.
*/
virtual bool IsInPrologOrEpilog(DWORD relPCOffset,
- PTR_VOID methodInfoPtr,
+ GCInfoToken gcInfoToken,
size_t* prologSize) = 0;
/*
Returns true if the given IP is in the synchronized region of the method (valid for synchronized methods only)
*/
virtual bool IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags) = 0;
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags) = 0;
/*
Returns the size of a given function as reported in the GC info (does
@@ -297,9 +297,15 @@ virtual bool IsInSynchronizedRegion(
virtual size_t GetFunctionSize(GCInfoToken gcInfoToken) = 0;
/*
+Returns the ReturnKind of a given function as reported in the GC info.
+*/
+
+virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken) = 0;
+
+/*
Returns the size of the frame (barring localloc)
*/
-virtual unsigned int GetFrameSize(PTR_VOID methodInfoPtr) = 0;
+virtual unsigned int GetFrameSize(GCInfoToken gcInfoToken) = 0;
#ifndef DACCESS_COMPILE
@@ -307,16 +313,16 @@ virtual unsigned int GetFrameSize(PTR_VOID methodInfoPtr) = 0;
virtual const BYTE* GetFinallyReturnAddr(PREGDISPLAY pReg)=0;
-virtual BOOL IsInFilter(void *methodInfoPtr,
+virtual BOOL IsInFilter(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx,
DWORD curNestLevel) = 0;
-virtual BOOL LeaveFinally(void *methodInfoPtr,
+virtual BOOL LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx) = 0;
-virtual void LeaveCatch(void *methodInfoPtr,
+virtual void LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)=0;
@@ -535,18 +541,18 @@ void * GetGSCookieAddr(PREGDISPLAY pContext,
*/
virtual
bool IsInPrologOrEpilog(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- size_t* prologSize);
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ size_t* prologSize);
/*
Returns true if the given IP is in the synchronized region of the method (valid for synchronized functions only)
*/
virtual
bool IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags);
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags);
/*
Returns the size of a given function.
@@ -555,23 +561,27 @@ virtual
size_t GetFunctionSize(GCInfoToken gcInfoToken);
/*
+Returns the ReturnKind of a given function.
+*/
+virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken);
+
+/*
Returns the size of the frame (barring localloc)
*/
virtual
-unsigned int GetFrameSize(
- PTR_VOID methodInfoPtr);
+unsigned int GetFrameSize(GCInfoToken gcInfoToken);
#ifndef DACCESS_COMPILE
virtual const BYTE* GetFinallyReturnAddr(PREGDISPLAY pReg);
-virtual BOOL LeaveFinally(void *methodInfoPtr,
+virtual BOOL LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx);
-virtual BOOL IsInFilter(void *methodInfoPtr,
+virtual BOOL IsInFilter(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx,
DWORD curNestLevel);
-virtual void LeaveCatch(void *methodInfoPtr,
+virtual void LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx);
@@ -646,8 +656,9 @@ struct hdrInfo
{
unsigned int methodSize; // native code bytes
unsigned int argSize; // in bytes
- unsigned int stackSize; /* including callee saved registers */
- unsigned int rawStkSize; /* excluding callee saved registers */
+ unsigned int stackSize; // including callee saved registers
+ unsigned int rawStkSize; // excluding callee saved registers
+ ReturnKind returnKind; // The ReturnKind for this method.
unsigned int prologSize;
@@ -689,6 +700,7 @@ struct hdrInfo
unsigned int syncStartOffset; // start/end code offset of the protected region in synchronized methods.
unsigned int syncEndOffset; // INVALID_SYNC_OFFSET if there not synchronized method
unsigned int syncEpilogStart; // The start of the epilog. Synchronized methods are guaranteed to have no more than one epilog.
+ unsigned int revPInvokeOffset; // INVALID_REV_PINVOKE_OFFSET if there is no Reverse PInvoke frame
enum { NOT_IN_PROLOG = -1, NOT_IN_EPILOG = -1 };
diff --git a/src/inc/gcdecoder.cpp b/src/inc/gcdecoder.cpp
index d337faeebc..ae672360aa 100644
--- a/src/inc/gcdecoder.cpp
+++ b/src/inc/gcdecoder.cpp
@@ -86,19 +86,20 @@ size_t FASTCALL decodeSigned(PTR_CBYTE src, int* val)
#pragma optimize("tgy", on)
#endif
-PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
+PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header)
{
LIMITED_METHOD_DAC_CONTRACT;
- BYTE byte = *table++;
- BYTE encoding = byte & 0x7f;
-
+ BYTE nextByte = *table++;
+ BYTE encoding = nextByte & 0x7f;
+ const BYTE maskHaveMoreBytesBit = MORE_BYTES_TO_FOLLOW - 1;
GetInfoHdr(encoding, header);
-
- while (byte & 0x80)
+ while (nextByte & MORE_BYTES_TO_FOLLOW)
{
- byte = *table++;
- encoding = byte & 0x7f;
+ nextByte = *table++;
+ encoding = nextByte & maskHaveMoreBytesBit;
+ // encoding here always corresponds to codes in InfoHdrAdjust set
+
if (encoding < NEXT_FOUR_START)
{
if (encoding < SET_ARGCOUNT)
@@ -126,6 +127,7 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
else if (encoding < FIRST_FLIP)
{
header->untrackedCnt = encoding - SET_UNTRACKED;
+ _ASSERTE(header->untrackedCnt != HAS_UNTRACKED);
}
else switch (encoding)
{
@@ -145,22 +147,22 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
header->ebpSaved ^= 1;
break;
case FLIP_EBP_FRAME:
- header->ebpFrame ^= 1;
+ header->ebpFrame ^= 1;
break;
case FLIP_INTERRUPTIBLE:
- header->interruptible ^= 1;
+ header->interruptible ^= 1;
break;
case FLIP_DOUBLE_ALIGN:
- header->doubleAlign ^= 1;
+ header->doubleAlign ^= 1;
break;
case FLIP_SECURITY:
- header->security ^= 1;
+ header->security ^= 1;
break;
case FLIP_HANDLERS:
- header->handlers ^= 1;
+ header->handlers ^= 1;
break;
case FLIP_LOCALLOC:
- header->localloc ^= 1;
+ header->localloc ^= 1;
break;
case FLIP_EDITnCONTINUE:
header->editNcontinue ^= 1;
@@ -172,10 +174,10 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
header->untrackedCnt = HAS_UNTRACKED;
break;
case FLIP_VARARGS:
- header->varargs ^= 1;
+ header->varargs ^= 1;
break;
case FLIP_PROF_CALLBACKS:
- header->profCallbacks ^= 1;
+ header->profCallbacks ^= 1;
break;
case FLIP_HAS_GENERICS_CONTEXT:
header->genericsContext ^= 1;
@@ -189,6 +191,27 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
case FLIP_SYNC:
header->syncStartOffset ^= HAS_SYNC_OFFSET;
break;
+ case FLIP_REV_PINVOKE_FRAME:
+ _ASSERTE(GCInfoEncodesRevPInvokeFrame(version));
+ header->revPInvokeOffset ^= HAS_REV_PINVOKE_FRAME_OFFSET;
+ break;
+
+ case NEXT_OPCODE:
+ _ASSERTE((nextByte & MORE_BYTES_TO_FOLLOW) && "Must have another code");
+ nextByte = *table++;
+ encoding = nextByte & maskHaveMoreBytesBit;
+ // encoding here always corresponds to codes in InfoHdrAdjust2 set
+
+ if (encoding < SET_RET_KIND_MAX)
+ {
+ _ASSERTE(GCInfoEncodesReturnKind(version));
+ header->returnKind = (ReturnKind)encoding;
+ }
+ else
+ {
+ assert(!"Unexpected encoding");
+ }
+ break;
}
}
else
@@ -202,14 +225,14 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
case 5:
assert(NEXT_FOUR_FRAMESIZE == 0x50);
lowBits = encoding & 0xf;
- header->frameSize <<= 4;
- header->frameSize += lowBits;
+ header->frameSize <<= 4;
+ header->frameSize += lowBits;
break;
case 6:
assert(NEXT_FOUR_ARGCOUNT == 0x60);
lowBits = encoding & 0xf;
- header->argCount <<= 4;
- header->argCount += lowBits;
+ header->argCount <<= 4;
+ header->argCount += lowBits;
break;
case 7:
if ((encoding & 0x8) == 0)
@@ -217,14 +240,14 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
assert(NEXT_THREE_PROLOGSIZE == 0x70);
lowBits = encoding & 0x7;
header->prologSize <<= 3;
- header->prologSize += lowBits;
+ header->prologSize += lowBits;
}
else
{
assert(NEXT_THREE_EPILOGSIZE == 0x78);
lowBits = encoding & 0x7;
header->epilogSize <<= 3;
- header->epilogSize += lowBits;
+ header->epilogSize += lowBits;
}
break;
}
@@ -293,154 +316,155 @@ const InfoHdrSmall infoHdrShortcut[128] = {
// | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | genericsContext
// | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | genericsContextIsMethodDesc
-// | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | Arg count
-// | | | | | | | | | | | | | | | | | | | | Counted occurances
-// | | | | | | | | | | | | | | | | | | | | Frame size |
-// | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | untrackedCnt | Header encoding
-// | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | varPtrTable | |
-// | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | gsCookieOffs | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | syncOffs | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// v v v v v v v v v v v v v v v v v v v v v v v v v v v v
- { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1139 00
- { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 128738 01
- { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3696 02
- { 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 402 03
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 4259 04
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 3379 05
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 2058 06
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 728 07
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 984 08
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 }, // 606 09
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0 }, // 1110 0a
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0 }, // 414 0b
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1553 0c
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 584 0d
- { 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 2182 0e
- { 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3445 0f
- { 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1369 10
- { 1, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 515 11
- { 1, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 21127 12
- { 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3517 13
- { 1, 2, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 750 14
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1876 15
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1665 16
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 729 17
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 484 18
- { 1, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 331 19
- { 2, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 1a
- { 2, 3, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 964 1b
- { 2, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3713 1c
- { 2, 3, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 466 1d
- { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1325 1e
- { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 712 1f
- { 2, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 588 20
- { 2, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 20542 21
- { 2, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3802 22
- { 2, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 798 23
- { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1900 24
- { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 385 25
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1617 26
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1743 27
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 909 28
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 602 29
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 352 2a
- { 2, 6, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 657 2b
- { 2, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1283 2c
- { 2, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1286 2d
- { 3, 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1495 2e
- { 3, 4, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1989 2f
- { 3, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1154 30
- { 3, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 9300 31
- { 3, 4, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 392 32
- { 3, 4, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1720 33
- { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1246 34
- { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 800 35
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1179 36
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1368 37
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 349 38
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 505 39
- { 3, 6, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 629 3a
- { 3, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, YES }, // 365 3b
- { 4, 5, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 487 3c
- { 4, 5, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1752 3d
- { 4, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1959 3e
- { 4, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2436 3f
- { 4, 5, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 861 40
- { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1459 41
- { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 950 42
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1491 43
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 879 44
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 408 45
- { 5, 4, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4870 46
- { 5, 6, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 359 47
- { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 915 48
- { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 412 49
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1288 4a
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1591 4b
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 361 4c
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0 }, // 623 4d
- { 5, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // 1239 4e
- { 6, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 457 4f
- { 6, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 606 50
- { 6, 4, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1073 51
- { 6, 4, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 508 52
- { 6, 6, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 330 53
- { 6, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1709 54
- { 6, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1164 55
- { 7, 4, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 556 56
- { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 529 57
- { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 1423 58
- { 7, 8, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 2455 59
- { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 956 5a
- { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1399 5b
- { 7, 8, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 587 5c
- { 7, 10, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 743 5d
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // 1004 5e
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, YES }, // 487 5f
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }, // 337 60
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, YES }, // 361 61
- { 8, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 560 62
- { 8, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1377 63
- { 9, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 877 64
- { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 3041 65
- { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 349 66
- { 10, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 2061 67
- { 10, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 577 68
- { 11, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 1195 69
- { 12, 5, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 491 6a
- { 13, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, YES }, // 627 6b
- { 13, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0 }, // 1099 6c
- { 13, 10, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 488 6d
- { 14, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 574 6e
- { 16, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 1281 6f
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1881 70
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 339 71
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, // 2594 72
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 339 73
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 2107 74
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 2372 75
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, YES }, // 1078 76
- { 16, 7, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 384 77
- { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 1, YES }, // 1541 78
- { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 4, 1, YES }, // 975 79
- { 19, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 546 7a
- { 24, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 675 7b
- { 45, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 902 7c
- { 51, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, YES }, // 432 7d
- { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 7e
- { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0 }, // 703 7f
+// | | | | | | | | | | | | | | | | | | genericsContextIsMethodDesc
+// | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | returnKind
+// | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | Arg count
+// | | | | | | | | | | | | | | | | | | | | | Counted occurences
+// | | | | | | | | | | | | | | | | | | | | | Frame size |
+// | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | untrackedCnt | Header encoding
+// | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | varPtrTable | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | gsCookieOffs | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | syncOffs | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
+ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1139 00
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 128738 01
+ { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3696 02
+ { 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 402 03
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 4259 04
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 3379 05
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 2058 06
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 728 07
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 984 08
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 }, // 606 09
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0 }, // 1110 0a
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0 }, // 414 0b
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1553 0c
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 584 0d
+ { 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 2182 0e
+ { 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3445 0f
+ { 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1369 10
+ { 1, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 515 11
+ { 1, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 21127 12
+ { 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3517 13
+ { 1, 2, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 750 14
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1876 15
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1665 16
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 729 17
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 484 18
+ { 1, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 331 19
+ { 2, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 1a
+ { 2, 3, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 964 1b
+ { 2, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3713 1c
+ { 2, 3, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 466 1d
+ { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1325 1e
+ { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 712 1f
+ { 2, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 588 20
+ { 2, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 20542 21
+ { 2, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3802 22
+ { 2, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 798 23
+ { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1900 24
+ { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 385 25
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1617 26
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1743 27
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 909 28
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 602 29
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 352 2a
+ { 2, 6, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 657 2b
+ { 2, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1283 2c
+ { 2, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1286 2d
+ { 3, 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1495 2e
+ { 3, 4, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1989 2f
+ { 3, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1154 30
+ { 3, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 9300 31
+ { 3, 4, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 392 32
+ { 3, 4, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1720 33
+ { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1246 34
+ { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 800 35
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1179 36
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1368 37
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 349 38
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 505 39
+ { 3, 6, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 629 3a
+ { 3, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, YES }, // 365 3b
+ { 4, 5, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 487 3c
+ { 4, 5, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1752 3d
+ { 4, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1959 3e
+ { 4, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2436 3f
+ { 4, 5, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 861 40
+ { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1459 41
+ { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 950 42
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1491 43
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 879 44
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 408 45
+ { 5, 4, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4870 46
+ { 5, 6, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 359 47
+ { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 915 48
+ { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 412 49
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1288 4a
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1591 4b
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 361 4c
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0 }, // 623 4d
+ { 5, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // 1239 4e
+ { 6, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 457 4f
+ { 6, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 606 50
+ { 6, 4, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1073 51
+ { 6, 4, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 508 52
+ { 6, 6, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 330 53
+ { 6, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1709 54
+ { 6, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1164 55
+ { 7, 4, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 556 56
+ { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 529 57
+ { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 1423 58
+ { 7, 8, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 2455 59
+ { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 956 5a
+ { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1399 5b
+ { 7, 8, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 587 5c
+ { 7, 10, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 743 5d
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // 1004 5e
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, YES }, // 487 5f
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }, // 337 60
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, YES }, // 361 61
+ { 8, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 560 62
+ { 8, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1377 63
+ { 9, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 877 64
+ { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 3041 65
+ { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 349 66
+ { 10, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 2061 67
+ { 10, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 577 68
+ { 11, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 1195 69
+ { 12, 5, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 491 6a
+ { 13, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, YES }, // 627 6b
+ { 13, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0 }, // 1099 6c
+ { 13, 10, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 488 6d
+ { 14, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 574 6e
+ { 16, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 1281 6f
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1881 70
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 339 71
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, // 2594 72
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 339 73
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 2107 74
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 2372 75
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, YES }, // 1078 76
+ { 16, 7, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 384 77
+ { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 1, YES }, // 1541 78
+ { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 4, 1, YES }, // 975 79
+ { 19, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 546 7a
+ { 24, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 675 7b
+ { 45, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 902 7c
+ { 51, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, YES }, // 432 7d
+ { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 7e
+ { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0 }, // 703 7f
};
-
bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
{
#ifdef _ASSERTE
@@ -448,7 +472,8 @@ bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
_ASSERTE(target.untrackedCnt != HAS_UNTRACKED &&
target.varPtrTableSize != HAS_VARPTR &&
target.gsCookieOffset != HAS_GS_COOKIE_OFFSET &&
- target.syncStartOffset != HAS_SYNC_OFFSET);
+ target.syncStartOffset != HAS_SYNC_OFFSET &&
+ target.revPInvokeOffset != HAS_REV_PINVOKE_FRAME_OFFSET);
#endif
// compare two InfoHdr's up to but not including the untrackCnt field
@@ -470,7 +495,13 @@ bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
if (target.gsCookieOffset != INVALID_GS_COOKIE_OFFSET)
return false;
- return target.syncStartOffset == INVALID_SYNC_OFFSET;
+ if (target.syncStartOffset != INVALID_SYNC_OFFSET)
+ return false;
+
+ if (target.revPInvokeOffset!= INVALID_REV_PINVOKE_OFFSET)
+ return false;
+
+ return true;
}
@@ -503,7 +534,7 @@ const unsigned callCommonDelta[4] = { 6,8,10,12 };
* EDI = 0x1, ESI = 0x2, EBX = 0x4, EBP = 0x8
*
*/
-const unsigned callPatternTable[80] = { // # of occurances
+const unsigned callPatternTable[80] = { // # of occurences
0x0a000200, // 30109
0x0c000200, // 22970
0x0c000201, // 19005
diff --git a/src/inc/gcdump.h b/src/inc/gcdump.h
index cd73940ded..3271ca1d6b 100644
--- a/src/inc/gcdump.h
+++ b/src/inc/gcdump.h
@@ -45,7 +45,7 @@ public:
* Return value : Size in bytes of the header encoding
*/
- unsigned FASTCALL DumpInfoHdr (PTR_CBYTE gcInfoBlock,
+ unsigned FASTCALL DumpInfoHdr (PTR_CBYTE gcInfoBlock,
InfoHdr * header, /* OUT */
unsigned * methodSize, /* OUT */
bool verifyGCTables = false);
@@ -53,7 +53,7 @@ public:
/*-------------------------------------------------------------------------
* Dumps the GC tables to 'stdout'
- * table : The GCInfoToken
+ * gcInfoBlock : Start of the GC info block
* verifyGCTables : If the JIT has been compiled with VERIFY_GC_TABLES
* Return value : Size in bytes of the GC table encodings
*/
@@ -70,10 +70,10 @@ public:
* verifyGCTables : If the JIT has been compiled with VERIFY_GC_TABLES
*/
- void FASTCALL DumpPtrsInFrame(PTR_CBYTE infoBlock,
- PTR_CBYTE codeBlock,
- unsigned offs,
- bool verifyGCTables = false);
+ void FASTCALL DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
+ PTR_CBYTE codeBlock,
+ unsigned offs,
+ bool verifyGCTables = false);
public:
diff --git a/src/inc/gcinfo.h b/src/inc/gcinfo.h
index 8d249a38a6..acfc072fa5 100644
--- a/src/inc/gcinfo.h
+++ b/src/inc/gcinfo.h
@@ -32,8 +32,8 @@ const unsigned this_OFFSET_FLAG = 0x2; // the offset is "this"
// The current GCInfo Version
//-----------------------------------------------------------------------------
-#ifdef _TARGET_X86_
-// X86 GcInfo encoding is yet to be changed.
+#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
+// X86 GcInfo encoding is yet to be changed for Desktop JIT32.
#define GCINFO_VERSION 1
#else
#define GCINFO_VERSION 2
@@ -41,6 +41,17 @@ const unsigned this_OFFSET_FLAG = 0x2; // the offset is "this"
#define MIN_GCINFO_VERSION_WITH_RETURN_KIND 2
#define MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME 2
+
+inline BOOL GCInfoEncodesReturnKind(UINT32 version=GCINFO_VERSION)
+{
+ return version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND;
+}
+
+inline BOOL GCInfoEncodesRevPInvokeFrame(UINT32 version=GCINFO_VERSION)
+{
+ return version >= MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME;
+}
+
//-----------------------------------------------------------------------------
// GCInfoToken: A wrapper that contains the GcInfo data and version number.
//
@@ -62,11 +73,11 @@ struct GCInfoToken
BOOL IsReturnKindAvailable()
{
- return (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND);
+ return GCInfoEncodesReturnKind(Version);
}
BOOL IsReversePInvokeFrameAvailable()
{
- return (Version >= MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME);
+ return GCInfoEncodesRevPInvokeFrame(Version);
}
static UINT32 ReadyToRunVersionToGcInfoVersion(UINT32 readyToRunMajorVersion)
diff --git a/src/inc/gcinfotypes.h b/src/inc/gcinfotypes.h
index cd19759634..1edb5f38d0 100644
--- a/src/inc/gcinfotypes.h
+++ b/src/inc/gcinfotypes.h
@@ -376,12 +376,15 @@ enum infoHdrAdjustConstants {
SET_PROLOGSIZE_MAX = 16,
SET_EPILOGSIZE_MAX = 10, // Change to 6
SET_EPILOGCNT_MAX = 4,
- SET_UNTRACKED_MAX = 3
+ SET_UNTRACKED_MAX = 3,
+ SET_RET_KIND_MAX = 4, // 2 bits for ReturnKind
+ MORE_BYTES_TO_FOLLOW = 0x80 // If the High-bit of a header or adjustment byte
+ // is set, then there are more adjustments to follow.
};
//
-// Enum to define the 128 codes that are used to incrementally adjust the InfoHdr structure
-//
+// Enum to define codes that are used to incrementally adjust the InfoHdr structure.
+// First set of opcodes
enum infoHdrAdjust {
SET_FRAMESIZE = 0, // 0x00
@@ -412,18 +415,25 @@ enum infoHdrAdjust {
FLIP_SYNC, // 0x4B
FLIP_HAS_GENERICS_CONTEXT,// 0x4C
FLIP_GENERICS_CONTEXT_IS_METHODDESC,// 0x4D
+ FLIP_REV_PINVOKE_FRAME, // 0x4E
+ NEXT_OPCODE, // 0x4F -- see next Adjustment enumeration
+ NEXT_FOUR_START = 0x50,
+ NEXT_FOUR_FRAMESIZE = 0x50,
+ NEXT_FOUR_ARGCOUNT = 0x60,
+ NEXT_THREE_PROLOGSIZE = 0x70,
+ NEXT_THREE_EPILOGSIZE = 0x78
+};
- // 0x4E .. 0x4f unused
-
- NEXT_FOUR_START = 0x50,
- NEXT_FOUR_FRAMESIZE = 0x50,
- NEXT_FOUR_ARGCOUNT = 0x60,
- NEXT_THREE_PROLOGSIZE = 0x70,
- NEXT_THREE_EPILOGSIZE = 0x78
+// Second set of opcodes, when first code is 0x4F
+enum infoHdrAdjust2 {
+ SET_RETURNKIND = 0, // 0x00-SET_RET_KIND_MAX Set ReturnKind to value
};
#define HAS_UNTRACKED ((unsigned int) -1)
#define HAS_VARPTR ((unsigned int) -1)
+
+#define INVALID_REV_PINVOKE_OFFSET 0
+#define HAS_REV_PINVOKE_FRAME_OFFSET ((unsigned int) -1)
// 0 is not a valid offset for EBP-frames as all locals are at a negative offset
// For ESP frames, the cookie is above (at a higher address than) the buffers,
// and so cannot be at offset 0.
@@ -463,6 +473,7 @@ struct InfoHdrSmall {
unsigned char profCallbacks : 1; // 4 [0]
unsigned char genericsContext : 1;//4 [1] function reports a generics context parameter is present
unsigned char genericsContextIsMethodDesc : 1;//4[2]
+ unsigned char returnKind : 2; // 4 [4] Available GcInfo v2 onwards, previously undefined
unsigned short argCount; // 5,6 in bytes
unsigned int frameSize; // 7,8,9,10 in bytes
unsigned int untrackedCnt; // 11,12,13,14
@@ -483,8 +494,8 @@ struct InfoHdr : public InfoHdrSmall {
unsigned int gsCookieOffset; // 19,20,21,22
unsigned int syncStartOffset; // 23,24,25,26
unsigned int syncEndOffset; // 27,28,29,30
-
- // 31 bytes total
+ unsigned int revPInvokeOffset; // 31,32,33,34 Available GcInfo v2 onwards, previously undefined
+ // 35 bytes total
// Checks whether "this" is compatible with "target".
// It is not an exact bit match as "this" could have some
@@ -498,7 +509,8 @@ struct InfoHdr : public InfoHdrSmall {
_ASSERTE(target.untrackedCnt != HAS_UNTRACKED &&
target.varPtrTableSize != HAS_VARPTR &&
target.gsCookieOffset != HAS_GS_COOKIE_OFFSET &&
- target.syncStartOffset != HAS_SYNC_OFFSET);
+ target.syncStartOffset != HAS_SYNC_OFFSET &&
+ target.revPInvokeOffset != HAS_REV_PINVOKE_FRAME_OFFSET);
#endif
// compare two InfoHdr's up to but not including the untrackCnt field
@@ -525,6 +537,10 @@ struct InfoHdr : public InfoHdrSmall {
(target.syncStartOffset == INVALID_SYNC_OFFSET))
return false;
+ if ((revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET) !=
+ (target.revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET))
+ return false;
+
return true;
}
};
@@ -551,15 +567,16 @@ inline void GetInfoHdr(int index, InfoHdr * header)
{
*((InfoHdrSmall *)header) = infoHdrShortcut[index];
- header->gsCookieOffset = 0;
- header->syncStartOffset = 0;
- header->syncEndOffset = 0;
+ header->gsCookieOffset = INVALID_GS_COOKIE_OFFSET;
+ header->syncStartOffset = INVALID_SYNC_OFFSET;
+ header->syncEndOffset = INVALID_SYNC_OFFSET;
+ header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
}
-PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header);
+PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header);
BYTE FASTCALL encodeHeaderFirst(const InfoHdr& header, InfoHdr* state, int* more, int *pCached);
-BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state);
+BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE &codeSet);
size_t FASTCALL decodeUnsigned(PTR_CBYTE src, unsigned* value);
size_t FASTCALL decodeUDelta(PTR_CBYTE src, unsigned* value, unsigned lastValue);
diff --git a/src/jit/gcencode.cpp b/src/jit/gcencode.cpp
index f20183b25a..f2627e0fe6 100644
--- a/src/jit/gcencode.cpp
+++ b/src/jit/gcencode.cpp
@@ -23,6 +23,89 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "gcinfotypes.h"
+ReturnKind GCTypeToReturnKind(CorInfoGCType gcType)
+{
+ switch (gcType)
+ {
+ case TYPE_GC_NONE:
+ return RT_Scalar;
+ case TYPE_GC_REF:
+ return RT_Object;
+ case TYPE_GC_BYREF:
+ return RT_ByRef;
+ default:
+ _ASSERTE(!"TYP_GC_OTHER is unexpected");
+ return RT_Illegal;
+ }
+}
+
+ReturnKind GCInfo::getReturnKind()
+{
+ switch (compiler->info.compRetType)
+ {
+ case TYP_REF:
+ case TYP_ARRAY:
+ return RT_Object;
+ case TYP_BYREF:
+ return RT_ByRef;
+ case TYP_STRUCT:
+ {
+ CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
+ var_types retType = compiler->getReturnTypeForStruct(structType);
+
+ switch (retType)
+ {
+ case TYP_ARRAY:
+ _ASSERTE(false && "TYP_ARRAY unexpected from getReturnTypeForStruct()");
+ // fall through
+ case TYP_REF:
+ return RT_Object;
+
+ case TYP_BYREF:
+ return RT_ByRef;
+
+ case TYP_STRUCT:
+ if (compiler->IsHfa(structType))
+ {
+#ifdef _TARGET_X86_
+ _ASSERTE(false && "HFAs not expected for X86");
+#endif // _TARGET_X86_
+
+ return RT_Scalar;
+ }
+ else
+ {
+ // Multi-reg return
+ BYTE gcPtrs[2] = { TYPE_GC_NONE, TYPE_GC_NONE };
+ compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
+
+ ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
+ ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);
+
+ return GetStructReturnKind(first, second);
+ }
+
+#ifdef _TARGET_X86_
+ case TYP_FLOAT:
+ case TYP_DOUBLE:
+ return RT_Float;
+#endif // _TARGET_X86_
+ default:
+ return RT_Scalar;
+ }
+ }
+
+#ifdef _TARGET_X86_
+ case TYP_FLOAT:
+ case TYP_DOUBLE:
+ return RT_Float;
+#endif // _TARGET_X86_
+
+ default:
+ return RT_Scalar;
+ }
+}
+
#ifdef JIT32_GCENCODER
#include "emit.h"
@@ -104,18 +187,21 @@ static void regenLog(unsigned encoding, InfoHdr* header, InfoHdr* state)
fprintf(logFile, "InfoHdr( %2d, %2d, %1d, %1d, %1d,"
" %1d, %1d, %1d, %1d, %1d,"
- " %1d, %1d, %1d, %1d, %1d,"
- " %1d, %2d, %2d, %2d, %2d,"
- " %2d, %2d), \n",
+ " %1d, %1d, %1d, %1d, %1d, %1d,"
+ " %1d, %1d, %1d,"
+ " %1d, %2d, %2d,"
+ " %2d, %2d, %2d, %2d, %2d, %2d), \n",
state->prologSize, state->epilogSize, state->epilogCount, state->epilogAtEnd, state->ediSaved,
state->esiSaved, state->ebxSaved, state->ebpSaved, state->ebpFrame, state->interruptible,
state->doubleAlign, state->security, state->handlers, state->localloc, state->editNcontinue, state->varargs,
- state->profCallbacks, state->argCount, state->frameSize,
+ state->profCallbacks, state->genericsContext, state->genericsContextIsMethodDesc,
+ state->returnKind, state->argCount, state->frameSize,
(state->untrackedCnt <= SET_UNTRACKED_MAX) ? state->untrackedCnt : HAS_UNTRACKED,
(state->varPtrTableSize == 0) ? 0 : HAS_VARPTR,
(state->gsCookieOffset == INVALID_GS_COOKIE_OFFSET) ? 0 : HAS_GS_COOKIE_OFFSET,
(state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET,
- (state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET);
+ (state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET,
+ (state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET) ? 0 : HAS_REV_PINVOKE_FRAME_OFFSET);
fflush(logFile);
@@ -265,9 +351,11 @@ static int bigEncoding4(unsigned cur, unsigned tgt, unsigned max)
return cnt;
}
-BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
+BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE &codeSet)
{
BYTE encoding = 0xff;
+ codeSet = 1; // codeSet is 1 or 2, depending on whether the returned encoding
+ // corresponds to InfoHdrAdjust, or InfoHdrAdjust2 enumerations.
if (state->argCount != header.argCount)
{
@@ -547,6 +635,16 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
goto DO_RETURN;
}
+ if (state->returnKind != header.returnKind)
+ {
+ _ASSERTE(GCInfoEncodesReturnKind());
+ state->returnKind = header.returnKind;
+ codeSet = 2; // Two byte encoding
+ encoding = header.returnKind;
+ _ASSERTE(encoding < SET_RET_KIND_MAX);
+ goto DO_RETURN;
+ }
+
if (state->gsCookieOffset != header.gsCookieOffset)
{
assert(state->gsCookieOffset == INVALID_GS_COOKIE_OFFSET || state->gsCookieOffset == HAS_GS_COOKIE_OFFSET);
@@ -587,10 +685,31 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
}
}
+ if (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)
+ {
+ // header.revPInvokeOffset is non-zero.
+ state->revPInvokeOffset = HAS_REV_PINVOKE_FRAME_OFFSET;
+ encoding = FLIP_REV_PINVOKE_FRAME;
+ goto DO_RETURN;
+ }
+ else if (header.revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET)
+ {
+ state->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
+ encoding = FLIP_REV_PINVOKE_FRAME;
+ goto DO_RETURN;
+ }
+ }
+
DO_RETURN:
- assert(encoding < 0x80);
+ _ASSERTE(encoding < MORE_BYTES_TO_FOLLOW);
if (!state->isHeaderMatch(header))
- encoding |= 0x80;
+ encoding |= MORE_BYTES_TO_FOLLOW;
+
return encoding;
}
@@ -806,6 +925,14 @@ static int measureDistance(const InfoHdr& header, const InfoHdrSmall* p, int clo
return distance;
}
+ if (p->returnKind != header.returnKind)
+ {
+ // Setting the ReturnKind requires two bytes of encoding.
+ distance += 2;
+ if (distance >= closeness)
+ return distance;
+ }
+
if (header.gsCookieOffset != INVALID_GS_COOKIE_OFFSET)
{
distance += 1;
@@ -820,6 +947,13 @@ static int measureDistance(const InfoHdr& header, const InfoHdrSmall* p, int clo
return distance;
}
+ if (header.revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET)
+ {
+ distance += 1;
+ if (distance >= closeness)
+ return distance;
+ }
+
return distance;
}
@@ -1165,6 +1299,12 @@ size_t GCInfo::gcInfoBlockHdrSave(
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 (compiler->getNeedsGSSecurityCookie())
{
assert(compiler->lvaGSSecurityCookie != BAD_VAR_NUM);
@@ -1189,6 +1329,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);
@@ -1224,12 +1365,22 @@ size_t GCInfo::gcInfoBlockHdrSave(
*dest++ = headerEncoding;
BYTE encoding = headerEncoding;
- while (encoding & 0x80)
+ BYTE codeSet = 1;
+ while (encoding & MORE_BYTES_TO_FOLLOW)
{
- encoding = encodeHeaderNext(*header, &state);
+ encoding = encodeHeaderNext(*header, &state, codeSet);
+
#if REGEN_SHORTCUTS
regenLog(headerEncoding, header, &state);
#endif
+ _ASSERTE(codeSet == 1 || codeSet == 2 &&
+ "Encoding must correspond to InfoHdrAdjust or InfoHdrAdjust2");
+ if (codeSet == 2)
+ {
+ *dest++ = NEXT_OPCODE | MORE_BYTES_TO_FOLLOW;
+ ++size;
+ }
+
*dest++ = encoding;
++size;
}
@@ -3277,7 +3428,7 @@ void GCInfo::gcFindPtrsInFrame(const void* infoBlock, const void* codeBlock, uns
GCDump gcDump(GCINFO_VERSION);
gcDump.gcPrintf = gcDump_logf; // use my printf (which logs to VM)
- gcDump.DumpPtrsInFrame((const BYTE*)infoBlock, (const BYTE*)codeBlock, offs, verifyGCTables);
+ gcDump.DumpPtrsInFrame((PTR_CBYTE)infoBlock, (const BYTE*)codeBlock, offs, verifyGCTables);
}
#endif // DUMP_GC_TABLES
@@ -3504,23 +3655,6 @@ public:
#endif // DEBUG
-ReturnKind GCTypeToReturnKind(CorInfoGCType gcType)
-{
-
- switch (gcType)
- {
- case TYPE_GC_NONE:
- return RT_Scalar;
- case TYPE_GC_REF:
- return RT_Object;
- case TYPE_GC_BYREF:
- return RT_ByRef;
- default:
- _ASSERTE(!"TYP_GC_OTHER is unexpected");
- return RT_Illegal;
- }
-}
-
void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSize, unsigned prologSize)
{
#ifdef DEBUG
@@ -3536,65 +3670,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
gcInfoEncoderWithLog->SetCodeLength(methodSize);
- ReturnKind returnKind = RT_Illegal;
-
- switch (compiler->info.compRetType)
- {
- case TYP_REF:
- case TYP_ARRAY:
- returnKind = RT_Object;
- break;
- case TYP_BYREF:
- returnKind = RT_ByRef;
- break;
- case TYP_STRUCT:
- {
- CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
- var_types retType = compiler->getReturnTypeForStruct(structType);
-
- switch (retType)
- {
- case TYP_ARRAY:
- _ASSERTE(false && "TYP_ARRAY unexpected from getReturnTypeForStruct()");
-
- case TYP_REF:
- returnKind = RT_Object;
- break;
-
- case TYP_BYREF:
- returnKind = RT_ByRef;
- break;
-
- case TYP_STRUCT:
- if (compiler->IsHfa(structType))
- {
- returnKind = RT_Scalar;
- }
- else
- {
- // Multi-reg return
- BYTE gcPtrs[2] = { TYPE_GC_NONE, TYPE_GC_NONE };
- compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
-
- ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
- ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);
-
- returnKind = GetStructReturnKind(first, second);
- }
- break;
-
- default:
- returnKind = RT_Scalar;
- break;
- }
- break;
- }
- default:
- returnKind = RT_Scalar;
- }
-
- _ASSERTE(returnKind != RT_Illegal);
- gcInfoEncoderWithLog->SetReturnKind(returnKind);
+ gcInfoEncoderWithLog->SetReturnKind(getReturnKind());
if (compiler->isFramePointerUsed())
{
diff --git a/src/jit/jitgcinfo.h b/src/jit/jitgcinfo.h
index b93ac3376c..3f8d8afe88 100644
--- a/src/jit/jitgcinfo.h
+++ b/src/jit/jitgcinfo.h
@@ -380,6 +380,9 @@ private:
public:
void gcUpdateForRegVarMove(regMaskTP srcMask, regMaskTP dstMask, LclVarDsc* varDsc);
#endif // !LEGACY_BACKEND
+
+private:
+ ReturnKind getReturnKind();
};
inline unsigned char encodeUnsigned(BYTE* dest, unsigned value)
diff --git a/src/vm/codeman.h b/src/vm/codeman.h
index f143dd642c..3b383cf3f4 100644
--- a/src/vm/codeman.h
+++ b/src/vm/codeman.h
@@ -1801,7 +1801,7 @@ public:
ULONG GetFixedStackSize()
{
WRAPPER_NO_CONTRACT;
- return GetCodeManager()->GetFrameSize(GetGCInfo());
+ return GetCodeManager()->GetFrameSize(GetGCInfoToken());
}
#endif // WIN64EXCEPTIONS
diff --git a/src/vm/debughelp.cpp b/src/vm/debughelp.cpp
index df769455aa..9db0ce5197 100644
--- a/src/vm/debughelp.cpp
+++ b/src/vm/debughelp.cpp
@@ -1198,12 +1198,12 @@ void DumpGCInfo(MethodDesc* method)
_ASSERTE(codeInfo.GetRelOffset() == 0);
ICodeManager* codeMan = codeInfo.GetCodeManager();
- GCInfoToken table = codeInfo.GetGCInfoToken();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
- unsigned methodSize = (unsigned)codeMan->GetFunctionSize(table);
+ unsigned methodSize = (unsigned)codeMan->GetFunctionSize(gcInfoToken);
- GCDump gcDump(table.Version);
- PTR_CBYTE gcInfo = PTR_CBYTE(table.Info);
+ GCDump gcDump(gcInfoToken.Version);
+ PTR_CBYTE gcInfo = PTR_CBYTE(gcInfoToken.Info);
gcDump.gcPrintf = printfToDbgOut;
diff --git a/src/vm/eedbginterfaceimpl.cpp b/src/vm/eedbginterfaceimpl.cpp
index 93decc9b0d..ff63d846e7 100644
--- a/src/vm/eedbginterfaceimpl.cpp
+++ b/src/vm/eedbginterfaceimpl.cpp
@@ -501,9 +501,9 @@ BOOL EEDbgInterfaceImpl::IsInPrologOrEpilog(const BYTE *address,
if (codeInfo.IsValid())
{
- LPVOID methodInfo = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
- if (codeInfo.GetCodeManager()->IsInPrologOrEpilog(codeInfo.GetRelOffset(), methodInfo, prologSize))
+ if (codeInfo.GetCodeManager()->IsInPrologOrEpilog(codeInfo.GetRelOffset(), gcInfoToken, prologSize))
{
return TRUE;
}
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 032bda7c96..2ce7b59578 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -142,13 +142,15 @@ __forceinline int decodeSigned(PTR_CBYTE& src)
/*****************************************************************************
*
- * Decodes the methodInfoPtr and returns the decoded information
- * in the hdrInfo struct. The EIP parameter is the PC location
- * within the active method.
+ * Decodes the X86 GcInfo header and returns the decoded information
+ * in the hdrInfo struct.
+ * curOffset is the code offset within the active method used in the
+ * computation of PrologOffs/EpilogOffs.
+ * Returns the size of the header (number of bytes decoded).
*/
-static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
- unsigned curOffset,
- hdrInfo * infoPtr)
+static size_t DecodeGCHdrInfo(GCInfoToken gcInfoToken,
+ unsigned curOffset,
+ hdrInfo * infoPtr)
{
CONTRACTL {
NOTHROW;
@@ -157,7 +159,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
SUPPORTS_DAC;
} CONTRACTL_END;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = (PTR_CBYTE) gcInfoToken.Info;
#if VERIFY_GC_TABLES
_ASSERTE(*castto(table, unsigned short *)++ == 0xFEEF);
#endif
@@ -170,7 +172,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
/* Decode the InfoHdr */
InfoHdr header;
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoToken.Version, &header);
BOOL hasArgTabOffset = FALSE;
if (header.untrackedCnt == HAS_UNTRACKED)
@@ -199,6 +201,10 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
_ASSERTE(header.syncStartOffset < header.syncEndOffset);
}
+ if (header.revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ header.revPInvokeOffset = fastDecodeUnsigned(table);
+ }
/* Some sanity checks on header */
@@ -220,6 +226,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
infoPtr->argSize = header.argCount * 4;
infoPtr->ebpFrame = header.ebpFrame;
infoPtr->interruptible = header.interruptible;
+ infoPtr->returnKind = (ReturnKind) header.returnKind;
infoPtr->prologSize = header.prologSize;
infoPtr->epilogSize = header.epilogSize;
@@ -232,6 +239,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
infoPtr->syncStartOffset = header.syncStartOffset;
infoPtr->syncEndOffset = header.syncEndOffset;
+ infoPtr->revPInvokeOffset = header.revPInvokeOffset;
infoPtr->doubleAlign = header.doubleAlign;
infoPtr->securityCheck = header.security;
@@ -352,7 +360,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
(infoPtr->gsCookieOffset < infoPtr->stackSize) &&
((header.gsCookieOffset % sizeof(void*)) == 0));
- return table - PTR_CBYTE(methodInfoPtr);
+ return table - PTR_CBYTE(gcInfoToken.Info);
}
/*****************************************************************************/
@@ -715,7 +723,7 @@ void EECodeManager::FixContext( ContextType ctxType,
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(pCodeInfo->GetGCInfo(),
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(),
dwRelOffset,
&stateBuf->hdrInfoBody);
pState->dwIsSet = 1;
@@ -836,11 +844,11 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx,
hdrInfo oldInfo, newInfo;
- crackMethodInfoHdr(pOldCodeInfo->GetGCInfo(),
+ DecodeGCHdrInfo(pOldCodeInfo->GetGCInfoToken(),
pOldCodeInfo->GetRelOffset(),
&oldInfo);
- crackMethodInfoHdr(pNewCodeInfo->GetGCInfo(),
+ DecodeGCHdrInfo(pNewCodeInfo->GetGCInfoToken(),
pNewCodeInfo->GetRelOffset(),
&newInfo);
@@ -1545,7 +1553,7 @@ bool EECodeManager::IsGcSafe( EECodeInfo *pCodeInfo,
/* Extract the necessary information from the info block header */
- table = (BYTE *)crackMethodInfoHdr(pCodeInfo->GetGCInfo(),
+ table = (BYTE *)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(),
dwRelOffset,
&info);
@@ -3905,8 +3913,9 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
PTR_CBYTE methodStart = PTR_CBYTE(pCodeInfo->GetSavedMethodCode());
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- DWORD curOffs = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = gcInfoToken.Info;
+ DWORD curOffs = pCodeInfo->GetRelOffset();
_ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf));
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
@@ -3915,7 +3924,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
{
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr,
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken,
curOffs,
&stateBuf->hdrInfoBody);
}
@@ -4097,7 +4106,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
GC_NOTRIGGER;
} CONTRACTL_END;
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
unsigned curOffs = pCodeInfo->GetRelOffset();
unsigned EBP = *pContext->pEbp;
@@ -4108,7 +4117,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
unsigned count;
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
#if 0
printf("EECodeManager::EnumGcRefs - EIP = %08x ESP = %08x offset = %x GC Info is at %08x\n", *pContext->pPC, ESP, curOffs, table);
#endif
@@ -4116,14 +4125,14 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table += crackMethodInfoHdr(methodInfoPtr,
- curOffs,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ curOffs,
+ &info);
_ASSERTE( curOffs <= info.methodSize);
#ifdef _DEBUG
-// if ((methodInfoPtr == (void*)0x37760d0) && (curOffs == 0x264))
+// if ((gcInfoToken.Info == (void*)0x37760d0) && (curOffs == 0x264))
// __asm int 3;
if (trEnumGCRefs) {
@@ -4220,11 +4229,11 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table = PTR_CBYTE(methodInfoPtr);
+ table = PTR_CBYTE(gcInfoToken.Info);
- table += crackMethodInfoHdr(methodInfoPtr,
- curOffs,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ curOffs,
+ &info);
}
}
@@ -5030,9 +5039,9 @@ OBJECTREF* EECodeManager::GetAddrOfSecurityObject(CrawlFrame *pCF)
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO>
- relOffset,
- &stateBuf->hdrInfoBody);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO>
+ relOffset,
+ &stateBuf->hdrInfoBody);
pState->dwIsSet = 1;
if (stateBuf->hdrInfoBody.securityCheck)
@@ -5109,10 +5118,10 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
} CONTRACTL_END;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
hdrInfo info;
unsigned stackDepth;
TADDR taArgBase;
@@ -5120,9 +5129,9 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
// We do not have accurate information in the prolog or the epilog
if (info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5236,14 +5245,15 @@ GenericParamContextType EECodeManager::GetParamContextType(PREGDISPLAY pCont
#ifdef _TARGET_X86_
/* Extract the necessary information from the info block header */
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
if (!info.genericsContext ||
info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5300,15 +5310,16 @@ PTR_VOID EECodeManager::GetParamTypeArg(PREGDISPLAY pContext,
LIMITED_METHOD_DAC_CONTRACT;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
/* Extract the necessary information from the info block header */
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
if (!info.genericsContext ||
info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5424,9 +5435,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
hdrInfo * info = &stateBuf->hdrInfoBody;
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO>
- relOffset,
- info);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO>
+ relOffset,
+ info);
pState->dwIsSet = 1;
@@ -5482,9 +5493,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext,
*
* Returns true if the given IP is in the given method's prolog or epilog.
*/
-bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
- PTR_VOID methodInfoPtr,
- size_t* prologSize)
+bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
+ GCInfoToken gcInfoToken,
+ size_t* prologSize)
{
CONTRACTL {
NOTHROW;
@@ -5494,7 +5505,7 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, relPCoffset, &info);
+ DecodeGCHdrInfo(gcInfoToken, relPCoffset, &info);
if (prologSize)
*prologSize = info.prologSize;
@@ -5511,10 +5522,9 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
*
* Returns true if the given IP is in the synchronized region of the method (valid for synchronized functions only)
*/
-bool EECodeManager::IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags)
+bool EECodeManager::IsInSynchronizedRegion(DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags)
{
CONTRACTL {
NOTHROW;
@@ -5524,7 +5534,7 @@ bool EECodeManager::IsInSynchronizedRegion(
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, relOffset, &info);
+ DecodeGCHdrInfo(gcInfoToken, relOffset, &info);
// We should be called only for synchronized methods
_ASSERTE(info.syncStartOffset != INVALID_SYNC_OFFSET && info.syncEndOffset != INVALID_SYNC_OFFSET);
@@ -5558,9 +5568,8 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken)
#if defined(_TARGET_X86_)
hdrInfo info;
- PTR_VOID methodInfoPtr = gcInfoToken.Info;
- crackMethodInfoHdr(methodInfoPtr, 0, &info);
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
return info.methodSize;
#elif defined(USE_GC_INFO_DECODER)
@@ -5578,15 +5587,47 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken)
PORTABILITY_ASSERT("EECodeManager::GetFunctionSize is not implemented on this platform.");
return 0;
#endif
+}
+/*****************************************************************************
+*
+* Returns the size of a given function.
+*/
+ReturnKind EECodeManager::GetReturnKind(GCInfoToken gcInfoToken)
+{
+ CONTRACTL{
+ NOTHROW;
+ GC_NOTRIGGER;
+ SUPPORTS_DAC;
+ } CONTRACTL_END;
+ if (!gcInfoToken.IsReturnKindAvailable())
+ {
+ return RT_Illegal;
+ }
+
+#if defined(_TARGET_X86_)
+ hdrInfo info;
+
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
+
+ return info.returnKind;
+#elif defined(USE_GC_INFO_DECODER)
+
+ GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND);
+ return gcInfoDecoder.GetReturnKind();
+
+#else // !_TARGET_X86_ && !USE_GC_INFO_DECODER
+ PORTABILITY_ASSERT("EECodeManager::GetReturnKind is not implemented on this platform.");
+ return 0;
+#endif
}
/*****************************************************************************
*
* Returns the size of the frame of the given function.
*/
-unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr)
+unsigned int EECodeManager::GetFrameSize(GCInfoToken gcInfoToken)
{
CONTRACTL {
NOTHROW;
@@ -5596,7 +5637,7 @@ unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr)
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, 0, &info);
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
// currently only used by E&C callers need to know about doubleAlign
// in all likelyhood
@@ -5624,10 +5665,10 @@ const BYTE* EECodeManager::GetFinallyReturnAddr(PREGDISPLAY pReg)
#endif
}
-BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
- unsigned offset,
- PCONTEXT pCtx,
- DWORD curNestLevel)
+BOOL EECodeManager::IsInFilter(GCInfoToken gcInfoToken,
+ unsigned offset,
+ PCONTEXT pCtx,
+ DWORD curNestLevel)
{
CONTRACTL {
NOTHROW;
@@ -5640,9 +5681,9 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr,
- offset,
- &info);
+ DecodeGCHdrInfo(gcInfoToken,
+ offset,
+ &info);
/* make sure that we have an ebp stack frame */
@@ -5668,7 +5709,7 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
}
-BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
+BOOL EECodeManager::LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)
{
@@ -5681,9 +5722,9 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr,
- offset,
- &info);
+ DecodeGCHdrInfo(gcInfoToken,
+ offset,
+ &info);
DWORD nestingLevel;
GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL, NULL, &nestingLevel);
@@ -5707,7 +5748,7 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
#endif
}
-void EECodeManager::LeaveCatch(void *methodInfoPtr,
+void EECodeManager::LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)
{
@@ -5724,7 +5765,7 @@ void EECodeManager::LeaveCatch(void *methodInfoPtr,
bool hasInnerFilter;
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, offset, &info);
+ DecodeGCHdrInfo(gcInfoToken, offset, &info);
GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL,
&baseSP, &nestingLevel, &hasInnerFilter);
// _ASSERTE(frameType == FR_HANDLER);
@@ -5774,17 +5815,17 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,
} CONTRACTL_END;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
_ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf));
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr,
- dwRelOffset,
- &stateBuf->hdrInfoBody);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken,
+ dwRelOffset,
+ &stateBuf->hdrInfoBody);
table += stateBuf->hdrInfoSize;
pState->dwIsSet = 1;
@@ -5868,8 +5909,8 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
} CONTRACTL_END;
#if defined(_TARGET_X86_)
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned dwOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ unsigned dwOffset = pCodeInfo->GetRelOffset();
CodeManState state;
state.dwIsSet = 0;
@@ -5878,7 +5919,7 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
CodeManStateBuf * pStateBuf = reinterpret_cast<CodeManStateBuf *>(state.stateBuf);
hdrInfo * pHdrInfo = &(pStateBuf->hdrInfoBody);
- pStateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr, dwOffset, pHdrInfo);
+ pStateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, dwOffset, pHdrInfo);
// We need to subtract 4 here because ESPIncrOnReturn() includes the stack slot containing the return
// address.
diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp
index d26f2d62d8..4f72702af6 100644
--- a/src/vm/excep.cpp
+++ b/src/vm/excep.cpp
@@ -1679,7 +1679,7 @@ bool FinallyIsUnwinding(EHRangeTreeNode *pNode,
BOOL LeaveCatch(ICodeManager* pEECM,
Thread *pThread,
CONTEXT *pCtx,
- void *methodInfoPtr,
+ GCInfoToken gcInfoToken,
unsigned offset)
{
CONTRACTL
@@ -1703,7 +1703,7 @@ BOOL LeaveCatch(ICodeManager* pEECM,
PopNestedExceptionRecords(esp, pCtx, pThread->GetExceptionListPtr());
// Do JIT-specific work
- pEECM->LeaveCatch(methodInfoPtr, offset, pCtx);
+ pEECM->LeaveCatch(gcInfoToken, offset, pCtx);
SetSP(pCtx, (UINT_PTR)esp);
return TRUE;
@@ -1762,7 +1762,7 @@ HRESULT IsLegalTransition(Thread *pThread,
ICodeManager* pEECM,
PREGDISPLAY pReg,
SLOT addrStart,
- void *methodInfoPtr,
+ GCInfoToken gcInfoToken,
PCONTEXT pCtx)
{
CONTRACTL
@@ -1875,7 +1875,7 @@ HRESULT IsLegalTransition(Thread *pThread,
if (!LeaveCatch(pEECM,
pThread,
pFilterCtx,
- methodInfoPtr,
+ gcInfoToken,
offFrom))
return E_FAIL;
}
@@ -1930,7 +1930,7 @@ HRESULT IsLegalTransition(Thread *pThread,
if (!fCanSetIPOnly)
{
- if (!pEECM->LeaveFinally(methodInfoPtr,
+ if (!pEECM->LeaveFinally(gcInfoToken,
offFrom,
pFilterCtx))
return E_FAIL;
@@ -2041,7 +2041,7 @@ HRESULT SetIPFromSrcToDst(Thread *pThread,
EECodeInfo codeInfo((TADDR)(addrStart));
ICodeManager * pEECM = codeInfo.GetCodeManager();
- LPVOID methodInfoPtr = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
// Do both checks here so compiler doesn't complain about skipping
// initialization b/c of goto.
@@ -2097,7 +2097,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
@@ -2120,7 +2120,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
@@ -2143,7 +2143,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
diff --git a/src/vm/gccover.cpp b/src/vm/gccover.cpp
index 89f271cdd0..24f9435641 100644
--- a/src/vm/gccover.cpp
+++ b/src/vm/gccover.cpp
@@ -80,7 +80,7 @@ void SetupAndSprinkleBreakpoints(
gcCover->methodRegion = methodRegionInfo;
gcCover->codeMan = pCodeInfo->GetCodeManager();
- gcCover->gcInfoToken = pCodeInfo->GetGCInfoToken();
+ gcCover->gcInfoToken = pCodeInfo->GetGCInfoToken();
gcCover->callerThread = 0;
gcCover->doingEpilogChecks = true;
@@ -583,7 +583,7 @@ void GCCoverageInfo::SprinkleBreakpoints(
#ifdef _TARGET_X86_
// we will whack every instruction in the prolog and epilog to make certain
// our unwinding logic works there.
- if (codeMan->IsInPrologOrEpilog((cur - codeStart) + (DWORD)regionOffsetAdj, gcInfoToken.Info, NULL)) {
+ if (codeMan->IsInPrologOrEpilog((cur - codeStart) + (DWORD)regionOffsetAdj, gcInfoToken, NULL)) {
*cur = INTERRUPT_INSTR;
}
#endif
@@ -1527,7 +1527,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
/* are we in a prolog or epilog? If so just test the unwind logic
but don't actually do a GC since the prolog and epilog are not
GC safe points */
- if (gcCover->codeMan->IsInPrologOrEpilog(offset, gcCover->gcInfoToken.Info, NULL))
+ if (gcCover->codeMan->IsInPrologOrEpilog(offset, gcCover->gcInfoToken, NULL))
{
// We are not at a GC safe point so we can't Suspend EE (Suspend EE will yield to GC).
// But we still have to update the GC Stress instruction. We do it directly without suspending
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index 8dc1692643..b294581009 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -125,7 +125,7 @@ inline bool SafeToReportGenericParamContext(CrawlFrame* pCF)
#ifndef USE_GC_INFO_DECODER
ICodeManager * pEECM = pCF->GetCodeManager();
- if (pEECM != NULL && pEECM->IsInPrologOrEpilog(pCF->GetRelOffset(), pCF->GetGCInfo(), NULL))
+ if (pEECM != NULL && pEECM->IsInPrologOrEpilog(pCF->GetRelOffset(), pCF->GetGCInfoToken(), NULL))
{
return false;
}
diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp
index fee883f0ef..20dceed1e4 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -7081,12 +7081,13 @@ Loop:
// GC info will assist us in determining whether this is a non-EBP frame and
// info about pushed arguments.
- PTR_VOID gcInfo = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
+ PTR_VOID gcInfo = gcInfoToken.Info;
InfoHdr header;
unsigned uiMethodSizeDummy;
PTR_CBYTE table = PTR_CBYTE(gcInfo);
table += decodeUnsigned(table, &uiMethodSizeDummy);
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoToken.Version, &header);
// Ok, GCInfo, can we do a simple EBP walk or what?
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index 3b0b4720f7..29b5617414 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -2416,7 +2416,7 @@ StackWalkAction StackFrameIterator::NextRaw(void)
OBJECTREF orUnwind = NULL;
if (m_crawl.GetCodeManager()->IsInSynchronizedRegion(m_crawl.GetRelOffset(),
- m_crawl.GetGCInfo(),
+ m_crawl.GetGCInfoToken(),
m_crawl.GetCodeManagerFlags()))
{
if (pMD->IsStatic())
@@ -3158,7 +3158,7 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
m_crawl.pFunc->IsSynchronized() &&
!m_crawl.pFunc->IsStatic() &&
m_crawl.GetCodeManager()->IsInSynchronizedRegion(m_crawl.GetRelOffset(),
- m_crawl.GetGCInfo(),
+ m_crawl.GetGCInfoToken(),
m_crawl.GetCodeManagerFlags()))
{
BEGIN_GCX_ASSERT_COOP;
diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp
index 0458b7dd57..e5c54368ca 100644
--- a/src/vm/threadsuspend.cpp
+++ b/src/vm/threadsuspend.cpp
@@ -7275,18 +7275,8 @@ ReturnKind GetReturnKindFromMethodTable(Thread *pThread, EECodeInfo *codeInfo)
ReturnKind GetReturnKind(Thread *pThread, EECodeInfo *codeInfo)
{
- ReturnKind returnKind = RT_Illegal;
-
-#ifdef _TARGET_X86_
- // X86 GCInfo updates yet to be implemented.
-#else
GCInfoToken gcInfoToken = codeInfo->GetGCInfoToken();
- if (gcInfoToken.IsReturnKindAvailable())
- {
- GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND);
- returnKind = gcInfoDecoder.GetReturnKind();
- }
-#endif // _TARGET_X86_
+ ReturnKind returnKind = codeInfo->GetCodeManager()->GetReturnKind(gcInfoToken);
if (!IsValidReturnKind(returnKind))
{