diff options
author | Swaroop Sridhar <swaroops@microsoft.com> | 2016-08-22 15:06:44 -0700 |
---|---|---|
committer | Swaroop Sridhar <swaroops@microsoft.com> | 2016-09-14 10:16:00 -0700 |
commit | 4871121dbb7d1ee3282f9beb950cd73fb4f8a95b (patch) | |
tree | e45e0025e4c54366cedd61d402fd9b62ef324c6a | |
parent | 21e4eb9cd224c6fa257c810d270e3ff45b12a63e (diff) | |
download | coreclr-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.cpp | 8 | ||||
-rw-r--r-- | src/gcdump/gcdumpnonx86.cpp | 2 | ||||
-rw-r--r-- | src/gcdump/i386/gcdumpx86.cpp | 24 | ||||
-rw-r--r-- | src/inc/eetwain.h | 54 | ||||
-rw-r--r-- | src/inc/gcdecoder.cpp | 373 | ||||
-rw-r--r-- | src/inc/gcdump.h | 12 | ||||
-rw-r--r-- | src/inc/gcinfo.h | 19 | ||||
-rw-r--r-- | src/inc/gcinfotypes.h | 53 | ||||
-rw-r--r-- | src/jit/gcencode.cpp | 250 | ||||
-rw-r--r-- | src/jit/jitgcinfo.h | 3 | ||||
-rw-r--r-- | src/vm/codeman.h | 2 | ||||
-rw-r--r-- | src/vm/debughelp.cpp | 8 | ||||
-rw-r--r-- | src/vm/eedbginterfaceimpl.cpp | 4 | ||||
-rw-r--r-- | src/vm/eetwain.cpp | 209 | ||||
-rw-r--r-- | src/vm/excep.cpp | 18 | ||||
-rw-r--r-- | src/vm/gccover.cpp | 6 | ||||
-rw-r--r-- | src/vm/gcenv.ee.cpp | 2 | ||||
-rw-r--r-- | src/vm/proftoeeinterfaceimpl.cpp | 5 | ||||
-rw-r--r-- | src/vm/stackwalk.cpp | 4 | ||||
-rw-r--r-- | src/vm/threadsuspend.cpp | 12 |
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)) { |