Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Implement GcInfo v2 for X86
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Swaroop Sridhar committed Sep 7, 2016
1 parent 7ae29e8 commit c2e452b
Show file tree
Hide file tree
Showing 23 changed files with 729 additions and 543 deletions.
2 changes: 1 addition & 1 deletion src/ToolBox/SOS/Strike/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ void X86Machine::DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printf
{
gcDump.gcPrintf = PrintNothing;
}
pTable += gcDump.DumpInfoHdr(pTable, &header, &methodSize, 0);
pTable += gcDump.DumpInfoHdr(gcInfoToken, &header, &methodSize, 0);
if (bPrintHeader)
{
gcPrintf("\n");
Expand Down
10 changes: 6 additions & 4 deletions src/debug/daccess/nidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(gcInfoToken, &hdr, &methodSize, 0);
stringOutFn( "\n" );
#endif

Expand Down Expand Up @@ -9439,18 +9439,20 @@ 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

//dump the data to a string first so we can get the gcinfo size.
#ifdef _TARGET_X86_
InfoHdr hdr;
stringOutFn("method info Block:\n");
curGCInfoPtr += gcDump.DumpInfoHdr(curGCInfoPtr, &hdr, &methodSize, 0);
curGCInfoPtr += gcDump.DumpInfoHdr(gcInfoToken, &hdr, &methodSize, 0);
stringOutFn("\n");
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/gcdump/gcdumpnonx86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ size_t GCDump::DumpGCTable(PTR_CBYTE gcInfoBlock,

/*****************************************************************************/

void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
void GCDump::DumpPtrsInFrame(GCInfoToken gcInfoToken,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
Expand Down
24 changes: 19 additions & 5 deletions src/gcdump/i386/gcdumpx86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ const char * CalleeSavedRegName(unsigned reg)

/*****************************************************************************/

unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
unsigned GCDump::DumpInfoHdr (GCInfoToken gcInfoToken,
InfoHdr* header,
unsigned * methodSize,
bool verifyGCTables)
{
unsigned count;
PTR_CBYTE table = (PTR_CBYTE)gcInfoToken.Info;
PTR_CBYTE tableStart = table;
PTR_CBYTE bp = table;

Expand All @@ -76,7 +77,7 @@ unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,

table += decodeUnsigned(table, methodSize);

table = decodeHeader(table, header);
table = decodeHeader(table, gcInfoToken.Version, header);

BOOL hasArgTabOffset = FALSE;
if (header->untrackedCnt == HAS_UNTRACKED)
Expand Down Expand Up @@ -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
//
Expand Down Expand Up @@ -931,12 +938,12 @@ size_t GCDump::DumpGCTable(PTR_CBYTE table,

/*****************************************************************************/

void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
void GCDump::DumpPtrsInFrame(GCInfoToken gcInfoToken,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
{
PTR_CBYTE table = infoBlock;
PTR_CBYTE table = (PTR_CBYTE)gcInfoToken.Info;

size_t methodSize;
size_t stackSize;
Expand All @@ -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, gcInfoToken.Version, &header);

if (header.untrackedCnt == HAS_UNTRACKED)
{
Expand Down Expand Up @@ -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;
Expand Down
46 changes: 29 additions & 17 deletions src/inc/eetwain.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,15 @@ 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,
GCInfoToken gcInfoToken,
unsigned flags) = 0;

/*
Expand All @@ -296,27 +296,33 @@ 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

/* Debugger API */

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;

Expand Down Expand Up @@ -535,17 +541,17 @@ 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,
GCInfoToken gcInfoToken,
unsigned flags);

/*
Expand All @@ -554,24 +560,28 @@ bool IsInSynchronizedRegion(
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);

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 };

Expand Down
Loading

0 comments on commit c2e452b

Please sign in to comment.