summaryrefslogtreecommitdiff
path: root/src/inc
diff options
context:
space:
mode:
authorSwaroop Sridhar <swaroops@microsoft.com>2016-07-20 16:50:22 -0700
committerSwaroop Sridhar <swaroops@microsoft.com>2016-08-05 14:05:55 -0700
commitd302e64bcb4ea445f6702c529f8a964df20ab494 (patch)
tree6fda2c392acf1d44aa4222ed6d9813533c455a0a /src/inc
parent5b0953d50e9d0c6e388643210476d6a95a55a247 (diff)
downloadcoreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.tar.gz
coreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.tar.bz2
coreclr-d302e64bcb4ea445f6702c529f8a964df20ab494.zip
Implement GcInfo v2
Ref #4379 This change implements GcInfo version 2 for all platforms that use the GcInfo library (all architectures other than X86). Changes are: 1) Defines ReturnKind enumeration for all platforms 2) Change the GcInfo encoder library to encode the ReturnKind and ReversePInvokeFrame slot 3) Change the CM's GcInfo decoder to encode the ReturnKind and ReversePInvokeFrame slot for GCINFO_VERSION 2 4) Some corrections to GCINFO_MEASUREments 5) Changes to RYU Jit to provide the correct information to the encoder 6) Changes to the VM to use the ReturnKind information while hijacking a thread - If ReturnKind is available from GcInfo, new hijack routines are used - Otherwise, fall back to old method (for compatibility) 7) Rework and simplify the thread hijack routines by scanning HijackFrames directly for gcroots 8) Supporting code to implement the above features. Returning Structs in multiple registers Hijacking for StructInRegs is currently only implemented for Unix SystemV ABI Multi-reg struct returns. However, the hijack-workers that use ReturnKind are ready to handle other platforms (ex: ARM/ARM64 Windows) once the corresponding HijackTripThread() assembly routines are defined. The New feature flag: FEATURE_MULTIREG_RETURN is set for platforms where a struct value can be returned in multiple registers [ex: Windows/Unix ARM/ARM64, Unix-AMD64] FEATURE_UNIX_AMD64_STRUCT_PASSING is a specific kind of FEATURE_MULTIREG_RETURN specified by SystemV ABI for AMD64 Compatibility with other JITs - All new GCInfo generated by RYU Jit is in GcInfo version 2 - All Ngen images must be regenerated with the new GcInfo version. - Ready-to-run images with old GcInfo will continue to work. - Jit64/X64 uses the GcInfo library, so it generates GcInfo version 2. However, it doesn't (yet) provide the data to encode the correct ReturnKind Similar is the case for ARM32 code running on JIT32, and any other JITs that may be using GcInfo library but not yet modified to use the new API. So, compatibility is achived using RT_Unset flag. When ReturnKind is RT_Unset, it means that the JIT did not set the ReturnKind in the GCInfo, and therefore the VM cannot rely on it, and must use other mechanisms (similar to GcInfo ver 1) to determine the Return type's GC information. Implement GC root scanning for Hijack-frames This change implements GCScanRoots() method for Hijacke-frames based on the ReturnKind information available from the GcInfo. If the exact ReturnKind is not available in the GcInfo, the thread-suspension logic will compute the ReturnKind based on the method-signature. As a result of this change, several hijack-helpers in the VM are cleaned up. There's only one implementation of HijackWorker() to handle all returnKinds. This change also simplifies the thread-hijack logic by using a single assembly helper OnHijackTripThread() in most cases. The only other helper used is for X86 floating point return values for save/restoring the top of the FP stack. ARM64 Only GcIndfo v2 is reliably supported for ARM64 platform. The changes to thread-hijack mechanism fixes #6494 for ARM64. No measurable change in JIT throughput, performance or native-image size from this change.
Diffstat (limited to 'src/inc')
-rw-r--r--src/inc/gcinfo.h26
-rw-r--r--src/inc/gcinfodecoder.h17
-rw-r--r--src/inc/gcinfoencoder.h28
-rw-r--r--src/inc/gcinfotypes.h218
4 files changed, 279 insertions, 10 deletions
diff --git a/src/inc/gcinfo.h b/src/inc/gcinfo.h
index 500e1b7a02..8d249a38a6 100644
--- a/src/inc/gcinfo.h
+++ b/src/inc/gcinfo.h
@@ -32,8 +32,15 @@ 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.
#define GCINFO_VERSION 1
+#else
+#define GCINFO_VERSION 2
+#endif // _TARGET_X86_
+#define MIN_GCINFO_VERSION_WITH_RETURN_KIND 2
+#define MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME 2
//-----------------------------------------------------------------------------
// GCInfoToken: A wrapper that contains the GcInfo data and version number.
//
@@ -45,14 +52,29 @@ const unsigned this_OFFSET_FLAG = 0x2; // the offset is "this"
// 1) The current GCINFO_VERSION for JITted and Ngened images
// 2) A function of the Ready - to - run major version stored in READYTORUN_HEADER
// for ready - to - run images.ReadyToRunJitManager::JitTokenToGCInfoVersion()
-// provides the GcInfo version for any Method.Currently, there's only one
-// version of GCInfo.
+// provides the GcInfo version for any Method.
//-----------------------------------------------------------------------------
struct GCInfoToken
{
PTR_VOID Info;
UINT32 Version;
+
+ BOOL IsReturnKindAvailable()
+ {
+ return (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND);
+ }
+ BOOL IsReversePInvokeFrameAvailable()
+ {
+ return (Version >= MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME);
+ }
+
+ static UINT32 ReadyToRunVersionToGcInfoVersion(UINT32 readyToRunMajorVersion)
+ {
+ // GcInfo version is 1 up to ReadyTorun version 1.x
+ // GcInfo version is current from ReadyToRun version 2.0
+ return (readyToRunMajorVersion == 1) ? 1 : GCINFO_VERSION;
+ }
};
/*****************************************************************************/
diff --git a/src/inc/gcinfodecoder.h b/src/inc/gcinfodecoder.h
index f703727a76..c77c3598b0 100644
--- a/src/inc/gcinfodecoder.h
+++ b/src/inc/gcinfodecoder.h
@@ -161,6 +161,7 @@ enum ICodeManagerFlags
enum GcInfoDecoderFlags
{
+ DECODE_EVERYTHING = 0x0,
DECODE_SECURITY_OBJECT = 0x01, // stack location of security object
DECODE_CODE_LENGTH = 0x02,
DECODE_VARARG = 0x04,
@@ -174,6 +175,8 @@ enum GcInfoDecoderFlags
DECODE_FOR_RANGES_CALLBACK = 0x200,
DECODE_PROLOG_LENGTH = 0x400, // length of the prolog (used to avoid reporting generics context)
DECODE_EDIT_AND_CONTINUE = 0x800,
+ DECODE_REVERSE_PINVOKE_VAR = 0x1000,
+ DECODE_RETURN_KIND = 0x2000
};
enum GcInfoHeaderFlags
@@ -190,11 +193,12 @@ enum GcInfoHeaderFlags
GC_INFO_HAS_STACK_BASE_REGISTER = 0x40,
GC_INFO_WANTS_REPORT_ONLY_LEAF = 0x80,
GC_INFO_HAS_EDIT_AND_CONTINUE_PRESERVED_SLOTS = 0x100,
+ GC_INFO_REVERSE_PINVOKE_FRAME = 0x200,
- GC_INFO_FLAGS_BIT_SIZE = 9,
+ GC_INFO_FLAGS_BIT_SIZE_VERSION_1 = 9,
+ GC_INFO_FLAGS_BIT_SIZE = 10,
};
-
class BitStreamReader
{
public:
@@ -430,7 +434,7 @@ public:
// If you are not insterested in interruptibility or gc lifetime information, pass 0 as instructionOffset
GcInfoDecoder(
GCInfoToken gcInfoToken,
- GcInfoDecoderFlags flags,
+ GcInfoDecoderFlags flags = DECODE_EVERYTHING,
UINT32 instructionOffset = 0
);
@@ -486,10 +490,12 @@ public:
UINT32 GetPrologSize();
INT32 GetPSPSymStackSlot();
INT32 GetGenericsInstContextStackSlot();
+ INT32 GetReversePInvokeStackSlot();
bool HasMethodDescGenericsInstContext();
bool HasMethodTableGenericsInstContext();
bool GetIsVarArg();
bool WantsReportOnlyLeaf();
+ ReturnKind GetReturnKind();
UINT32 GetCodeLength();
UINT32 GetStackBaseRegister();
UINT32 GetSizeOfEditAndContinuePreservedArea();
@@ -512,6 +518,7 @@ private:
bool m_WantsReportOnlyLeaf;
INT32 m_SecurityObjectStackSlot;
INT32 m_GSCookieStackSlot;
+ INT32 m_ReversePInvokeStackSlot;
UINT32 m_ValidRangeStart;
UINT32 m_ValidRangeEnd;
INT32 m_PSPSymStackSlot;
@@ -519,6 +526,8 @@ private:
UINT32 m_CodeLength;
UINT32 m_StackBaseRegister;
UINT32 m_SizeOfEditAndContinuePreservedArea;
+ INT32 m_ReversePInvokeFrameSlot;
+ ReturnKind m_ReturnKind;
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
UINT32 m_NumSafePoints;
UINT32 m_SafePointIndex;
@@ -533,8 +542,8 @@ private:
#ifdef _DEBUG
GcInfoDecoderFlags m_Flags;
PTR_CBYTE m_GcInfoAddress;
- UINT32 m_Version;
#endif
+ UINT32 m_Version;
static bool SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback);
diff --git a/src/inc/gcinfoencoder.h b/src/inc/gcinfoencoder.h
index 8875d3b492..838f1babf7 100644
--- a/src/inc/gcinfoencoder.h
+++ b/src/inc/gcinfoencoder.h
@@ -12,6 +12,15 @@
ENCODING LAYOUT
1. Header
+
+ Slim Header for simple and common cases:
+ - EncodingType[Slim]
+ - ReturnKind (Fat: 2 bits)
+ - CodeLength
+ - NumCallSites (#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED)
+
+ Fat Header for other cases:
+ - EncodingType[Fat]
- Flag: isVarArg,
hasSecurityObject,
hasGSCookie,
@@ -20,6 +29,8 @@
hasStackBaseregister,
wantsReportOnlyLeaf,
hasSizeOfEditAndContinuePreservedArea
+ hasReversePInvokeFrame,
+ - ReturnKind (Fat: 4 bits)
- CodeLength
- Prolog (if hasSecurityObject || hasGenericsInstContextStackSlot || hasGSCookie)
- Epilog (if hasGSCookie)
@@ -29,9 +40,11 @@
- GenericsInstContextStackSlot (if any)
- StackBaseRegister (if any)
- SizeOfEditAndContinuePreservedArea (if any)
+ - ReversePInvokeFrameSlot (if any)
- SizeOfStackOutgoingAndScratchArea (#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA)
- NumCallSites (#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED)
- NumInterruptibleRanges
+
2. Call sites offsets (#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED)
3. Fully-interruptible ranges
4. Slot table
@@ -102,14 +115,15 @@ struct GcInfoSize
size_t SizeOfCode;
size_t FlagsSize;
+ size_t RetKindSize;
size_t CodeLengthSize;
size_t ProEpilogSize;
size_t SecObjSize;
size_t GsCookieSize;
- size_t GenericsCtxSize;
size_t PspSymSize;
+ size_t GenericsCtxSize;
size_t StackBaseSize;
- size_t FrameMarkerSize;
+ size_t ReversePInvokeFrameSize;
size_t FixedAreaSize;
size_t NumCallSitesSize;
size_t NumRangesSize;
@@ -129,7 +143,7 @@ struct GcInfoSize
size_t ChunkTransitionSize;
GcInfoSize();
- GcInfoSize& operator+=(GcInfoSize& other);
+ GcInfoSize& operator+=(const GcInfoSize& other);
void Log(DWORD level, const char * header);
};
#endif
@@ -390,6 +404,11 @@ public:
);
+ //------------------------------------------------------------------------
+ // ReturnKind
+ //------------------------------------------------------------------------
+
+ void SetReturnKind(ReturnKind returnKind);
//------------------------------------------------------------------------
// Miscellaneous method information
@@ -400,6 +419,7 @@ public:
void SetGSCookieStackSlot( INT32 spOffsetGSCookie, UINT32 validRangeStart, UINT32 validRangeEnd );
void SetPSPSymStackSlot( INT32 spOffsetPSPSym );
void SetGenericsInstContextStackSlot( INT32 spOffsetGenericsContext, GENERIC_CONTEXTPARAM_TYPE type);
+ void SetReversePInvokeFrameSlot(INT32 spOffset);
void SetIsVarArg();
void SetCodeLength( UINT32 length );
@@ -472,9 +492,11 @@ private:
INT32 m_PSPSymStackSlot;
INT32 m_GenericsInstContextStackSlot;
GENERIC_CONTEXTPARAM_TYPE m_contextParamType;
+ ReturnKind m_ReturnKind;
UINT32 m_CodeLength;
UINT32 m_StackBaseRegister;
UINT32 m_SizeOfEditAndContinuePreservedArea;
+ INT32 m_ReversePInvokeFrameSlot;
InterruptibleRange* m_pLastInterruptibleRange;
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
diff --git a/src/inc/gcinfotypes.h b/src/inc/gcinfotypes.h
index fc624b2c0a..c08dd79c16 100644
--- a/src/inc/gcinfotypes.h
+++ b/src/inc/gcinfotypes.h
@@ -46,7 +46,6 @@
#define DISABLE_EH_VECTORS
#endif
-
#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
#define FIXED_STACK_PARAMETER_SCRATCH_AREA
#endif
@@ -136,6 +135,210 @@ struct GcStackSlot
}
};
+//--------------------------------------------------------------------------------
+// ReturnKind -- encoding return type information in GcInfo
+//
+// When a method is stopped at a call - site for GC (ex: via return-address
+// hijacking) the runtime needs to know whether the value is a GC - value
+// (gc - pointer or gc - pointers stored in an aggregate).
+// It needs this information so that mark - phase can preserve the gc-pointers
+// being returned.
+//
+// The Runtime doesn't need the precise return-type of a method.
+// It only needs to find the GC-pointers in the return value.
+// The only scenarios currently supported by CoreCLR are:
+// 1. Object references
+// 2. ByRef pointers
+// 3. ARM64/X64 only : Structs returned in two registers
+// 4. X86 only : Floating point returns to perform the correct save/restore
+// of the return value around return-hijacking.
+//
+// Based on these cases, the legal set of ReturnKind enumerations are specified
+// for each architecture/encoding.
+// A value of this enumeration is stored in the GcInfo header.
+//
+//--------------------------------------------------------------------------------
+
+// RT_Unset: An intermediate step for staged bringup.
+// When ReturnKind is RT_Unset, it means that the JIT did not set
+// the ReturnKind in the GCInfo, and therefore the VM cannot rely on it,
+// and must use other mechanisms (similar to GcInfo ver 1) to determine
+// the Return type's GC information.
+//
+// RT_Unset is only used in the following situations:
+// X64: Used by JIT64 until updated to use GcInfo v2 API
+// ARM: Used by JIT32 until updated to use GcInfo v2 API
+//
+// RT_Unset should have a valid encoding, whose bits are actually stored in the image.
+// For X86, there are no free bits, and there's no RT_Unused enumeration.
+
+#if defined(_TARGET_X86_)
+
+// 00 RT_Scalar
+// 01 RT_Object
+// 10 RT_ByRef
+// 11 RT_Float
+
+#elif defined(_TARGET_ARM_)
+
+// 00 RT_Scalar
+// 01 RT_Object
+// 10 RT_ByRef
+// 11 RT_Unset
+
+#elif defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+
+// Slim Header:
+
+// 00 RT_Scalar
+// 01 RT_Object
+// 10 RT_ByRef
+// 11 RT_Unset
+
+// Fat Header:
+
+// 0000 RT_Scalar
+// 0001 RT_Object
+// 0010 RT_ByRef
+// 0011 RT_Unset
+// 0100 RT_Scalar_Obj
+// 1000 RT_Scalar_ByRef
+// 0101 RT_Obj_Obj
+// 1001 RT_Obj_ByRef
+// 0110 RT_ByRef_Obj
+// 1010 RT_ByRef_ByRef
+
+#else
+#ifdef PORTABILITY_WARNING
+PORTABILITY_WARNING("Need ReturnKind for new Platform")
+#endif // PORTABILITY_WARNING
+#endif // Target checks
+
+enum ReturnKind {
+
+ // Cases for Return in one register
+
+ RT_Scalar = 0,
+ RT_Object = 1,
+ RT_ByRef = 2,
+
+#ifdef _TARGET_X86_
+ RT_Float = 3, // Encoding 3 means RT_Float on X86
+#else
+ RT_Unset = 3, // RT_Unset on other platforms
+#endif // _TARGET_X86_
+
+ // Cases for Struct Return in two registers
+ //
+ // We have the following equivalencies, because the VM's behavior is the same
+ // for both cases:
+ // RT_Scalar_Scalar == RT_Scalar
+ // RT_Obj_Scalar == RT_Object
+ // RT_ByRef_Scalar == RT_Byref
+ // The encoding for these equivalencies will play out well because
+ // RT_Scalar is zero.
+ //
+ // Naming: RT_firstReg_secondReg
+ // Encoding: <Two bits for secondRef> <Two bits for first Reg>
+ //
+ // This encoding with exclusive bits for each register is chosen for ease of use,
+ // and because it doesn't cost any more bits.
+ // It can be changed (ex: to a linear sequence) if necessary.
+ // For example, we can encode the GC-information for the two registers in 3 bits (instead of 4)
+ // if we approximate RT_Obj_ByRef and RT_ByRef_Obj as RT_ByRef_ByRef.
+
+ // RT_Scalar_Scalar = RT_Scalar
+ RT_Scalar_Obj = RT_Object << 2 | RT_Scalar,
+ RT_Scalar_ByRef = RT_ByRef << 2 | RT_Scalar,
+
+ // RT_Obj_Scalar = RT_Object
+ RT_Obj_Obj = RT_Object << 2 | RT_Object,
+ RT_Obj_ByRef = RT_ByRef << 2 | RT_Object,
+
+ // RT_ByRef_Scalar = RT_Byref
+ RT_ByRef_Obj = RT_Object << 2 | RT_ByRef,
+ RT_ByRef_ByRef = RT_ByRef << 2 | RT_ByRef,
+
+ // Illegal or uninitialized value,
+ // Not a valid encoding, never written to image.
+ RT_Illegal = 0xFF
+};
+
+// Identify ReturnKinds containing useful information
+inline bool IsValidReturnKind(ReturnKind returnKind)
+{
+ return (returnKind != RT_Illegal)
+#ifndef _TARGET_X86_
+ && (returnKind != RT_Unset)
+#endif // _TARGET_X86_
+ ;
+}
+
+// Identify ReturnKinds that can be a part of a multi-reg struct return
+inline bool IsValidFieldReturnKind(ReturnKind returnKind)
+{
+ return (returnKind == RT_Scalar || returnKind == RT_Object || returnKind == RT_ByRef);
+}
+
+inline bool IsValidReturnRegister(size_t regNo)
+{
+ return (regNo == 0)
+#ifdef FEATURE_MULTIREG_RETURN
+ || (regNo == 1)
+#endif // FEATURE_MULTIREG_RETURN
+ ;
+}
+
+// Helpers for combining/extracting individual ReturnKinds from/to Struct ReturnKinds.
+// Encoding is two bits per register
+
+inline ReturnKind GetStructReturnKind(ReturnKind reg0, ReturnKind reg1)
+{
+ _ASSERTE(IsValidFieldReturnKind(reg0) && IsValidFieldReturnKind(reg1));
+
+ ReturnKind structReturnKind = (ReturnKind)(reg1 << 2 | reg0);
+
+ _ASSERTE(IsValidReturnKind(structReturnKind));
+
+ return structReturnKind;
+}
+
+inline ReturnKind ExtractRegReturnKind(ReturnKind returnKind, size_t regNo)
+{
+ _ASSERTE(IsValidReturnKind(returnKind));
+ _ASSERTE(IsValidReturnRegister(regNo));
+
+ ReturnKind regReturnKind = (ReturnKind)((returnKind >> (regNo * 2)) & 3);
+
+ _ASSERTE(IsValidReturnKind(regReturnKind));
+ _ASSERTE((regNo == 0) || IsValidFieldReturnKind(regReturnKind));
+
+ return regReturnKind;
+}
+
+inline const char *ReturnKindToString(ReturnKind returnKind)
+{
+ switch (returnKind) {
+ case RT_Scalar: return "Scalar";
+ case RT_Object: return "Object";
+ case RT_ByRef: return "ByRef";
+#ifdef _TARGET_X86_
+ case RT_Float: return "Float";
+#else
+ case RT_Unset: return "UNSET";
+#endif // _TARGET_X86_
+ case RT_Scalar_Obj: return "{Scalar, Object}";
+ case RT_Scalar_ByRef: return "{Scalar, ByRef}";
+ case RT_Obj_Obj: return "{Object, Object}";
+ case RT_Obj_ByRef: return "{Object, ByRef}";
+ case RT_ByRef_Obj: return "{ByRef, Object}";
+ case RT_ByRef_ByRef: return "{ByRef, ByRef}";
+
+ case RT_Illegal: return "<Illegal>";
+ default: return "!Impossible!";
+ }
+}
+
#ifdef _TARGET_X86_
#include <stdlib.h> // For memcmp()
@@ -375,6 +578,7 @@ void FASTCALL decodeCallPattern(int pattern,
#define NO_STACK_BASE_REGISTER (0xffffffff)
#define NO_SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA (0xffffffff)
#define NO_GENERICS_INST_CONTEXT (-1)
+#define NO_REVERSE_PINVOKE_FRAME (-1)
#define NO_PSP_SYM (-1)
#if defined(_TARGET_AMD64_)
@@ -408,9 +612,12 @@ void FASTCALL decodeCallPattern(int pattern,
#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 6
#define GS_COOKIE_STACK_SLOT_ENCBASE 6
#define CODE_LENGTH_ENCBASE 8
+#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2
+#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 4
#define STACK_BASE_REGISTER_ENCBASE 3
#define SIZE_OF_STACK_AREA_ENCBASE 3
#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 4
+#define REVERSE_PINVOKE_FRAME_ENCBASE 6
#define NUM_REGISTERS_ENCBASE 2
#define NUM_STACK_SLOTS_ENCBASE 2
#define NUM_UNTRACKED_SLOTS_ENCBASE 1
@@ -463,9 +670,12 @@ void FASTCALL decodeCallPattern(int pattern,
#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 5
#define GS_COOKIE_STACK_SLOT_ENCBASE 5
#define CODE_LENGTH_ENCBASE 7
+#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2
+#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 2
#define STACK_BASE_REGISTER_ENCBASE 1
#define SIZE_OF_STACK_AREA_ENCBASE 3
#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 3
+#define REVERSE_PINVOKE_FRAME_ENCBASE 5
#define NUM_REGISTERS_ENCBASE 2
#define NUM_STACK_SLOTS_ENCBASE 3
#define NUM_UNTRACKED_SLOTS_ENCBASE 3
@@ -515,9 +725,12 @@ void FASTCALL decodeCallPattern(int pattern,
#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 6
#define GS_COOKIE_STACK_SLOT_ENCBASE 6
#define CODE_LENGTH_ENCBASE 8
+#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2
+#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 4
#define STACK_BASE_REGISTER_ENCBASE 2 // FP encoded as 0, SP as 2.
#define SIZE_OF_STACK_AREA_ENCBASE 3
#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 4
+#define REVERSE_PINVOKE_FRAME_ENCBASE 6
#define NUM_REGISTERS_ENCBASE 3
#define NUM_STACK_SLOTS_ENCBASE 2
#define NUM_UNTRACKED_SLOTS_ENCBASE 1
@@ -573,9 +786,12 @@ PORTABILITY_WARNING("Please specialize these definitions for your platform!")
#define SECURITY_OBJECT_STACK_SLOT_ENCBASE 6
#define GS_COOKIE_STACK_SLOT_ENCBASE 6
#define CODE_LENGTH_ENCBASE 6
+#define SIZE_OF_RETURN_KIND_IN_SLIM_HEADER 2
+#define SIZE_OF_RETURN_KIND_IN_FAT_HEADER 2
#define STACK_BASE_REGISTER_ENCBASE 3
#define SIZE_OF_STACK_AREA_ENCBASE 6
#define SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE 3
+#define REVERSE_PINVOKE_FRAME_ENCBASE 6
#define NUM_REGISTERS_ENCBASE 3
#define NUM_STACK_SLOTS_ENCBASE 5
#define NUM_UNTRACKED_SLOTS_ENCBASE 5