text: // Licensed to the .NET Foundation under one or more agreements.
  // The .NET Foundation licenses this file to you under the MIT license.
  
  //----------------------------------------------------------
  // MethodContext.h - Primary structure to store all the EE-JIT details required to replay creation of a method
  //                   CompileResult contains the stuff generated by a compilation
  //----------------------------------------------------------
  #ifndef _MethodContext
  #define _MethodContext
  
  #include "runtimedetails.h"
  #include "compileresult.h"
  #include "lightweightmap.h"
  #include "errorhandling.h"
  #include "hash.h"
  #include "agnostic.h"
  
  extern bool g_debugRec;
  extern bool g_debugRep;
  
  #if 0
  // Enable these to get verbose logging during record or playback.
  #define DEBUG_REC(x)    \
      if (g_debugRec) {   \
          printf("rec");  \
          x;              \
          printf("\n");   \
      }
  
  #define DEBUG_REP(x)    \
      if (g_debugRep) {   \
          printf("rep");  \
          x;              \
          printf("\n");   \
      }
  #else
  #define DEBUG_REC(x)
  #define DEBUG_REP(x)
  #endif
  
  // Helper function for dumping.
  const char* toString(CorInfoType cit);
  
  #define METHOD_IDENTITY_INFO_SIZE 0x10000 // We assume that the METHOD_IDENTITY_INFO_SIZE will not exceed 64KB
  
  // Special "jit flags" for noting some method context features
  
  enum EXTRA_JIT_FLAGS
  {
      HAS_PGO = 63,
      HAS_EDGE_PROFILE = 62,
      HAS_CLASS_PROFILE = 61,
      HAS_LIKELY_CLASS = 60,
      HAS_STATIC_PROFILE = 59,
      HAS_DYNAMIC_PROFILE = 58
  };
  
  // Asserts to catch changes in corjit flags definitions.
  
  static_assert((int)EXTRA_JIT_FLAGS::HAS_PGO == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED36, "Jit Flags Mismatch");
  static_assert((int)EXTRA_JIT_FLAGS::HAS_EDGE_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED35, "Jit Flags Mismatch");
  static_assert((int)EXTRA_JIT_FLAGS::HAS_CLASS_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED34, "Jit Flags Mismatch");
  static_assert((int)EXTRA_JIT_FLAGS::HAS_LIKELY_CLASS == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED33, "Jit Flags Mismatch");
  static_assert((int)EXTRA_JIT_FLAGS::HAS_STATIC_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED32, "Jit Flags Mismatch");
  static_assert((int)EXTRA_JIT_FLAGS::HAS_DYNAMIC_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED31, "Jit Flags Mismatch");
  
  class MethodContext
  {
  public:
      MethodContext();
  
  private:
      MethodContext(HANDLE hFile);
      MethodContext(unsigned char* buff, unsigned int totalLen);
  
      void MethodInitHelper(unsigned char* buff, unsigned int totalLen);
      void MethodInitHelperFile(HANDLE hFile);
  
      bool Initialize(int mcIndex, unsigned char* buff, DWORD size);
      bool Initialize(int mcIndex, HANDLE hFile);
  
      int dumpMD5HashToBuffer(BYTE* pBuffer, int bufLen, char* buff, int len);
  
  public:
      static bool Initialize(int mcIndex, unsigned char* buff, DWORD size, /* OUT */ MethodContext** ppmc);
      static bool Initialize(int mcIndex, HANDLE hFile, /* OUT */ MethodContext** ppmc);
      ~MethodContext();
      void Destroy();
  
      bool Equal(MethodContext* other);
      unsigned int saveToFile(HANDLE hFile);
      unsigned int calculateFileSize();
      unsigned int calculateRawFileSize();
  
      // dumpToConsole: If mcNumber is not -1, display the method context number before the dumped info.
      // If simple is `true`, don't display the function name/arguments in the header.
      void dumpToConsole(int mcNumber = -1, bool simple = false);
  
      int dumpStatToBuffer(char* buff, int len);
      static int dumpStatTitleToBuffer(char* buff, int len);
      int methodSize;
  
      int dumpMethodIdentityInfoToBuffer(char* buff, int len, bool ignoreMethodName = false, CORINFO_METHOD_INFO* optInfo = nullptr, unsigned optFlags = 0);
      int dumpMethodMD5HashToBuffer(char* buff, int len, bool ignoreMethodName = false, CORINFO_METHOD_INFO* optInfo = nullptr, unsigned optFlags = 0);
  
      bool hasPgoData(bool& hasEdgeProfile, bool& hasClassProfile, bool& hasLikelyClass, ICorJitInfo::PgoSource& pgoSource);
  
      void recGlobalContext(const MethodContext& other);
  
      void dmpEnvironment(DWORD key, const Agnostic_Environment& value);
  
      void recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags, CORINFO_OS os);
      void dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value);
      void repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags, CORINFO_OS* os);
  
      void recGetMethodClass(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle);
      void dmpGetMethodClass(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetMethodClass(CORINFO_METHOD_HANDLE methodHandle);
  
      void recGetMethodModule(CORINFO_METHOD_HANDLE methodHandle, CORINFO_MODULE_HANDLE moduleHandle);
      void dmpGetMethodModule(DWORDLONG key, DWORDLONG value);
      CORINFO_MODULE_HANDLE repGetMethodModule(CORINFO_METHOD_HANDLE methodHandle);
  
      void recGetClassAttribs(CORINFO_CLASS_HANDLE classHandle, DWORD attribs);
      void dmpGetClassAttribs(DWORDLONG key, DWORD value);
      DWORD repGetClassAttribs(CORINFO_CLASS_HANDLE classHandle);
  
      void recIsIntrinsic(CORINFO_METHOD_HANDLE ftn, bool result);
      void dmpIsIntrinsic(DWORDLONG key, DWORD value);
      bool repIsIntrinsic(CORINFO_METHOD_HANDLE ftn);
  
      void recGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle, DWORD attribs);
      void dmpGetMethodAttribs(DWORDLONG key, DWORD value);
      DWORD repGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle);
  
      void recGetClassModule(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE mod);
      void dmpGetClassModule(DWORDLONG key, DWORDLONG value);
      CORINFO_MODULE_HANDLE repGetClassModule(CORINFO_CLASS_HANDLE cls);
  
      void recGetModuleAssembly(CORINFO_MODULE_HANDLE mod, CORINFO_ASSEMBLY_HANDLE assem);
      void dmpGetModuleAssembly(DWORDLONG key, DWORDLONG value);
      CORINFO_ASSEMBLY_HANDLE repGetModuleAssembly(CORINFO_MODULE_HANDLE mod);
  
      void recGetAssemblyName(CORINFO_ASSEMBLY_HANDLE assem, const char* assemblyName);
      void dmpGetAssemblyName(DWORDLONG key, DWORD value);
      const char* repGetAssemblyName(CORINFO_ASSEMBLY_HANDLE assem);
  
      void recGetVars(CORINFO_METHOD_HANDLE ftn, ULONG32* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers);
      void dmpGetVars(DWORDLONG key, const Agnostic_GetVars& value);
      void repGetVars(CORINFO_METHOD_HANDLE ftn, ULONG32* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers);
  
      void recGetBoundaries(CORINFO_METHOD_HANDLE         ftn,
                            unsigned int*                 cILOffsets,
                            uint32_t**                       pILOffsets,
                            ICorDebugInfo::BoundaryTypes* implicitBoundaries);
      void dmpGetBoundaries(DWORDLONG key, const Agnostic_GetBoundaries& value);
      void repGetBoundaries(CORINFO_METHOD_HANDLE         ftn,
                            unsigned int*                 cILOffsets,
                            uint32_t**                    pILOffsets,
                            ICorDebugInfo::BoundaryTypes* implicitBoundaries);
  
      void recInitClass(CORINFO_FIELD_HANDLE   field,
                        CORINFO_METHOD_HANDLE  method,
                        CORINFO_CONTEXT_HANDLE context,
                        CorInfoInitClassResult result);
      void dmpInitClass(const Agnostic_InitClass& key, DWORD value);
      CorInfoInitClassResult repInitClass(CORINFO_FIELD_HANDLE   field,
                                          CORINFO_METHOD_HANDLE  method,
                                          CORINFO_CONTEXT_HANDLE context);
  
      void recGetMethodName(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName);
      void dmpGetMethodName(DLD key, DD value);
      const char* repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName);
  
      void recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn,
                                        char*                 methodname,
                                        const char**          moduleName,
                                        const char**          namespaceName,
                                        const char**          enclosingClassName);
      void dmpGetMethodNameFromMetadata(Agnostic_CORINFO_METHODNAME_TOKENin key, Agnostic_CORINFO_METHODNAME_TOKENout value);
      const char* repGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn,
                                               const char**          className,
                                               const char**          namespaceName,
                                               const char**          enclosingClassName);
  
      void recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DWORD result);
      void dmpGetJitFlags(DWORD key, DD value);
      DWORD repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes);
  
      void recGetJitTimeLogFilename(LPCWSTR tempFileName);
      void dmpGetJitTimeLogFilename(DWORD key, DWORD value);
      LPCWSTR repGetJitTimeLogFilename();
  
      void recCanInline(CORINFO_METHOD_HANDLE callerHnd,
                        CORINFO_METHOD_HANDLE calleeHnd,
                        uint32_t*                pRestrictions,
                        CorInfoInline         response,
                        DWORD                 exceptionCode);
      void dmpCanInline(DLDL key, const Agnostic_CanInline& value);
      CorInfoInline repCanInline(CORINFO_METHOD_HANDLE callerHnd,
                                 CORINFO_METHOD_HANDLE calleeHnd,
                                 uint32_t*             pRestrictions,
                                 DWORD*                exceptionCode);
  
      void recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode);
      void dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const ResolveTokenValue& value);
      void repResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD* exceptionCode);
  
      void recTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool success);
      void dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const TryResolveTokenValue& value);
      bool repTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken);
  
      void recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                          CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
                          CORINFO_METHOD_HANDLE   callerHandle,
                          CORINFO_CALLINFO_FLAGS  flags,
                          CORINFO_CALL_INFO*      pResult,
                          DWORD                   exceptionCode);
      void dmpGetCallInfo(const Agnostic_GetCallInfo& key, const Agnostic_CORINFO_CALL_INFO& value);
      void repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                          CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
                          CORINFO_METHOD_HANDLE   callerHandle,
                          CORINFO_CALLINFO_FLAGS  flags,
                          CORINFO_CALL_INFO*      pResult,
                          DWORD*                  exceptionCode);
      void repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CALL_INFO* pResult);
  
      void recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result);
      void dmpAsCorInfoType(DWORDLONG key, DWORD value);
      CorInfoType repAsCorInfoType(CORINFO_CLASS_HANDLE cls);
  
      void recIsValueClass(CORINFO_CLASS_HANDLE cls, bool result);
      void dmpIsValueClass(DWORDLONG key, DWORD value);
      bool repIsValueClass(CORINFO_CLASS_HANDLE cls);
  
      void recGetClassSize(CORINFO_CLASS_HANDLE cls, unsigned result);
      void dmpGetClassSize(DWORDLONG key, DWORD val);
      unsigned repGetClassSize(CORINFO_CLASS_HANDLE cls);
  
      void recGetHeapClassSize(CORINFO_CLASS_HANDLE cls, unsigned result);
      void dmpGetHeapClassSize(DWORDLONG key, DWORD val);
      unsigned repGetHeapClassSize(CORINFO_CLASS_HANDLE cls);
  
      void recCanAllocateOnStack(CORINFO_CLASS_HANDLE cls, bool result);
      void dmpCanAllocateOnStack(DWORDLONG key, DWORD val);
      bool repCanAllocateOnStack(CORINFO_CLASS_HANDLE cls);
  
      void recGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls, unsigned result);
      void dmpGetClassNumInstanceFields(DWORDLONG key, DWORD value);
      unsigned repGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls);
  
      void recGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls, CorInfoHelpFunc result);
      void dmpGetNewArrHelper(DWORDLONG key, DWORD value);
      CorInfoHelpFunc repGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls);
  
      void recGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd, CorInfoHelpFunc result);
      void dmpGetSharedCCtorHelper(DWORDLONG key, DWORD value);
      CorInfoHelpFunc repGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd);
  
      void recGetTypeForBox(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
      void dmpGetTypeForBox(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetTypeForBox(CORINFO_CLASS_HANDLE cls);
  
      void recGetBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result);
      void dmpGetBoxHelper(DWORDLONG key, DWORD value);
      CorInfoHelpFunc repGetBoxHelper(CORINFO_CLASS_HANDLE cls);
  
      void recGetBuiltinClass(CorInfoClassId classId, CORINFO_CLASS_HANDLE result);
      void dmpGetBuiltinClass(DWORD key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetBuiltinClass(CorInfoClassId classId);
  
      void recGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls, CorInfoType result);
      void dmpGetTypeForPrimitiveValueClass(DWORDLONG key, DWORD value);
      CorInfoType repGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls);
  
      void recGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls, CorInfoType result);
      void dmpGetTypeForPrimitiveNumericClass(DWORDLONG key, DWORD value);
      CorInfoType repGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls);
  
      void recGetParentType(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
      void dmpGetParentType(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetParentType(CORINFO_CLASS_HANDLE cls);
  
      void recIsSDArray(CORINFO_CLASS_HANDLE cls, bool result);
      void dmpIsSDArray(DWORDLONG key, DWORD value);
      bool repIsSDArray(CORINFO_CLASS_HANDLE cls);
  
      void recIsIntrinsicType(CORINFO_CLASS_HANDLE cls, bool result);
      void dmpIsIntrinsicType(DWORDLONG key, DWORD value);
      bool repIsIntrinsicType(CORINFO_CLASS_HANDLE cls);
  
      void recGetFieldClass(CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE result);
      void dmpGetFieldClass(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetFieldClass(CORINFO_FIELD_HANDLE field);
  
      void recGetFieldOffset(CORINFO_FIELD_HANDLE field, unsigned result);
      void dmpGetFieldOffset(DWORDLONG key, DWORD value);
      unsigned repGetFieldOffset(CORINFO_FIELD_HANDLE field);
  
      void recGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle, CorInfoHelpFunc result);
      void dmpGetLazyStringLiteralHelper(DWORDLONG key, DWORD value);
      CorInfoHelpFunc repGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle);
  
      void recGetUnBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result);
      void dmpGetUnBoxHelper(DWORDLONG key, DWORD value);
      CorInfoHelpFunc repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls);
  
      void recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                  CORINFO_LOOKUP_KIND*    pGenericLookupKind,
                                  CorInfoHelpFunc         id,
                                  CORINFO_CONST_LOOKUP*   pLookup,
                                  bool                    result);
      void dmpGetReadyToRunHelper(GetReadyToRunHelper_TOKENin key, GetReadyToRunHelper_TOKENout value);
      bool repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                  CORINFO_LOOKUP_KIND*    pGenericLookupKind,
                                  CorInfoHelpFunc         id,
                                  CORINFO_CONST_LOOKUP*   pLookup);
  
      void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod,
                                              CORINFO_CLASS_HANDLE    delegateType,
                                              CORINFO_LOOKUP*         pLookup);
      void dmpGetReadyToRunDelegateCtorHelper(GetReadyToRunDelegateCtorHelper_TOKENIn key,
                                              Agnostic_CORINFO_LOOKUP                 pLookup);
      void repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod,
                                              CORINFO_CLASS_HANDLE    delegateType,
                                              CORINFO_LOOKUP*         pLookup);
  
      void recGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection, void* result);
      void dmpGetHelperFtn(DWORD key, DLDL value);
      void* repGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection);
      bool fndGetHelperFtn(void* functionAddress, CorInfoHelpFunc* pResult);
  
      void recGetJustMyCodeHandle(CORINFO_METHOD_HANDLE         method,
                                  CORINFO_JUST_MY_CODE_HANDLE** ppIndirection,
                                  CORINFO_JUST_MY_CODE_HANDLE   result);
      void dmpGetJustMyCodeHandle(DWORDLONG key, DLDL value);
      CORINFO_JUST_MY_CODE_HANDLE repGetJustMyCodeHandle(CORINFO_METHOD_HANDLE         method,
                                                         CORINFO_JUST_MY_CODE_HANDLE** ppIndirection);
  
      void recGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn,
                                    CORINFO_CONST_LOOKUP* pResult,
                                    CORINFO_ACCESS_FLAGS  accessFlags);
      void dmpGetFunctionEntryPoint(DLD key, DLD value);
      void repGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn,
                                    CORINFO_CONST_LOOKUP* pResult,
                                    CORINFO_ACCESS_FLAGS  accessFlags);
      bool fndGetFunctionEntryPoint(DLD value, CORINFO_METHOD_HANDLE* pResult);
  
      void recConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void* ppValue, InfoAccessType result);
      void dmpConstructStringLiteral(DLD key, DLD value);
      InfoAccessType repConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue);
  
      void recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert, bool result);
      void dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value);
      bool repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert);
  
      void recEmptyStringLiteral(void** ppValue, InfoAccessType result);
      void dmpEmptyStringLiteral(DWORD key, DLD value);
      InfoAccessType repEmptyStringLiteral(void** ppValue);
  
      void recGetArgType(CORINFO_SIG_INFO*       sig,
                         CORINFO_ARG_LIST_HANDLE args,
                         CORINFO_CLASS_HANDLE*   vcTypeRet,
                         CorInfoTypeWithMod      result,
                         DWORD                   exception);
      void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value);
      CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO*       sig,
                                       CORINFO_ARG_LIST_HANDLE args,
                                       CORINFO_CLASS_HANDLE*   vcTypeRet,
                                       DWORD*                  exception);
  
      void recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result);
      void dmpGetArgNext(DWORDLONG key, DWORDLONG value);
      CORINFO_ARG_LIST_HANDLE repGetArgNext(CORINFO_ARG_LIST_HANDLE args);
  
      void recGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent);
      void dmpGetMethodSig(DLDL key, const Agnostic_CORINFO_SIG_INFO& value);
      void repGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent);
  
      void recGetArgClass(CORINFO_SIG_INFO*       sig,
                          CORINFO_ARG_LIST_HANDLE args,
                          CORINFO_CLASS_HANDLE    result,
                          DWORD                   exceptionCode);
      void dmpGetArgClass(const Agnostic_GetArgClass_Key& key, const Agnostic_GetArgClass_Value& value);
      CORINFO_CLASS_HANDLE repGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, DWORD* exceptionCode);
  
      void recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoHFAElemType result);
      void dmpGetHFAType(DWORDLONG key, DWORD value);
      CorInfoHFAElemType repGetHFAType(CORINFO_CLASS_HANDLE clsHnd);
  
      void recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, bool result, DWORD exceptionCode);
      void dmpGetMethodInfo(DWORDLONG key, const Agnostic_GetMethodInfo& value);
      bool repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, DWORD* exceptionCode);
  
      void recGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                           CORINFO_METHOD_HANDLE   callerHandle,
                           bool* pHasSideEffects,
                           CorInfoHelpFunc         result);
      void dmpGetNewHelper(const Agnostic_GetNewHelper& key, DD value);
      CorInfoHelpFunc repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool * pHasSideEffects);
  
      void recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN*       pResolvedToken,
                                 bool                          fEmbedParent,
                                 CORINFO_GENERICHANDLE_RESULT* pResult);
      void dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle&           key,
                                 const Agnostic_CORINFO_GENERICHANDLE_RESULT& value);
      void repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN*       pResolvedToken,
                                 bool                          fEmbedParent,
                                 CORINFO_GENERICHANDLE_RESULT* pResult);
  
      void recGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause);
      void dmpGetEHinfo(DLD key, const Agnostic_CORINFO_EH_CLAUSE& value);
      void repGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause);
  
      void recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
                                    unsigned*             offsetOfIndirection,
                                    unsigned*             offsetAfterIndirection,
                                    bool*                 isRelative);
      void dmpGetMethodVTableOffset(DWORDLONG key, DDD value);
      void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method,
                                    unsigned*             offsetOfIndirection,
                                    unsigned*             offsetAfterIndirection,
                                    bool*                 isRelative);
  
      void recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info, bool returnValue);
      void dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodKey& key, const Agnostic_ResolveVirtualMethodResult& value);
      bool repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info);
  
      void recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg, CORINFO_METHOD_HANDLE result);
      void dmpGetUnboxedEntry(DWORDLONG key, DLD value);
      CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg);
  
      void recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
      void dmpGetDefaultComparerClass(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls);
  
      void recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result);
      void dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls);
  
      void recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CLASS_HANDLE result);
      void dmpGetTokenTypeAsHandle(const GetTokenTypeAsHandleValue& key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken);
  
      void recGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                           CORINFO_METHOD_HANDLE   callerHandle,
                           CORINFO_ACCESS_FLAGS    flags,
                           CORINFO_FIELD_INFO*     pResult);
      void dmpGetFieldInfo(const Agnostic_GetFieldInfo& key, const Agnostic_CORINFO_FIELD_INFO& value);
      void repGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                           CORINFO_METHOD_HANDLE   callerHandle,
                           CORINFO_ACCESS_FLAGS    flags,
                           CORINFO_FIELD_INFO*     pResult);
  
      void recEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection, CORINFO_METHOD_HANDLE result);
      void dmpEmbedMethodHandle(DWORDLONG key, DLDL value);
      CORINFO_METHOD_HANDLE repEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection);
  
      void recGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection, void* result, CorInfoType cit);
      void dmpGetFieldAddress(DWORDLONG key, const Agnostic_GetFieldAddress& value);
      void* repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection);
  
      void recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool isSpeculative, CORINFO_CLASS_HANDLE result);
      void dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value);
      CORINFO_CLASS_HANDLE repGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative);
  
      void recGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs, unsigned len, unsigned result);
      void dmpGetClassGClayout(DWORDLONG key, const Agnostic_GetClassGClayout& value);
      unsigned repGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs);
  
      void recGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, bool fDoubleAlignHint, unsigned result);
      void dmpGetClassAlignmentRequirement(DLD key, DWORD value);
      unsigned repGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, bool fDoubleAlignHint);
  
      void recCanAccessClass(CORINFO_RESOLVED_TOKEN*      pResolvedToken,
                             CORINFO_METHOD_HANDLE        callerHandle,
                             CORINFO_HELPER_DESC*         pAccessHelper,
                             CorInfoIsAccessAllowedResult result);
      void dmpCanAccessClass(const Agnostic_CanAccessClassIn& key, const Agnostic_CanAccessClassOut& value);
      CorInfoIsAccessAllowedResult repCanAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                                     CORINFO_METHOD_HANDLE   callerHandle,
                                                     CORINFO_HELPER_DESC*    pAccessHelper);
  
      void recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result);
      void dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value);
      CorInfoHelpFunc repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing);
  
      void recEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection, CORINFO_MODULE_HANDLE result);
      void dmpEmbedModuleHandle(DWORDLONG key, DLDL value);
      CORINFO_MODULE_HANDLE repEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection);
  
      void recEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection, CORINFO_CLASS_HANDLE result);
      void dmpEmbedClassHandle(DWORDLONG key, DLDL value);
      CORINFO_CLASS_HANDLE repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection);
  
      void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result);
      void dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value);
      bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
  
      void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result, bool suppressGCTransitionResult);
      void dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value);
      CorInfoCallConvExtension repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition);
  
      void recFindSig(CORINFO_MODULE_HANDLE  module,
                      unsigned               sigTOK,
                      CORINFO_CONTEXT_HANDLE context,
                      CORINFO_SIG_INFO*      sig);
      void dmpFindSig(const Agnostic_FindSig& key, const Agnostic_CORINFO_SIG_INFO& value);
      void repFindSig(CORINFO_MODULE_HANDLE  module,
                      unsigned               sigTOK,
                      CORINFO_CONTEXT_HANDLE context,
                      CORINFO_SIG_INFO*      sig);
  
      void recGetEEInfo(CORINFO_EE_INFO* pEEInfoOut);
      void dmpGetEEInfo(DWORD key, const Agnostic_CORINFO_EE_INFO& value);
      void repGetEEInfo(CORINFO_EE_INFO* pEEInfoOut);
  
      void recGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal);
      void dmpGetGSCookie(DWORD key, DLDL value);
      void repGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal);
  
      void recGetOSRInfo(PatchpointInfo* patchpointInfo, unsigned* ilOffset);
      void dmpGetOSRInfo(DWORD key, const Agnostic_GetOSRInfo& value);
      PatchpointInfo* repGetOSRInfo(unsigned* ilOffset);
  
      void recGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE   cls,
                                         CORINFO_MODULE_HANDLE* pModule,
                                         void**                 ppIndirection,
                                         size_t                 result);
      void dmpGetClassModuleIdForStatics(DWORDLONG key, const Agnostic_GetClassModuleIdForStatics& value);
      size_t repGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE   cls,
                                           CORINFO_MODULE_HANDLE* pModule,
                                           void**                 ppIndirection);
  
      void recGetThreadTLSIndex(void** ppIndirection, DWORD result);
      void dmpGetThreadTLSIndex(DWORD key, DLD value);
      DWORD repGetThreadTLSIndex(void** ppIndirection);
  
      void recGetInlinedCallFrameVptr(void** ppIndirection, const void* result);
      void dmpGetInlinedCallFrameVptr(DWORD key, DLDL value);
      const void* repGetInlinedCallFrameVptr(void** ppIndirection);
  
      void recGetAddrOfCaptureThreadGlobal(void** ppIndirection, int32_t* result);
      void dmpGetAddrOfCaptureThreadGlobal(DWORD key, DLDL value);
      int32_t* repGetAddrOfCaptureThreadGlobal(void** ppIndirection);
  
      void recGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection, unsigned result);
      void dmpGetClassDomainID(DWORDLONG key, DLD value);
      unsigned repGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection);
  
      void recGetLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* result);
      void dmpGetLocationOfThisType(DWORDLONG key, const Agnostic_CORINFO_LOOKUP_KIND& value);
      void repGetLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind);
  
      void recGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
                              CORINFO_CLASS_HANDLE  clsHnd,
                              CORINFO_METHOD_HANDLE targetMethodHnd,
                              DelegateCtorArgs*     pCtorData,
                              CORINFO_METHOD_HANDLE result);
      void dmpGetDelegateCtor(const Agnostic_GetDelegateCtorIn& key, const Agnostic_GetDelegateCtorOut& value);
      CORINFO_METHOD_HANDLE repGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
                                               CORINFO_CLASS_HANDLE  clsHnd,
                                               CORINFO_METHOD_HANDLE targetMethodHnd,
                                               DelegateCtorArgs*     pCtorData);
  
      void recGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult);
      void dmpGetFunctionFixedEntryPoint(DWORDLONG key, const Agnostic_CORINFO_CONST_LOOKUP& value);
      void repGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult);
  
      void recGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num, CORINFO_FIELD_HANDLE result);
      void dmpGetFieldInClass(DLD key, DWORDLONG value);
      CORINFO_FIELD_HANDLE repGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);
  
      void recGetFieldType(CORINFO_FIELD_HANDLE  field,
                           CORINFO_CLASS_HANDLE* structType,
                           CORINFO_CLASS_HANDLE  memberParent,
                           CorInfoType           result);
      void dmpGetFieldType(DLDL key, DLD value);
      CorInfoType repGetFieldType(CORINFO_FIELD_HANDLE  field,
                                  CORINFO_CLASS_HANDLE* structType,
                                  CORINFO_CLASS_HANDLE  memberParent);
  
      void recGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName, const char* result);
      void dmpGetFieldName(DWORDLONG key, DD value);
      const char* repGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName);
  
      void recCanInlineTypeCheck(CORINFO_CLASS_HANDLE         cls,
                                 CorInfoInlineTypeCheckSource source,
                                 CorInfoInlineTypeCheck       result);
      void dmpCanInlineTypeCheck(DLD key, DWORD value);
      CorInfoInlineTypeCheck repCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source);
  
      void recSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method, bool result);
      void dmpSatisfiesMethodConstraints(DLDL key, DWORD value);
      bool repSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method);
  
      void recIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result);
      void dmpIsValidStringRef(DLD key, DWORD value);
      bool repIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK);
  
      void recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int length, const char16_t* result);
      void dmpGetStringLiteral(DLD key, DD value);
      const char16_t* repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, int* length);
  
      void recGetHelperName(CorInfoHelpFunc funcNum, const char* result);
      void dmpGetHelperName(DWORD key, DWORD value);
      const char* repGetHelperName(CorInfoHelpFunc funcNum);
  
      void recCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent, bool result);
      void dmpCanCast(DLDL key, DWORD value);
      bool repCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent);
  
      void recGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet, CorInfoType result);
      void dmpGetChildType(DWORDLONG key, DLD value);
      CorInfoType repGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet);
  
      void recGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size, void* result);
      void dmpGetArrayInitializationData(DLD key, DWORDLONG value);
      void* repGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size);
  
      void recFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers, int result);
      void dmpFilterException(DWORD key, DWORD value);
      int repFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers);
  
      void recGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup);
      void dmpGetAddressOfPInvokeTarget(DWORDLONG key, DLD value);
      void repGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup);
  
      void recSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls, bool result);
      void dmpSatisfiesClassConstraints(DWORDLONG key, DWORD value);
      bool repSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls);
  
      void recGetMethodHash(CORINFO_METHOD_HANDLE ftn, unsigned result);
      void dmpGetMethodHash(DWORDLONG key, DWORD value);
      unsigned repGetMethodHash(CORINFO_METHOD_HANDLE ftn);
  
      void recCanTailCall(CORINFO_METHOD_HANDLE callerHnd,
                          CORINFO_METHOD_HANDLE declaredCalleeHnd,
                          CORINFO_METHOD_HANDLE exactCalleeHnd,
                          bool                  fIsTailPrefix,
                          bool                  result);
      void dmpCanTailCall(const Agnostic_CanTailCall& key, DWORD value);
      bool repCanTailCall(CORINFO_METHOD_HANDLE callerHnd,
                          CORINFO_METHOD_HANDLE declaredCalleeHnd,
                          CORINFO_METHOD_HANDLE exactCalleeHnd,
                          bool                  fIsTailPrefix);
  
      void recIsCompatibleDelegate(CORINFO_CLASS_HANDLE  objCls,
                                   CORINFO_CLASS_HANDLE  methodParentCls,
                                   CORINFO_METHOD_HANDLE method,
                                   CORINFO_CLASS_HANDLE  delegateCls,
                                   bool*                 pfIsOpenDelegate,
                                   bool                  result);
      void dmpIsCompatibleDelegate(const Agnostic_IsCompatibleDelegate& key, DD value);
      bool repIsCompatibleDelegate(CORINFO_CLASS_HANDLE  objCls,
                                   CORINFO_CLASS_HANDLE  methodParentCls,
                                   CORINFO_METHOD_HANDLE method,
                                   CORINFO_CLASS_HANDLE  delegateCls,
                                   bool*                 pfIsOpenDelegate);
  
      void recIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, CORINFO_METHOD_HANDLE calleeHnd, bool result);
      void dmpIsDelegateCreationAllowed(DLDL key, DWORD value);
      bool repIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, CORINFO_METHOD_HANDLE calleeHnd);
  
      void recFindCallSiteSig(CORINFO_MODULE_HANDLE  module,
                              unsigned               methTOK,
                              CORINFO_CONTEXT_HANDLE context,
                              CORINFO_SIG_INFO*      sig);
      void dmpFindCallSiteSig(const Agnostic_FindCallSiteSig& key, const Agnostic_CORINFO_SIG_INFO& value);
      void repFindCallSiteSig(CORINFO_MODULE_HANDLE  module,
                              unsigned               methTOK,
                              CORINFO_CONTEXT_HANDLE context,
                              CORINFO_SIG_INFO*      sig);
  
      void recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result);
      void dmpGetMethodSync(DWORDLONG key, DLDL value);
      void* repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection);
  
      void recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result);
      void dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value);
      CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection);
  
      void recCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig, bool result);
      void dmpCanGetVarArgsHandle(const CanGetVarArgsHandleValue& key, DWORD value);
      bool repCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig);
  
      void recGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection, DWORD result);
      void dmpGetFieldThreadLocalStoreID(DWORDLONG key, DLD value);
      DWORD repGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection);
  
      void recAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData, HRESULT result);
      void dmpAllocPgoInstrumentationBySchema(DWORDLONG key, const Agnostic_AllocPgoInstrumentationBySchema& value);
      HRESULT repAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData);
  
      void recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, HRESULT result);
      void dmpGetPgoInstrumentationResults(DWORDLONG key, const Agnostic_GetPgoInstrumentationResults& value);
      HRESULT repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource);
  
      void recMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, CORINFO_CLASS_HANDLE result);
      void dmpMergeClasses(DLDL key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
  
      void recIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result);
      void dmpIsMoreSpecificType(DLDL key, DWORD value);
      bool repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
  
      void recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result);
      void dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value);
      LPVOID repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection);
  
      void recCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, bool result);
      void dmpCanGetCookieForPInvokeCalliSig(const CanGetCookieForPInvokeCalliSigValue& key, DWORD value);
      bool repCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig);
  
      void recCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType, bool result);
      void dmpCanAccessFamily(DLDL key, DWORD value);
      bool repCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType);
  
      void recErrorList(const char* error);
      void dmpErrorList(DWORD key, DWORD value);
  
      void recGetProfilingHandle(bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles);
      void dmpGetProfilingHandle(DWORD key, const Agnostic_GetProfilingHandle& value);
      void repGetProfilingHandle(bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles);
  
      void recEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection, CORINFO_FIELD_HANDLE result);
      void dmpEmbedFieldHandle(DWORDLONG key, DLDL value);
      CORINFO_FIELD_HANDLE repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection);
  
      void recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result);
      void dmpAreTypesEquivalent(DLDL key, DWORD value);
      bool repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
  
      void recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result);
      void dmpCompareTypesForCast(DLDL key, DWORD value);
      TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass);
  
      void recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, TypeCompareState result);
      void dmpCompareTypesForEquality(DLDL key, DWORD value);
      TypeCompareState repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
  
      void recFindNameOfToken(
          CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity, size_t result);
      void dmpFindNameOfToken(DLD key, DLD value);
      size_t repFindNameOfToken(CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity);
  
      void recGetSystemVAmd64PassStructInRegisterDescriptor(
          CORINFO_CLASS_HANDLE                                 structHnd,
          SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr,
          bool                                                 result);
      void dmpGetSystemVAmd64PassStructInRegisterDescriptor(
          DWORDLONG key, const Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor& value);
      bool repGetSystemVAmd64PassStructInRegisterDescriptor(
          CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
  
      void recGetRelocTypeHint(void* target, WORD result);
      void dmpGetRelocTypeHint(DWORDLONG key, DWORD value);
      WORD repGetRelocTypeHint(void* target);
  
      void recGetExpectedTargetArchitecture(DWORD result);
      void dmpGetExpectedTargetArchitecture(DWORD key, DWORD result);
      DWORD repGetExpectedTargetArchitecture();
  
      void recDoesFieldBelongToClass(CORINFO_FIELD_HANDLE fld, CORINFO_CLASS_HANDLE cls, bool result);
      void dmpDoesFieldBelongToClass(DLDL key, bool value);
      bool repDoesFieldBelongToClass(CORINFO_FIELD_HANDLE fld, CORINFO_CLASS_HANDLE cls);
  
      void recIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result);
      void dmpIsValidToken(DLD key, DWORD value);
      bool repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK);
  
      void recGetClassName(CORINFO_CLASS_HANDLE cls, const char* result);
      void dmpGetClassName(DWORDLONG key, DWORD value);
      const char* repGetClassName(CORINFO_CLASS_HANDLE cls);
  
      void recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, char* className, const char** namespaceName);
      void dmpGetClassNameFromMetadata(DLD key, DD value);
      const char* repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName);
  
      void recGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result, unsigned index);
      void dmpGetTypeInstantiationArgument(DWORDLONG key, DWORDLONG value);
      CORINFO_CLASS_HANDLE repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index);
  
      void recAppendClassName(
          CORINFO_CLASS_HANDLE cls, bool fNamespace, bool fFullInst, bool fAssembly, const char16_t* result);
      void dmpAppendClassName(const Agnostic_AppendClassName& key, DWORD value);
      const WCHAR* repAppendClassName(CORINFO_CLASS_HANDLE cls, bool fNamespace, bool fFullInst, bool fAssembly);
  
      void recGetTailCallHelpers(
          CORINFO_RESOLVED_TOKEN* callToken,
          CORINFO_SIG_INFO* sig,
          CORINFO_GET_TAILCALL_HELPERS_FLAGS flags,
          CORINFO_TAILCALL_HELPERS* pResult);
      void dmpGetTailCallHelpers(const Agnostic_GetTailCallHelpers& key, const Agnostic_CORINFO_TAILCALL_HELPERS& value);
      bool repGetTailCallHelpers(
          CORINFO_RESOLVED_TOKEN* callToken,
          CORINFO_SIG_INFO* sig,
          CORINFO_GET_TAILCALL_HELPERS_FLAGS flags,
          CORINFO_TAILCALL_HELPERS* pResult);
  
      void recUpdateEntryPointForTailCall(const CORINFO_CONST_LOOKUP& origEntryPoint, const CORINFO_CONST_LOOKUP& newEntryPoint);
      void dmpUpdateEntryPointForTailCall(const Agnostic_CORINFO_CONST_LOOKUP& origEntryPoint, const Agnostic_CORINFO_CONST_LOOKUP& newEntryPoint);
      void repUpdateEntryPointForTailCall(CORINFO_CONST_LOOKUP* entryPoint);
  
      void recGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod, mdMethodDef result);
      void dmpGetMethodDefFromMethod(DWORDLONG key, DWORD value);
      mdMethodDef repGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod);
  
      void recCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, bool fOptional, bool result);
      void dmpCheckMethodModifier(const Agnostic_CheckMethodModifier& key, DWORD value);
      bool repCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, bool fOptional);
  
      void recGetArrayRank(CORINFO_CLASS_HANDLE cls, unsigned result);
      void dmpGetArrayRank(DWORDLONG key, DWORD value);
      unsigned repGetArrayRank(CORINFO_CLASS_HANDLE cls);
  
      void recGetArrayIntrinsicID(CORINFO_METHOD_HANDLE hMethod, CorInfoArrayIntrinsic result);
      void dmpGetArrayIntrinsicID(DWORDLONG key, DWORD value);
      CorInfoArrayIntrinsic repGetArrayIntrinsicID(CORINFO_METHOD_HANDLE hMethod);
  
      void recIsFieldStatic(CORINFO_FIELD_HANDLE fhld, bool result);
      void dmpIsFieldStatic(DWORDLONG key, DWORD value);
      bool repIsFieldStatic(CORINFO_FIELD_HANDLE fhld);
  
      void recGetIntConfigValue(const WCHAR* name, int defaultValue, int result);
      void dmpGetIntConfigValue(const Agnostic_ConfigIntInfo& key, int value);
      int repGetIntConfigValue(const WCHAR* name, int defaultValue);
  
      void recGetStringConfigValue(const WCHAR* name, const WCHAR* result);
      void dmpGetStringConfigValue(DWORD nameIndex, DWORD result);
      const WCHAR* repGetStringConfigValue(const WCHAR* name);
  
      void dmpSigInstHandleMap(DWORD key, DWORDLONG value);
  
      struct Environment
      {
          Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr)
          {
          }
  
          LightWeightMap<Agnostic_ConfigIntInfo, DWORD>* getIntConfigValue;
          LightWeightMap<DWORD, DWORD>*                  getStingConfigValue;
      };
  
      Environment cloneEnvironment();
  
      bool WasEnvironmentChanged(const Environment& prevEnv);
  
      CompileResult* cr;
      CompileResult* originalCR;
      int            index;
  
  private:
      bool IsEnvironmentHeaderEqual(const Environment& prevEnv);
      bool IsEnvironmentContentEqual(const Environment& prevEnv);
  
      enum class ReadyToRunCompilation
      {
          Uninitialized,
          ReadyToRun,
          NotReadyToRun
      };
  
      ReadyToRunCompilation isReadyToRunCompilation;
  
      void InitReadyToRunFlag(const CORJIT_FLAGS* jitFlags);
  
      template <typename key, typename value>
      static bool AreLWMHeadersEqual(LightWeightMap<key, value>* prev, LightWeightMap<key, value>* curr);
      static bool IsIntConfigContentEqual(LightWeightMap<Agnostic_ConfigIntInfo, DWORD>* prev,
                                          LightWeightMap<Agnostic_ConfigIntInfo, DWORD>* curr);
      static bool IsStringContentEqual(LightWeightMap<DWORD, DWORD>* prev, LightWeightMap<DWORD, DWORD>* curr);
  
  #define LWM(map, key, value) LightWeightMap<key, value>* map;
  #define DENSELWM(map, value) DenseLightWeightMap<value>* map;
  #include "lwmlist.h"
  
      // MD5 hasher
      static Hash m_hash;
  
      // Scheme for jit time temporary allocations
      struct DeletionNode
      {
          DeletionNode* pNext;
      };
      DeletionNode *nodesToDelete = nullptr;
  
      void* AllocJitTempBuffer(size_t size)
      {
          DeletionNode *pDeletionNode = (DeletionNode *)malloc(sizeof(DeletionNode) + size);
          pDeletionNode->pNext = this->nodesToDelete;
          this->nodesToDelete = pDeletionNode;
          return pDeletionNode + 1;
      }
  
      void FreeTempAllocations()
      {
          while (nodesToDelete != nullptr)
          {
              DeletionNode *next = nodesToDelete->pNext;
              free(nodesToDelete);
              nodesToDelete = next;
          }
      }
  };
  
  enum mcPackets
  {
      Packet_AreTypesEquivalent = 1,
      Packet_AsCorInfoType = 2,
      Packet_CanAccessClass = 3,
      Packet_CanAccessFamily = 4,
      Packet_CanCast = 5,
      Packet_CanGetCookieForPInvokeCalliSig = 7,
      Packet_CanGetVarArgsHandle = 8,
      Packet_CanInline = 9,
      //Packet_CanInlineTypeCheckWithObjectVTable = 10,
      //Packet_CanSkipMethodVerification = 11,
      Packet_CanTailCall = 12,
      //Retired4 = 13,
      //Retired3 = 14,
      Packet_ConstructStringLiteral = 15,
      Packet_EmbedClassHandle = 16,
      Packet_EmbedFieldHandle = 17,
      Packet_EmbedGenericHandle = 18,
      Packet_EmbedMethodHandle = 19,
      Packet_EmbedModuleHandle = 20,
      Packet_EmptyStringLiteral = 21,
      Packet_ErrorList = 22,
      Packet_FindCallSiteSig = 23,
      //Retired7 = 24,
      Packet_FindSig = 25,
      Packet_GetAddressOfPInvokeFixup = 26,
      Packet_GetAddrOfCaptureThreadGlobal = 27,
      //Retired1 = 28,
      Packet_GetArgNext = 29,
      //Retired2 = 30,
      Packet_GetArrayInitializationData = 31,
      Packet_GetArrayRank = 32,
      //Packet_GetMethodBlockCounts = 33,
      Packet_GetBoundaries = 34,
      Packet_GetBoxHelper = 35,
      Packet_GetBuiltinClass = 36,
      Packet_GetCallInfo = 37,
      Packet_GetCastingHelper = 38,
      Packet_GetChildType = 39,
      Packet_GetClassAlignmentRequirement = 40,
      Packet_GetClassAttribs = 41,
      Packet_GetClassDomainID = 42,
      Packet_GetClassGClayout = 43,
      Packet_GetClassModuleIdForStatics = 44,
      Packet_GetClassName = 45,
      Packet_GetClassNumInstanceFields = 46,
      Packet_GetClassSize = 47,
      Packet_GetCookieForPInvokeCalliSig = 48,
      Packet_GetDelegateCtor = 49,
      Packet_GetEEInfo = 50,
      Packet_GetEHinfo = 51,
      Packet_GetFieldAddress = 52,
      Packet_GetFieldClass = 53,
      Packet_GetFieldInClass = 54,
      Packet_GetFieldInfo = 55,
      Packet_GetFieldName = 56,
      Packet_GetFieldOffset = 57,
      Packet_GetFieldThreadLocalStoreID = 58,
      Packet_GetFieldType = 59,
      Packet_GetFunctionEntryPoint = 60,
      Packet_GetFunctionFixedEntryPoint = 61,
      Packet_GetGSCookie = 62,
      Packet_GetHelperFtn = 63,
      Packet_GetHelperName = 64,
      Packet_GetInlinedCallFrameVptr = 65,
      Packet_GetArrayIntrinsicID = 66,
      Packet_GetJitTimeLogFilename = 67,
      Packet_GetJustMyCodeHandle = 68,
      Packet_GetLocationOfThisType = 69,
      Packet_GetMethodAttribs = 70,
      Packet_GetMethodClass = 71,
      Packet_GetMethodDefFromMethod = 72,
      Packet_GetMethodHash = 73,
      Packet_GetMethodInfo = 74,
      Packet_GetMethodName = 75,
      Packet_GetMethodSig = 76,
      Packet_GetMethodSync = 77,
      Packet_GetMethodVTableOffset = 78,
      Packet_GetNewArrHelper = 79,
      Packet_GetNewHelper = 80,
      Packet_GetParentType = 81,
      //Packet_GetPInvokeUnmanagedTarget = 82,
      Packet_GetProfilingHandle = 83,
      Packet_GetRelocTypeHint = 84,
      //Packet_GetSecurityPrologHelper = 85,
      Packet_GetSharedCCtorHelper = 86,
      //Packet_GetTailCallCopyArgsThunk = 87,
      Packet_GetThreadTLSIndex = 88,
      Packet_GetTokenTypeAsHandle = 89,
      Packet_GetTypeForBox = 90,
      Packet_GetTypeForPrimitiveValueClass = 91,
      Packet_GetUnBoxHelper = 92,
      Packet_GetUnmanagedCallConv = 94,
      Packet_GetVarArgsHandle = 95,
      Packet_GetVars = 96,
      Packet_InitClass = 97,
      //Packet_InitConstraintsForVerification = 98,
      Packet_IsCompatibleDelegate = 99,
      //Packet_IsInstantiationOfVerifiedGeneric = 100,
      Packet_IsSDArray = 101,
      //Packet_IsStructRequiringStackAllocRetBuf = 102,
      Packet_IsValidStringRef = 103,
      //Retired6 = 104,
      Packet_IsValueClass = 105,
      //Packet_IsWriteBarrierHelperRequired = 106,
      Packet_MergeClasses = 107,
      Packet_PInvokeMarshalingRequired = 108,
      Packet_ResolveToken = 109,
      Packet_SatisfiesClassConstraints = 110,
      Packet_SatisfiesMethodConstraints = 111,
      Packet_DoesFieldBelongToClass = 112,
      PacketCR_AddressMap = 113,
      PacketCR_AllocGCInfo = 114,
      PacketCR_AllocMem = 115,
      PacketCR_CallLog = 116,
      PacketCR_ClassMustBeLoadedBeforeCodeIsRun = 117,
      PacketCR_CompileMethod = 118,
      PacketCR_MessageLog = 119,
      PacketCR_MethodMustBeLoadedBeforeCodeIsRun = 120,
      PacketCR_ProcessName = 121,
      PacketCR_RecordRelocation = 122,
      PacketCR_ReportFatalError = 123,
      PacketCR_ReportInliningDecision = 124,
      PacketCR_ReportTailCallDecision = 125,
      PacketCR_SetBoundaries = 126,
      PacketCR_SetEHcount = 127,
      PacketCR_SetEHinfo = 128,
      PacketCR_SetMethodAttribs = 129,
      PacketCR_SetVars = 130,
      //Packet_AllocMethodBlockCounts = 131,
      PacketCR_AllocUnwindInfo = 132,
      PacketCR_ReserveUnwindInfo = 133,
      Packet_FilterException = 134,
      //Packet_HandleException = 135,
      //Retired9 = 136,
      Packet_IsFieldStatic = 137,
      PacketCR_AssertLog = 138,
      Packet_GetArgClass = 139,
      Packet_GetArgType = 140,
      //Retired5 = 141,
      Packet_CheckMethodModifier = 142,
      Packet_CompileMethod = 143,
      Packet_IsValidToken = 144,
      Packet_FindNameOfToken = 145,
      //PacketCR_RecordCallSite = 146,
      Packet_GetLazyStringLiteralHelper = 147,
      Packet_IsIntrinsicType = 148,
      Packet_AppendClassName = 149,
      Packet_GetReadyToRunHelper = 150,
      Packet_GetIntConfigValue = 151,
      Packet_GetStringConfigValue = 152,
      Packet_GetAddressOfPInvokeTarget = 153,
      Packet_GetJitFlags = 154,
      Packet_IsDelegateCreationAllowed = 155,
      Packet_GetSystemVAmd64PassStructInRegisterDescriptor = 156,
      Packet_GetReadyToRunDelegateCtorHelper = 157,
      Packet_TryResolveToken = 158,
      Packet_GetHFAType = 159,
      Packet_ResolveVirtualMethod = 160,
      Packet_GetMethodNameFromMetadata = 161,
      Packet_GetDefaultEqualityComparerClass = 162,
      Packet_CompareTypesForCast = 163,
      Packet_CompareTypesForEquality = 164,
      Packet_GetUnboxedEntry = 165,
      Packet_GetClassNameFromMetadata = 166,
      Packet_GetTypeInstantiationArgument = 167,
      Packet_GetTypeForPrimitiveNumericClass = 168,
      Packet_ConvertPInvokeCalliToCall = 169,
      Packet_GetHeapClassSize = 170,
      Packet_CanAllocateOnStack = 171,
      Packet_GetStaticFieldCurrentClass = 172,
      Packet_CanInlineTypeCheck = 173,
      Packet_IsMoreSpecificType = 174,
      Packet_GetStringLiteral = 175,
      PacketCR_SetPatchpointInfo = 176,
      Packet_GetOSRInfo = 177,
      Packet_GetTailCallHelpers = 178,
      PacketCR_RecordCallSiteWithSignature = 179,
      PacketCR_RecordCallSiteWithoutSignature = 180,
      Packet_GetMethodModule = 181,
      //Retired10 = 182,
      Packet_GetExpectedTargetArchitecture = 183,
      Packet_SigInstHandleMap = 184,
      PacketCR_CrSigInstHandleMap = 185,
      Packet_AllocPgoInstrumentationBySchema = 186,
      Packet_GetPgoInstrumentationResults = 187,
      Packet_GetDefaultComparerClass = 188,
      Packet_GetClassModule = 189,
      Packet_GetModuleAssembly = 190,
      Packet_GetAssemblyName = 191,
      Packet_IsIntrinsic = 192,
      Packet_UpdateEntryPointForTailCall = 193,
  };
  
  void SetDebugDumpVariables();
  
  #endif // _MethodContext
  