Spmi source code cleaning (dotnet/coreclr#12378)
authorSergey Andreenko <seandree@microsoft.com>
Wed, 21 Jun 2017 07:27:08 +0000 (00:27 -0700)
committerGitHub <noreply@github.com>
Wed, 21 Jun 2017 07:27:08 +0000 (00:27 -0700)
* fix pointer names in CORINFO_RESOLVED_TOKENin

* Remove exceptionCode from Agnostic_CORINFO_RESOLVED_TOKENout

The target if to do Agnostic_CORINFO_RESOLVED_TOKEN =
Agnostic_CORINFO_RESOLVED_TOKENin + Agnostic_CORINFO_RESOLVED_TOKENout

* Agnostic_CORINFO_RESOLVED_TOKEN = Agnostic_CORINFO_RESOLVED_TOKENin + Agnostic_CORINFO_RESOLVED_TOKENout

* spmi cleaning for ResolvedToken.

It is only the first part of changes. I am trying to delete as many code
as I can, because for now it is bad pain to make changes in this files.

Commit migrated from https://github.com/dotnet/coreclr/commit/9121670c7a3f927c4a7a4b9711fdc904eeef281c

src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
src/coreclr/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h [new file with mode: 0644]

index 6e5f016..2ee465d 100644 (file)
@@ -140,9 +140,9 @@ LWM(IsValueClass, DWORDLONG, DWORD)
 LWM(IsWriteBarrierHelperRequired, DWORDLONG, DWORD)
 LWM(MergeClasses, DLDL, DWORDLONG)
 LWM(PInvokeMarshalingRequired, Agnostic_PInvokeMarshalingRequired, DWORD)
-LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout)
+LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)
 LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethod, DWORDLONG)
-LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout)
+LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue)
 LWM(SatisfiesClassConstraints, DWORDLONG, DWORD)
 LWM(SatisfiesMethodConstraints, DLDL, DWORD)
 LWM(ShouldEnforceCallvirtRestriction, DWORDLONG, DWORD)
index 6ee3806..8f6b691 100644 (file)
@@ -14,6 +14,7 @@
 #include "compileresult.h"
 #include "lightweightmap.h"
 #include "callutils.h"
+#include "spmirecordhelper.h"
 
 struct
 {
@@ -1276,64 +1277,46 @@ CorInfoInline MethodContext::repCanInline(CORINFO_METHOD_HANDLE callerHnd,
 void MethodContext::recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode)
 {
     if (ResolveToken == nullptr)
-        ResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout>();
+        ResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue>();
 
     Agnostic_CORINFO_RESOLVED_TOKENin key;
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to
                                                                  // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_RESOLVED_TOKENout value;
-
-    key.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.token        = (DWORD)pResolvedToken->token;
-    key.tokenType    = (DWORD)pResolvedToken->tokenType;
-
-    value.hClass  = (DWORDLONG)pResolvedToken->hClass;
-    value.hMethod = (DWORDLONG)pResolvedToken->hMethod;
-    value.hField  = (DWORDLONG)pResolvedToken->hField;
-    value.pTypeSpec_Index =
-        (DWORD)ResolveToken->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    value.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    value.pMethodSpec_Index =
-        (DWORD)ResolveToken->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    value.cbMethodSpec  = (DWORD)pResolvedToken->cbMethodSpec;
+    key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
+
+    ResolveTokenValue value;
+    value.tokenOut      = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, ResolveToken);
     value.exceptionCode = (DWORD)exceptionCode;
 
     ResolveToken->Add(key, value);
     DEBUG_REC(dmpResolveToken(key, value));
 }
-void MethodContext::dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin&  key,
-                                    const Agnostic_CORINFO_RESOLVED_TOKENout& value)
+void MethodContext::dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const ResolveTokenValue& value)
 {
     printf("ResolveToken key tc-%016llX ts-%016llX tok-%08X tt-%u", key.tokenContext, key.tokenScope, key.token,
            key.tokenType);
-    printf(", value cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u excp-%08X", value.hClass,
-           value.hMethod, value.hField, value.pTypeSpec_Index, value.cbTypeSpec, value.pMethodSpec_Index,
-           value.cbMethodSpec, value.exceptionCode);
+    printf(", value cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u excp-%08X", value.tokenOut.hClass,
+           value.tokenOut.hMethod, value.tokenOut.hField, value.tokenOut.pTypeSpec_Index, value.tokenOut.cbTypeSpec,
+           value.tokenOut.pMethodSpec_Index, value.tokenOut.cbMethodSpec, value.exceptionCode);
 }
 void MethodContext::repResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD* exceptionCode)
 {
     Agnostic_CORINFO_RESOLVED_TOKENin key;
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to
                                                                  // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_RESOLVED_TOKENout value;
-
-    key.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.token        = (DWORD)pResolvedToken->token;
-    key.tokenType    = (DWORD)pResolvedToken->tokenType;
+    key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
 
     AssertCodeMsg(ResolveToken->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %x", pResolvedToken->token);
 
-    value = ResolveToken->Get(key);
+    ResolveTokenValue value = ResolveToken->Get(key);
 
-    pResolvedToken->hClass       = (CORINFO_CLASS_HANDLE)value.hClass;
-    pResolvedToken->hMethod      = (CORINFO_METHOD_HANDLE)value.hMethod;
-    pResolvedToken->hField       = (CORINFO_FIELD_HANDLE)value.hField;
-    pResolvedToken->pTypeSpec    = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.pTypeSpec_Index);
-    pResolvedToken->cbTypeSpec   = (ULONG)value.cbTypeSpec;
-    pResolvedToken->pMethodSpec  = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.pMethodSpec_Index);
-    pResolvedToken->cbMethodSpec = (ULONG)value.cbMethodSpec;
+    pResolvedToken->hClass       = (CORINFO_CLASS_HANDLE)value.tokenOut.hClass;
+    pResolvedToken->hMethod      = (CORINFO_METHOD_HANDLE)value.tokenOut.hMethod;
+    pResolvedToken->hField       = (CORINFO_FIELD_HANDLE)value.tokenOut.hField;
+    pResolvedToken->pTypeSpec    = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.tokenOut.pTypeSpec_Index);
+    pResolvedToken->cbTypeSpec   = (ULONG)value.tokenOut.cbTypeSpec;
+    pResolvedToken->pMethodSpec  = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.tokenOut.pMethodSpec_Index);
+    pResolvedToken->cbMethodSpec = (ULONG)value.tokenOut.cbMethodSpec;
     *exceptionCode               = (DWORD)value.exceptionCode;
 
     DEBUG_REP(dmpResolveToken(key, value));
@@ -1342,75 +1325,49 @@ void MethodContext::repResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWOR
 void MethodContext::recTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool success)
 {
     if (TryResolveToken == nullptr)
-        TryResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout>();
+        TryResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue>();
 
     Agnostic_CORINFO_RESOLVED_TOKENin key;
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to
                                                                  // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_RESOLVED_TOKENout value;
-
-    key.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.token        = (DWORD)pResolvedToken->token;
-    key.tokenType    = (DWORD)pResolvedToken->tokenType;
-
-    value.hClass  = (DWORDLONG)pResolvedToken->hClass;
-    value.hMethod = (DWORDLONG)pResolvedToken->hMethod;
-    value.hField  = (DWORDLONG)pResolvedToken->hField;
-    value.pTypeSpec_Index =
-        (DWORD)ResolveToken->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    value.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    value.pMethodSpec_Index =
-        (DWORD)ResolveToken->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    value.cbMethodSpec  = (DWORD)pResolvedToken->cbMethodSpec;
-    value.exceptionCode = success ? 0 : 1;
+    key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
+
+    TryResolveTokenValue value;
+
+    value.tokenOut = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, ResolveToken);
+    value.success  = success ? 0 : 1;
 
     TryResolveToken->Add(key, value);
     DEBUG_REC(dmpTryResolveToken(key, value));
 }
-void MethodContext::dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin&  key,
-                                       const Agnostic_CORINFO_RESOLVED_TOKENout& value)
+void MethodContext::dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const TryResolveTokenValue& value)
 {
     printf("TryResolveToken key tc-%016llX ts-%016llX tok-%08X tt-%u", key.tokenContext, key.tokenScope, key.token,
            key.tokenType);
-    printf(", value cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u failed-%u", value.hClass,
-           value.hMethod, value.hField, value.pTypeSpec_Index, value.cbTypeSpec, value.pMethodSpec_Index,
-           value.cbMethodSpec, value.exceptionCode);
+    printf(", value cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u failed-%u", value.tokenOut.hClass,
+           value.tokenOut.hMethod, value.tokenOut.hField, value.tokenOut.pTypeSpec_Index, value.tokenOut.cbTypeSpec,
+           value.tokenOut.pMethodSpec_Index, value.tokenOut.cbMethodSpec, value.success);
 }
 bool MethodContext::repTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken)
 {
     Agnostic_CORINFO_RESOLVED_TOKENin key;
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to
                                                                  // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_RESOLVED_TOKENout value;
 
-    key.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.token        = (DWORD)pResolvedToken->token;
-    key.tokenType    = (DWORD)pResolvedToken->tokenType;
+    key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
 
-    // Best-effort: if the `tryResolveToken` map is missing or the key is not found therein,
-    // fall back to the `resolveToken` map.
-    if (TryResolveToken != nullptr && TryResolveToken->GetIndex(key) != -1)
-    {
-        value = TryResolveToken->Get(key);
-    }
-    else
-    {
-        AssertCodeMsg(ResolveToken->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %x", pResolvedToken->token);
-        value = ResolveToken->Get(key);
-    }
+    TryResolveTokenValue value = TryResolveToken->Get(key);
 
-    pResolvedToken->hClass       = (CORINFO_CLASS_HANDLE)value.hClass;
-    pResolvedToken->hMethod      = (CORINFO_METHOD_HANDLE)value.hMethod;
-    pResolvedToken->hField       = (CORINFO_FIELD_HANDLE)value.hField;
-    pResolvedToken->pTypeSpec    = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.pTypeSpec_Index);
-    pResolvedToken->cbTypeSpec   = (ULONG)value.cbTypeSpec;
-    pResolvedToken->pMethodSpec  = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.pMethodSpec_Index);
-    pResolvedToken->cbMethodSpec = (ULONG)value.cbMethodSpec;
+    pResolvedToken->hClass       = (CORINFO_CLASS_HANDLE)value.tokenOut.hClass;
+    pResolvedToken->hMethod      = (CORINFO_METHOD_HANDLE)value.tokenOut.hMethod;
+    pResolvedToken->hField       = (CORINFO_FIELD_HANDLE)value.tokenOut.hField;
+    pResolvedToken->pTypeSpec    = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.tokenOut.pTypeSpec_Index);
+    pResolvedToken->cbTypeSpec   = (ULONG)value.tokenOut.cbTypeSpec;
+    pResolvedToken->pMethodSpec  = (PCCOR_SIGNATURE)ResolveToken->GetBuffer(value.tokenOut.pMethodSpec_Index);
+    pResolvedToken->cbMethodSpec = (ULONG)value.tokenOut.cbMethodSpec;
 
     DEBUG_REP(dmpTryResolveToken(key, value));
-    return (DWORD)value.exceptionCode == 0;
+    return (DWORD)value.success == 0;
 }
 
 void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
@@ -1426,57 +1383,32 @@ void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
     Agnostic_GetCallInfo key;
     ZeroMemory(&key, sizeof(Agnostic_GetCallInfo)); // We use the input structs as a key and use memcmp to compare.. so
                                                     // we need to zero out padding too
-    Agnostic_CORINFO_CALL_INFO value;
+    key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetCallInfo);
 
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)GetCallInfo->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)GetCallInfo->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
     if (pConstrainedResolvedToken != nullptr)
     {
-        key.ConstrainedResolvedToken.tokenContext = (DWORDLONG)pConstrainedResolvedToken->tokenContext;
-        key.ConstrainedResolvedToken.tokenScope   = (DWORDLONG)pConstrainedResolvedToken->tokenScope;
-        key.ConstrainedResolvedToken.token        = (DWORD)pConstrainedResolvedToken->token;
-        key.ConstrainedResolvedToken.tokenType    = (DWORD)pConstrainedResolvedToken->tokenType;
-        key.ConstrainedResolvedToken.hClass       = (DWORDLONG)pConstrainedResolvedToken->hClass;
-        key.ConstrainedResolvedToken.hMethod      = (DWORDLONG)pConstrainedResolvedToken->hMethod;
-        key.ConstrainedResolvedToken.hField       = (DWORDLONG)pConstrainedResolvedToken->hField;
-        key.ConstrainedResolvedToken.typeSpec_Index =
-            (DWORD)GetCallInfo->AddBuffer((unsigned char*)pConstrainedResolvedToken->pTypeSpec,
-                                          pConstrainedResolvedToken->cbTypeSpec);
-        key.ConstrainedResolvedToken.cbTypeSpec = (DWORD)pConstrainedResolvedToken->cbTypeSpec;
-        key.ConstrainedResolvedToken.methodSpec_Index =
-            (DWORD)GetCallInfo->AddBuffer((unsigned char*)pConstrainedResolvedToken->pMethodSpec,
-                                          pConstrainedResolvedToken->cbMethodSpec);
-        key.ConstrainedResolvedToken.cbMethodSpec = (DWORD)pConstrainedResolvedToken->cbMethodSpec;
+        key.ConstrainedResolvedToken =
+            SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pConstrainedResolvedToken, GetCallInfo);
     }
     else
     {
-        key.ConstrainedResolvedToken.tokenContext     = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.tokenScope       = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.token            = (DWORD)0;
-        key.ConstrainedResolvedToken.tokenType        = (DWORD)0;
-        key.ConstrainedResolvedToken.hClass           = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.hMethod          = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.hField           = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.typeSpec_Index   = (DWORD)0;
-        key.ConstrainedResolvedToken.cbTypeSpec       = (DWORD)0;
-        key.ConstrainedResolvedToken.methodSpec_Index = (DWORD)0;
-        key.ConstrainedResolvedToken.cbMethodSpec     = (DWORD)0;
+        key.ConstrainedResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.inValue.token              = (DWORD)0;
+        key.ConstrainedResolvedToken.inValue.tokenType          = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.hClass            = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.hField            = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
     }
 
     key.callerHandle = (DWORDLONG)callerHandle;
     key.flags        = (DWORD)flags;
 
+    Agnostic_CORINFO_CALL_INFO value;
     if (exceptionCode == 0)
     {
         value.hMethod                    = (DWORDLONG)pResult->hMethod;
@@ -1610,16 +1542,17 @@ void MethodContext::dmpGetCallInfo(const Agnostic_GetCallInfo& key, const Agnost
            " rt{tc-%016llX ts-%016llX tok-%08X tt-%u cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u}"
            " crt{tc-%016llX ts-%016llX tok-%08X tt-%u cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u mi-%u ms-%u}"
            " ch-%016llX flg-%08X",
-           key.ResolvedToken.tokenContext, key.ResolvedToken.tokenScope, key.ResolvedToken.token,
-           key.ResolvedToken.tokenType, key.ResolvedToken.hClass, key.ResolvedToken.hMethod, key.ResolvedToken.hField,
-           key.ResolvedToken.typeSpec_Index, key.ResolvedToken.cbTypeSpec, key.ResolvedToken.methodSpec_Index,
-           key.ResolvedToken.cbMethodSpec, key.ConstrainedResolvedToken.tokenContext,
-           key.ConstrainedResolvedToken.tokenScope, key.ConstrainedResolvedToken.token,
-           key.ConstrainedResolvedToken.tokenType, key.ConstrainedResolvedToken.hClass,
-           key.ConstrainedResolvedToken.hMethod, key.ConstrainedResolvedToken.hField,
-           key.ConstrainedResolvedToken.typeSpec_Index, key.ConstrainedResolvedToken.cbTypeSpec,
-           key.ConstrainedResolvedToken.methodSpec_Index, key.ConstrainedResolvedToken.cbMethodSpec, key.callerHandle,
-           key.flags);
+           key.ResolvedToken.inValue.tokenContext, key.ResolvedToken.inValue.tokenScope,
+           key.ResolvedToken.inValue.token, key.ResolvedToken.inValue.tokenType, key.ResolvedToken.outValue.hClass,
+           key.ResolvedToken.outValue.hMethod, key.ResolvedToken.outValue.hField,
+           key.ResolvedToken.outValue.pTypeSpec_Index, key.ResolvedToken.outValue.cbTypeSpec,
+           key.ResolvedToken.outValue.pMethodSpec_Index, key.ResolvedToken.outValue.cbMethodSpec,
+           key.ConstrainedResolvedToken.inValue.tokenContext, key.ConstrainedResolvedToken.inValue.tokenScope,
+           key.ConstrainedResolvedToken.inValue.token, key.ConstrainedResolvedToken.inValue.tokenType,
+           key.ConstrainedResolvedToken.outValue.hClass, key.ConstrainedResolvedToken.outValue.hMethod,
+           key.ConstrainedResolvedToken.outValue.hField, key.ConstrainedResolvedToken.outValue.pTypeSpec_Index,
+           key.ConstrainedResolvedToken.outValue.cbTypeSpec, key.ConstrainedResolvedToken.outValue.pMethodSpec_Index,
+           key.ConstrainedResolvedToken.outValue.cbMethodSpec, key.callerHandle, key.flags);
     printf(", value mth-%016llX, mf-%08X cf-%08X"
            " sig{flg-%08X na-%u cc-%u ci-%u mc-%u mi-%u args-%016llX scp-%016llX tok-%08X}"
            " vsig{flg-%08X na-%u cc-%u ci-%u mc-%u mi-%u args-%016llX scp-%016llX tok-%08X}"
@@ -1644,59 +1577,35 @@ void MethodContext::repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
     Agnostic_GetCallInfo key;
     ZeroMemory(&key, sizeof(Agnostic_GetCallInfo)); // We use the input structs as a key and use memcmp to compare.. so
                                                     // we need to zero out padding too
-    Agnostic_CORINFO_CALL_INFO value;
-
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)GetCallInfo->Contains((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)GetCallInfo->Contains((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
+    key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetCallInfo);
     if (pConstrainedResolvedToken != nullptr)
     {
-        key.ConstrainedResolvedToken.tokenContext = (DWORDLONG)pConstrainedResolvedToken->tokenContext;
-        key.ConstrainedResolvedToken.tokenScope   = (DWORDLONG)pConstrainedResolvedToken->tokenScope;
-        key.ConstrainedResolvedToken.token        = (DWORD)pConstrainedResolvedToken->token;
-        key.ConstrainedResolvedToken.tokenType    = (DWORD)pConstrainedResolvedToken->tokenType;
-        key.ConstrainedResolvedToken.hClass       = (DWORDLONG)pConstrainedResolvedToken->hClass;
-        key.ConstrainedResolvedToken.hMethod      = (DWORDLONG)pConstrainedResolvedToken->hMethod;
-        key.ConstrainedResolvedToken.hField       = (DWORDLONG)pConstrainedResolvedToken->hField;
-        key.ConstrainedResolvedToken.typeSpec_Index =
-            (DWORD)GetCallInfo->Contains((unsigned char*)pConstrainedResolvedToken->pTypeSpec,
-                                         pConstrainedResolvedToken->cbTypeSpec);
-        key.ConstrainedResolvedToken.cbTypeSpec = (DWORD)pConstrainedResolvedToken->cbTypeSpec;
-        key.ConstrainedResolvedToken.methodSpec_Index =
-            (DWORD)GetCallInfo->Contains((unsigned char*)pConstrainedResolvedToken->pMethodSpec,
-                                         pConstrainedResolvedToken->cbMethodSpec);
-        key.ConstrainedResolvedToken.cbMethodSpec = (DWORD)pConstrainedResolvedToken->cbMethodSpec;
+        key.ConstrainedResolvedToken =
+            SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pConstrainedResolvedToken, GetCallInfo);
     }
     else
     {
-        key.ConstrainedResolvedToken.tokenContext     = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.tokenScope       = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.token            = (DWORD)0;
-        key.ConstrainedResolvedToken.tokenType        = (DWORD)0;
-        key.ConstrainedResolvedToken.hClass           = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.hMethod          = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.hField           = (DWORDLONG)0;
-        key.ConstrainedResolvedToken.typeSpec_Index   = (DWORD)0;
-        key.ConstrainedResolvedToken.cbTypeSpec       = (DWORD)0;
-        key.ConstrainedResolvedToken.methodSpec_Index = (DWORD)0;
-        key.ConstrainedResolvedToken.cbMethodSpec     = (DWORD)0;
+        key.ConstrainedResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.inValue.token              = (DWORD)0;
+        key.ConstrainedResolvedToken.inValue.tokenType          = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.hClass            = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.hField            = (DWORDLONG)0;
+        key.ConstrainedResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+        key.ConstrainedResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
     }
     key.callerHandle = (DWORDLONG)callerHandle;
     key.flags        = (DWORD)flags;
 
     AssertCodeMsg(GetCallInfo->GetIndex(key) != -1, EXCEPTIONCODE_MC,
-                  "Didn't find %08x, %016llx. Probably a missing exception in GetCallInfo", key.ResolvedToken.token,
-                  key.ResolvedToken.hClass);
+                  "Didn't find %08x, %016llx. Probably a missing exception in GetCallInfo",
+                  key.ResolvedToken.inValue.token, key.ResolvedToken.outValue.hClass);
+
+    Agnostic_CORINFO_CALL_INFO value;
+
     value = GetCallInfo->Get(key);
 
     pResult->hMethod                    = (CORINFO_METHOD_HANDLE)value.hMethod;
@@ -1812,10 +1721,10 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH
                 CORINFO_RESOLVED_TOKEN resolvedToken;
                 DWORD                  exceptionCode;
 
-                resolvedToken.tokenContext = (CORINFO_CONTEXT_HANDLE)key.ResolvedToken.tokenContext;
-                resolvedToken.tokenScope   = (CORINFO_MODULE_HANDLE)key.ResolvedToken.tokenScope;
-                resolvedToken.token        = (mdToken)key.ResolvedToken.token;
-                resolvedToken.tokenType    = (CorInfoTokenKind)key.ResolvedToken.tokenType;
+                resolvedToken.tokenContext = (CORINFO_CONTEXT_HANDLE)key.ResolvedToken.inValue.tokenContext;
+                resolvedToken.tokenScope   = (CORINFO_MODULE_HANDLE)key.ResolvedToken.inValue.tokenScope;
+                resolvedToken.token        = (mdToken)key.ResolvedToken.inValue.token;
+                resolvedToken.tokenType    = (CorInfoTokenKind)key.ResolvedToken.inValue.tokenType;
 
                 repResolveToken(&resolvedToken, &exceptionCode);
 
@@ -1826,15 +1735,17 @@ void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodH
                 CORINFO_RESOLVED_TOKEN  constrainedResolvedToken;
                 CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken = nullptr;
 
-                if (key.ConstrainedResolvedToken.tokenContext != 0 && key.ConstrainedResolvedToken.tokenScope != 0)
+                if (key.ConstrainedResolvedToken.inValue.tokenContext != 0 &&
+                    key.ConstrainedResolvedToken.inValue.tokenScope != 0)
                 {
                     constrainedResolvedToken.tokenContext =
-                        (CORINFO_CONTEXT_HANDLE)key.ConstrainedResolvedToken.tokenContext;
+                        (CORINFO_CONTEXT_HANDLE)key.ConstrainedResolvedToken.inValue.tokenContext;
                     constrainedResolvedToken.tokenScope =
-                        (CORINFO_MODULE_HANDLE)key.ConstrainedResolvedToken.tokenScope;
-                    constrainedResolvedToken.token     = (mdToken)key.ConstrainedResolvedToken.token;
-                    constrainedResolvedToken.tokenType = (CorInfoTokenKind)key.ConstrainedResolvedToken.tokenType;
-                    pConstrainedResolvedToken          = &constrainedResolvedToken;
+                        (CORINFO_MODULE_HANDLE)key.ConstrainedResolvedToken.inValue.tokenScope;
+                    constrainedResolvedToken.token = (mdToken)key.ConstrainedResolvedToken.inValue.token;
+                    constrainedResolvedToken.tokenType =
+                        (CorInfoTokenKind)key.ConstrainedResolvedToken.inValue.tokenType;
+                    pConstrainedResolvedToken = &constrainedResolvedToken;
 
                     repResolveToken(pConstrainedResolvedToken, &exceptionCode);
                 }
@@ -3133,26 +3044,26 @@ void MethodContext::recGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
     ZeroMemory(&key, sizeof(Agnostic_GetNewHelper)); // We use the input structs as a key and use memcmp to compare.. so
                                                      // we need to zero out padding too
 
-    key.ResolvedToken.tokenContext     = (DWORDLONG)0;
-    key.ResolvedToken.tokenScope       = (DWORDLONG)0;
-    key.ResolvedToken.token            = (DWORD)0;
-    key.ResolvedToken.tokenType        = (DWORD)0;
-    key.ResolvedToken.hClass           = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod          = (DWORDLONG)0;
-    key.ResolvedToken.hField           = (DWORDLONG)0;
-    key.ResolvedToken.typeSpec_Index   = (DWORD)0;
-    key.ResolvedToken.cbTypeSpec       = (DWORD)0;
-    key.ResolvedToken.methodSpec_Index = (DWORD)0;
-    key.ResolvedToken.cbMethodSpec     = (DWORD)0;
-    key.callerHandle                   = (DWORDLONG)callerHandle;
+    key.ResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+    key.ResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+    key.ResolvedToken.inValue.token              = (DWORD)0;
+    key.ResolvedToken.inValue.tokenType          = (DWORD)0;
+    key.ResolvedToken.outValue.hClass            = (DWORDLONG)pResolvedToken->hClass;
+    key.ResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+    key.ResolvedToken.outValue.hField            = (DWORDLONG)0;
+    key.ResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.ResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+    key.ResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+    key.ResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
+    key.callerHandle                             = (DWORDLONG)callerHandle;
 
     GetNewHelper->Add(key, (DWORD)result);
     DEBUG_REC(dmpGetNewHelper(key, (DWORD)result));
 }
 void MethodContext::dmpGetNewHelper(const Agnostic_GetNewHelper& key, DWORD value)
 {
-    printf("GetNewHelper key cls-%016llX chan-%016llX, value res-%u", key.ResolvedToken.hClass, key.callerHandle,
-           value);
+    printf("GetNewHelper key cls-%016llX chan-%016llX, value res-%u", key.ResolvedToken.outValue.hClass,
+           key.callerHandle, value);
 }
 CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                                CORINFO_METHOD_HANDLE   callerHandle)
@@ -3161,23 +3072,23 @@ CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolved
     ZeroMemory(&key, sizeof(Agnostic_GetNewHelper)); // We use the input structs as a key and use memcmp to compare.. so
                                                      // we need to zero out padding too
 
-    key.ResolvedToken.tokenContext     = (DWORDLONG)0;
-    key.ResolvedToken.tokenScope       = (DWORDLONG)0;
-    key.ResolvedToken.token            = (DWORD)0;
-    key.ResolvedToken.tokenType        = (DWORD)0;
-    key.ResolvedToken.hClass           = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod          = (DWORDLONG)0;
-    key.ResolvedToken.hField           = (DWORDLONG)0;
-    key.ResolvedToken.typeSpec_Index   = (DWORD)0;
-    key.ResolvedToken.cbTypeSpec       = (DWORD)0;
-    key.ResolvedToken.methodSpec_Index = (DWORD)0;
-    key.ResolvedToken.cbMethodSpec     = (DWORD)0;
-    key.callerHandle                   = (DWORDLONG)callerHandle;
+    key.ResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+    key.ResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+    key.ResolvedToken.inValue.token              = (DWORD)0;
+    key.ResolvedToken.inValue.tokenType          = (DWORD)0;
+    key.ResolvedToken.outValue.hClass            = (DWORDLONG)pResolvedToken->hClass;
+    key.ResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+    key.ResolvedToken.outValue.hField            = (DWORDLONG)0;
+    key.ResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.ResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+    key.ResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+    key.ResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
+    key.callerHandle                             = (DWORDLONG)callerHandle;
 
     AssertCodeMsg(GetNewHelper != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX",
-                  (DWORDLONG)key.ResolvedToken.hClass);
+                  (DWORDLONG)key.ResolvedToken.outValue.hClass);
     AssertCodeMsg(GetNewHelper->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX",
-                  (DWORDLONG)key.ResolvedToken.hClass);
+                  (DWORDLONG)key.ResolvedToken.outValue.hClass);
     CorInfoHelpFunc value = (CorInfoHelpFunc)GetNewHelper->Get(key);
     DEBUG_REP(dmpGetNewHelper(key, value));
     return value;
@@ -3193,23 +3104,10 @@ void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN*       pResolve
     Agnostic_EmbedGenericHandle key;
     ZeroMemory(&key, sizeof(Agnostic_EmbedGenericHandle)); // We use the input structs as a key and use memcmp to
                                                            // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_GENERICHANDLE_RESULT value;
-
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)EmbedGenericHandle->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)EmbedGenericHandle->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.fEmbedParent               = (DWORD)fEmbedParent;
+    key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle);
+    key.fEmbedParent  = (DWORD)fEmbedParent;
 
+    Agnostic_CORINFO_GENERICHANDLE_RESULT value;
     value.lookup.lookupKind.needsRuntimeLookup = (DWORD)pResult->lookup.lookupKind.needsRuntimeLookup;
     value.lookup.lookupKind.runtimeLookupKind  = (DWORD)pResult->lookup.lookupKind.runtimeLookupKind;
     if (pResult->lookup.lookupKind.needsRuntimeLookup)
@@ -3251,10 +3149,11 @@ void MethodContext::dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle&
 {
     printf("EmbedGenericHandle key rt{tokCon-%016llX tokScp-%016llX tok-%08X tokTyp-%08X cls-%016llX ftn-%016llX "
            "fld-%016llX tsi-%u cbts-%u msi-%u cbms-%u} emb-%u",
-           key.ResolvedToken.tokenContext, key.ResolvedToken.tokenScope, key.ResolvedToken.token,
-           key.ResolvedToken.tokenType, key.ResolvedToken.hClass, key.ResolvedToken.hMethod, key.ResolvedToken.hField,
-           key.ResolvedToken.typeSpec_Index, key.ResolvedToken.cbTypeSpec, key.ResolvedToken.methodSpec_Index,
-           key.ResolvedToken.cbMethodSpec, key.fEmbedParent);
+           key.ResolvedToken.inValue.tokenContext, key.ResolvedToken.inValue.tokenScope,
+           key.ResolvedToken.inValue.token, key.ResolvedToken.inValue.tokenType, key.ResolvedToken.outValue.hClass,
+           key.ResolvedToken.outValue.hMethod, key.ResolvedToken.outValue.hField,
+           key.ResolvedToken.outValue.pTypeSpec_Index, key.ResolvedToken.outValue.cbTypeSpec,
+           key.ResolvedToken.outValue.pMethodSpec_Index, key.ResolvedToken.outValue.cbMethodSpec, key.fEmbedParent);
     printf(", value nrl-%u rlk-%u", value.lookup.lookupKind.needsRuntimeLookup,
            value.lookup.lookupKind.runtimeLookupKind);
     if (value.lookup.lookupKind.needsRuntimeLookup)
@@ -3279,25 +3178,14 @@ void MethodContext::repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN*       pResolve
     Agnostic_EmbedGenericHandle key;
     ZeroMemory(&key, sizeof(Agnostic_EmbedGenericHandle)); // We use the input structs as a key and use memcmp to
                                                            // compare.. so we need to zero out padding too
-    Agnostic_CORINFO_GENERICHANDLE_RESULT value;
 
     AssertCodeMsg(EmbedGenericHandle != nullptr, EXCEPTIONCODE_MC, "Encountered an empty LWM while looking for ...");
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)EmbedGenericHandle->Contains((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)EmbedGenericHandle->Contains((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.fEmbedParent               = (DWORD)fEmbedParent;
+    key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle);
+    key.fEmbedParent  = (DWORD)fEmbedParent;
 
     AssertCodeMsg(EmbedGenericHandle->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find ...");
+
+    Agnostic_CORINFO_GENERICHANDLE_RESULT value;
     value = EmbedGenericHandle->Get(key);
 
     pResult->lookup.lookupKind.needsRuntimeLookup = value.lookup.lookupKind.needsRuntimeLookup != 0;
@@ -3463,23 +3351,24 @@ void MethodContext::recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedTok
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKEN)); // We use the input structs as a key and use memcmp to
                                                                // compare.. so we need to zero out padding too
 
-    key.tokenContext     = (DWORDLONG)0;
-    key.tokenScope       = (DWORDLONG)0;
-    key.token            = (DWORD)0;
-    key.tokenType        = (DWORD)0;
-    key.hClass           = (DWORDLONG)0;
-    key.hMethod          = (DWORDLONG)pResolvedToken->hMethod;
-    key.hField           = (DWORDLONG)pResolvedToken->hField;
-    key.typeSpec_Index   = (DWORD)0;
-    key.cbTypeSpec       = (DWORD)0;
-    key.methodSpec_Index = (DWORD)0;
-    key.cbMethodSpec     = (DWORD)0;
+    key.inValue.tokenContext       = (DWORDLONG)0;
+    key.inValue.tokenScope         = (DWORDLONG)0;
+    key.inValue.token              = (DWORD)0;
+    key.inValue.tokenType          = (DWORD)0;
+    key.outValue.hClass            = (DWORDLONG)0;
+    key.outValue.hMethod           = (DWORDLONG)pResolvedToken->hMethod;
+    key.outValue.hField            = (DWORDLONG)pResolvedToken->hField;
+    key.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.outValue.cbTypeSpec        = (DWORD)0;
+    key.outValue.pMethodSpec_Index = (DWORD)0;
+    key.outValue.cbMethodSpec      = (DWORD)0;
 
     GetTokenTypeAsHandle->Add(key, (DWORDLONG)result);
 }
 void MethodContext::dmpGetTokenTypeAsHandle(const Agnostic_CORINFO_RESOLVED_TOKEN& key, DWORDLONG value)
 {
-    printf("GetTokenTypeAsHandle key ftn-%016llX fld-%016llX, value cls-%016llX", key.hMethod, key.hField, value);
+    printf("GetTokenTypeAsHandle key ftn-%016llX fld-%016llX, value cls-%016llX", key.outValue.hMethod,
+           key.outValue.hField, value);
 }
 CORINFO_CLASS_HANDLE MethodContext::repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken)
 {
@@ -3487,17 +3376,17 @@ CORINFO_CLASS_HANDLE MethodContext::repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOK
     ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKEN)); // We use the input structs as a key and use memcmp to
                                                                // compare.. so we need to zero out padding too
 
-    key.tokenContext     = (DWORDLONG)0;
-    key.tokenScope       = (DWORDLONG)0;
-    key.token            = (DWORD)0;
-    key.tokenType        = (DWORD)0;
-    key.hClass           = (DWORDLONG)0;
-    key.hMethod          = (DWORDLONG)pResolvedToken->hMethod;
-    key.hField           = (DWORDLONG)pResolvedToken->hField;
-    key.typeSpec_Index   = (DWORD)0;
-    key.cbTypeSpec       = (DWORD)0;
-    key.methodSpec_Index = (DWORD)0;
-    key.cbMethodSpec     = (DWORD)0;
+    key.inValue.tokenContext       = (DWORDLONG)0;
+    key.inValue.tokenScope         = (DWORDLONG)0;
+    key.inValue.token              = (DWORD)0;
+    key.inValue.tokenType          = (DWORD)0;
+    key.outValue.hClass            = (DWORDLONG)0;
+    key.outValue.hMethod           = (DWORDLONG)pResolvedToken->hMethod;
+    key.outValue.hField            = (DWORDLONG)pResolvedToken->hField;
+    key.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.outValue.cbTypeSpec        = (DWORD)0;
+    key.outValue.pMethodSpec_Index = (DWORD)0;
+    key.outValue.cbMethodSpec      = (DWORD)0;
 
     CORINFO_CLASS_HANDLE value = (CORINFO_CLASS_HANDLE)GetTokenTypeAsHandle->Get(key);
     return value;
@@ -3513,24 +3402,11 @@ void MethodContext::recGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
     Agnostic_GetFieldInfo key;
     ZeroMemory(&key, sizeof(Agnostic_GetFieldInfo)); // Since dd has nested structs, and we use memcmp to compare, we
                                                      // need to zero out the padding bytes too
-    Agnostic_CORINFO_FIELD_INFO value;
-
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)GetFieldInfo->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)GetFieldInfo->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.callerHandle               = (DWORDLONG)callerHandle;
-    key.flags                      = (DWORD)flags;
+    key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetFieldInfo);
+    key.callerHandle  = (DWORDLONG)callerHandle;
+    key.flags         = (DWORD)flags;
 
+    Agnostic_CORINFO_FIELD_INFO value;
     value.fieldAccessor                 = (DWORD)pResult->fieldAccessor;
     value.fieldFlags                    = (DWORD)pResult->fieldFlags;
     value.helper                        = (DWORD)pResult->helper;
@@ -3552,10 +3428,11 @@ void MethodContext::dmpGetFieldInfo(const Agnostic_GetFieldInfo& key, const Agno
 {
     printf("GetFieldInfo key ch-%016llX flg-%08X rt{tc-%016llX ts-%016llX tok-%08X tt-%u cls-%016llX meth-%016llX "
            "fld-%016llX tsi-%u cbts-%u msi-%u cbms-%u}",
-           key.callerHandle, key.flags, key.ResolvedToken.tokenContext, key.ResolvedToken.tokenScope,
-           key.ResolvedToken.token, key.ResolvedToken.tokenType, key.ResolvedToken.hClass, key.ResolvedToken.hMethod,
-           key.ResolvedToken.hField, key.ResolvedToken.typeSpec_Index, key.ResolvedToken.cbTypeSpec,
-           key.ResolvedToken.methodSpec_Index, key.ResolvedToken.cbMethodSpec);
+           key.callerHandle, key.flags, key.ResolvedToken.inValue.tokenContext, key.ResolvedToken.inValue.tokenScope,
+           key.ResolvedToken.inValue.token, key.ResolvedToken.inValue.tokenType, key.ResolvedToken.outValue.hClass,
+           key.ResolvedToken.outValue.hMethod, key.ResolvedToken.outValue.hField,
+           key.ResolvedToken.outValue.pTypeSpec_Index, key.ResolvedToken.outValue.cbTypeSpec,
+           key.ResolvedToken.outValue.pMethodSpec_Index, key.ResolvedToken.outValue.cbMethodSpec);
 
     printf(", value fa-%u fflg-%08X hlp-%u off-%u fT-%u(%s) sT-%016llX aa-%u hnum-%u na-%u {", value.fieldAccessor,
            value.fieldFlags, value.helper, value.offset, value.fieldType, toString((CorInfoType)value.fieldType),
@@ -3593,27 +3470,14 @@ void MethodContext::repGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
                                     CORINFO_ACCESS_FLAGS    flags,
                                     CORINFO_FIELD_INFO*     pResult)
 {
+    AssertCodeMsg(GetFieldInfo != nullptr, EXCEPTIONCODE_MC, "Didn't find %x", pResolvedToken->token);
+
     Agnostic_GetFieldInfo key;
     ZeroMemory(&key, sizeof(Agnostic_GetFieldInfo)); // Since dd has nested structs, and we use memcmp to compare, we
                                                      // need to zero out the padding bytes too
-    Agnostic_CORINFO_FIELD_INFO value;
-
-    AssertCodeMsg(GetFieldInfo != nullptr, EXCEPTIONCODE_MC, "Didn't find %x", pResolvedToken->token);
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)GetFieldInfo->Contains((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)GetFieldInfo->Contains((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.callerHandle               = (DWORDLONG)callerHandle;
-    key.flags                      = (DWORD)flags;
+    key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetFieldInfo);
+    key.callerHandle  = (DWORDLONG)callerHandle;
+    key.flags         = (DWORD)flags;
 
     DWORD origFlag = key.flags;
 
@@ -3651,7 +3515,7 @@ void MethodContext::repGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
 #endif
     }
 
-    value = GetFieldInfo->Get(key);
+    Agnostic_CORINFO_FIELD_INFO value = GetFieldInfo->Get(key);
 
     pResult->fieldAccessor                 = (CORINFO_FIELD_ACCESSOR)value.fieldAccessor;
     pResult->fieldFlags                    = (unsigned)value.fieldFlags;
@@ -3893,24 +3757,10 @@ void MethodContext::recCanAccessClass(CORINFO_RESOLVED_TOKEN*      pResolvedToke
     Agnostic_CanAccessClassIn key;
     ZeroMemory(&key, sizeof(Agnostic_CanAccessClassIn)); // We use the input structs as a key and use memcmp to
                                                          // compare.. so we need to zero out padding too
+    key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, CanAccessClass);
+    key.callerHandle = (DWORDLONG)callerHandle;
 
     Agnostic_CanAccessClassOut value;
-
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)CanAccessClass->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)CanAccessClass->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.callerHandle               = (DWORDLONG)callerHandle;
-
     value.AccessHelper.helperNum = (DWORD)pAccessHelper->helperNum;
     value.AccessHelper.numArgs   = (DWORD)pAccessHelper->numArgs;
     for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++)
@@ -3927,10 +3777,11 @@ void MethodContext::dmpCanAccessClass(const Agnostic_CanAccessClassIn& key, cons
 {
     printf("CanAccessClass key tc-%016llX ts-%016llX tok-%08X tt-%u cls-%016llX meth-%016llX fld-%016llX ti-%u ts-%u "
            "mi-%u ms-%u",
-           key.ResolvedToken.tokenContext, key.ResolvedToken.tokenScope, key.ResolvedToken.token,
-           key.ResolvedToken.tokenType, key.ResolvedToken.hClass, key.ResolvedToken.hMethod, key.ResolvedToken.hField,
-           key.ResolvedToken.typeSpec_Index, key.ResolvedToken.cbTypeSpec, key.ResolvedToken.methodSpec_Index,
-           key.ResolvedToken.cbMethodSpec);
+           key.ResolvedToken.inValue.tokenContext, key.ResolvedToken.inValue.tokenScope,
+           key.ResolvedToken.inValue.token, key.ResolvedToken.inValue.tokenType, key.ResolvedToken.outValue.hClass,
+           key.ResolvedToken.outValue.hMethod, key.ResolvedToken.outValue.hField,
+           key.ResolvedToken.outValue.pTypeSpec_Index, key.ResolvedToken.outValue.cbTypeSpec,
+           key.ResolvedToken.outValue.pMethodSpec_Index, key.ResolvedToken.outValue.cbMethodSpec);
     printf(", value hnum-%u na-%u {", value.AccessHelper.helperNum, value.AccessHelper.numArgs);
     for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++)
     {
@@ -3942,31 +3793,18 @@ CorInfoIsAccessAllowedResult MethodContext::repCanAccessClass(CORINFO_RESOLVED_T
                                                               CORINFO_METHOD_HANDLE   callerHandle,
                                                               CORINFO_HELPER_DESC*    pAccessHelper)
 {
+    AssertCodeMsg(CanAccessClass != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX",
+                  (DWORDLONG)pResolvedToken->hClass);
+
     Agnostic_CanAccessClassIn key;
     ZeroMemory(&key, sizeof(Agnostic_CanAccessClassIn)); // We use the input structs as a key and use memcmp to
                                                          // compare.. so we need to zero out padding too
-    Agnostic_CanAccessClassOut value;
-
-    AssertCodeMsg(CanAccessClass != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX",
-                  (DWORDLONG)pResolvedToken->hClass);
-    key.ResolvedToken.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
-    key.ResolvedToken.tokenScope   = (DWORDLONG)pResolvedToken->tokenScope;
-    key.ResolvedToken.token        = (DWORD)pResolvedToken->token;
-    key.ResolvedToken.tokenType    = (DWORD)pResolvedToken->tokenType;
-    key.ResolvedToken.hClass       = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod      = (DWORDLONG)pResolvedToken->hMethod;
-    key.ResolvedToken.hField       = (DWORDLONG)pResolvedToken->hField;
-    key.ResolvedToken.typeSpec_Index =
-        (DWORD)CanAccessClass->Contains((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
-    key.ResolvedToken.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
-    key.ResolvedToken.methodSpec_Index =
-        (DWORD)CanAccessClass->Contains((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
-    key.ResolvedToken.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
-    key.callerHandle               = (DWORDLONG)callerHandle;
+    key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, CanAccessClass);
+    key.callerHandle  = (DWORDLONG)callerHandle;
 
     AssertCodeMsg(CanAccessClass->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX",
                   (DWORDLONG)pResolvedToken->hClass);
-    value = CanAccessClass->Get(key);
+    Agnostic_CanAccessClassOut value = CanAccessClass->Get(key);
 
     pAccessHelper->helperNum = (CorInfoHelpFunc)value.AccessHelper.helperNum;
     pAccessHelper->numArgs   = (unsigned)value.AccessHelper.numArgs;
@@ -3989,24 +3827,25 @@ void MethodContext::recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken,
     ZeroMemory(&key, sizeof(Agnostic_GetCastingHelper)); // We use the input structs as a key and use memcmp to
                                                          // compare.. so we need to zero out padding too
 
-    key.ResolvedToken.tokenContext     = (DWORDLONG)0;
-    key.ResolvedToken.tokenScope       = (DWORDLONG)0;
-    key.ResolvedToken.token            = (DWORD)0;
-    key.ResolvedToken.tokenType        = (DWORD)0;
-    key.ResolvedToken.hClass           = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod          = (DWORDLONG)0;
-    key.ResolvedToken.hField           = (DWORDLONG)0;
-    key.ResolvedToken.typeSpec_Index   = (DWORD)0;
-    key.ResolvedToken.cbTypeSpec       = (DWORD)0;
-    key.ResolvedToken.methodSpec_Index = (DWORD)0;
-    key.ResolvedToken.cbMethodSpec     = (DWORD)0;
-    key.fThrowing                      = (DWORD)fThrowing;
+    key.ResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+    key.ResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+    key.ResolvedToken.inValue.token              = (DWORD)0;
+    key.ResolvedToken.inValue.tokenType          = (DWORD)0;
+    key.ResolvedToken.outValue.hClass            = (DWORDLONG)pResolvedToken->hClass;
+    key.ResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+    key.ResolvedToken.outValue.hField            = (DWORDLONG)0;
+    key.ResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.ResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+    key.ResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+    key.ResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
+    key.fThrowing                                = (DWORD)fThrowing;
 
     GetCastingHelper->Add(key, (DWORD)result);
 }
 void MethodContext::dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value)
 {
-    printf("GetCastingHelper key cls-%016llX, thw-%u, value res-%u", key.ResolvedToken.hClass, key.fThrowing, value);
+    printf("GetCastingHelper key cls-%016llX, thw-%u, value res-%u", key.ResolvedToken.outValue.hClass, key.fThrowing,
+           value);
 }
 CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing)
 {
@@ -4014,18 +3853,18 @@ CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pReso
     ZeroMemory(&key, sizeof(Agnostic_GetCastingHelper)); // We use the input structs as a key and use memcmp to
                                                          // compare.. so we need to zero out padding too
 
-    key.ResolvedToken.tokenContext     = (DWORDLONG)0;
-    key.ResolvedToken.tokenScope       = (DWORDLONG)0;
-    key.ResolvedToken.token            = (DWORD)0;
-    key.ResolvedToken.tokenType        = (DWORD)0;
-    key.ResolvedToken.hClass           = (DWORDLONG)pResolvedToken->hClass;
-    key.ResolvedToken.hMethod          = (DWORDLONG)0;
-    key.ResolvedToken.hField           = (DWORDLONG)0;
-    key.ResolvedToken.typeSpec_Index   = (DWORD)0;
-    key.ResolvedToken.cbTypeSpec       = (DWORD)0;
-    key.ResolvedToken.methodSpec_Index = (DWORD)0;
-    key.ResolvedToken.cbMethodSpec     = (DWORD)0;
-    key.fThrowing                      = (DWORD)fThrowing;
+    key.ResolvedToken.inValue.tokenContext       = (DWORDLONG)0;
+    key.ResolvedToken.inValue.tokenScope         = (DWORDLONG)0;
+    key.ResolvedToken.inValue.token              = (DWORD)0;
+    key.ResolvedToken.inValue.tokenType          = (DWORD)0;
+    key.ResolvedToken.outValue.hClass            = (DWORDLONG)pResolvedToken->hClass;
+    key.ResolvedToken.outValue.hMethod           = (DWORDLONG)0;
+    key.ResolvedToken.outValue.hField            = (DWORDLONG)0;
+    key.ResolvedToken.outValue.pTypeSpec_Index   = (DWORD)0;
+    key.ResolvedToken.outValue.cbTypeSpec        = (DWORD)0;
+    key.ResolvedToken.outValue.pMethodSpec_Index = (DWORD)0;
+    key.ResolvedToken.outValue.cbMethodSpec      = (DWORD)0;
+    key.fThrowing                                = (DWORD)fThrowing;
 
     CorInfoHelpFunc value = (CorInfoHelpFunc)GetCastingHelper->Get(key);
     return value;
index 14e6b5a..0e01a37 100644 (file)
@@ -105,7 +105,6 @@ public:
         DWORD     cbTypeSpec;
         DWORD     pMethodSpec_Index;
         DWORD     cbMethodSpec;
-        DWORD     exceptionCode;
     };
     struct Agnostic_GetArgType
     {
@@ -161,17 +160,9 @@ public:
     };
     struct Agnostic_CORINFO_RESOLVED_TOKEN
     {
-        DWORDLONG tokenContext;
-        DWORDLONG tokenScope;
-        DWORD     token;
-        DWORD     tokenType;
-        DWORDLONG hClass;
-        DWORDLONG hMethod;
-        DWORDLONG hField;
-        DWORD     typeSpec_Index;
-        DWORD     cbTypeSpec;
-        DWORD     methodSpec_Index;
-        DWORD     cbMethodSpec;
+        Agnostic_CORINFO_RESOLVED_TOKENin inValue;
+
+        Agnostic_CORINFO_RESOLVED_TOKENout outValue;
     };
     struct Agnostic_GetFieldInfo
     {
@@ -450,6 +441,18 @@ public:
         DWORDLONG ownerType;
     };
 
+    struct ResolveTokenValue
+    {
+        Agnostic_CORINFO_RESOLVED_TOKENout tokenOut;
+        DWORD                              exceptionCode;
+    };
+
+    struct TryResolveTokenValue
+    {
+        Agnostic_CORINFO_RESOLVED_TOKENout tokenOut;
+        DWORD                              success;
+    };
+
 #pragma pack(pop)
 
     MethodContext();
@@ -559,12 +562,11 @@ public:
                                DWORD*                exceptionCode);
 
     void recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode);
-    void dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const Agnostic_CORINFO_RESOLVED_TOKENout& value);
+    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 Agnostic_CORINFO_RESOLVED_TOKENout& value);
+    void dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const TryResolveTokenValue& value);
     bool repTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken);
 
     void recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
new file mode 100644 (file)
index 0000000..4578608
--- /dev/null
@@ -0,0 +1,107 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//----------------------------------------------------------
+// SpmiRecordHelper.h - Helpers to copy data between agnostic/non-agnostic types and dump them.
+//----------------------------------------------------------
+
+#include "methodcontext.h"
+
+class SpmiRecordsHelper
+{
+public:
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin CreateAgnostic_CORINFO_RESOLVED_TOKENin
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken);
+
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout CreateAgnostic_CORINFO_RESOLVED_TOKENout_without_buffers
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken);
+
+    template<typename key, typename value>
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout StoreAgnostic_CORINFO_RESOLVED_TOKENout
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken, LightWeightMap<key, value>* buffers);
+
+    template<typename key, typename value>
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout RestoreAgnostic_CORINFO_RESOLVED_TOKENout
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken, LightWeightMap<key, value>* buffers);
+
+    template<typename key, typename value>
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN StoreAgnostic_CORINFO_RESOLVED_TOKEN
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken, LightWeightMap<key, value>* buffers);
+
+    template<typename key, typename value>
+    static MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN RestoreAgnostic_CORINFO_RESOLVED_TOKEN
+    (CORINFO_RESOLVED_TOKEN* pResolvedToken, LightWeightMap<key, value>* buffers);
+};
+
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(CORINFO_RESOLVED_TOKEN * pResolvedToken)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKENin tokenIn;
+    ZeroMemory(&tokenIn, sizeof(tokenIn));
+    tokenIn.tokenContext = (DWORDLONG)pResolvedToken->tokenContext;
+    tokenIn.tokenScope = (DWORDLONG)pResolvedToken->tokenScope;
+    tokenIn.token = (DWORD)pResolvedToken->token;
+    tokenIn.tokenType = (DWORD)pResolvedToken->tokenType;
+    return tokenIn;
+}
+
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENout_without_buffers(CORINFO_RESOLVED_TOKEN * pResolvedToken)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout tokenOut;
+    ZeroMemory(&tokenOut, sizeof(tokenOut));
+    tokenOut.hClass = (DWORDLONG)pResolvedToken->hClass;
+    tokenOut.hMethod = (DWORDLONG)pResolvedToken->hMethod;
+    tokenOut.hField = (DWORDLONG)pResolvedToken->hField;
+
+    tokenOut.cbTypeSpec = (DWORD)pResolvedToken->cbTypeSpec;
+    tokenOut.cbMethodSpec = (DWORD)pResolvedToken->cbMethodSpec;
+
+    tokenOut.pTypeSpec_Index = -1;
+    tokenOut.pMethodSpec_Index = -1;
+
+    return tokenOut;
+}
+
+template<typename key, typename value>
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKENout(CORINFO_RESOLVED_TOKEN * pResolvedToken, LightWeightMap<key, value>* buffers)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout tokenOut(CreateAgnostic_CORINFO_RESOLVED_TOKENout_without_buffers(pResolvedToken));
+
+    tokenOut.pTypeSpec_Index =
+        (DWORD)buffers->AddBuffer((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
+    tokenOut.pMethodSpec_Index =
+        (DWORD)buffers->AddBuffer((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
+
+    return tokenOut;
+}
+
+template<typename key, typename value>
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKENout(CORINFO_RESOLVED_TOKEN * pResolvedToken, LightWeightMap<key, value>* buffers)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKENout tokenOut(CreateAgnostic_CORINFO_RESOLVED_TOKENout_without_buffers(pResolvedToken));
+    tokenOut.pTypeSpec_Index =
+        (DWORD)buffers->Contains((unsigned char*)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
+    tokenOut.pMethodSpec_Index =
+        (DWORD)buffers->Contains((unsigned char*)pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
+    return tokenOut;
+}
+
+template<typename key, typename value>
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(CORINFO_RESOLVED_TOKEN * pResolvedToken, LightWeightMap<key, value>* buffers)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN token;
+    token.inValue = CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
+    token.outValue = StoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, buffers);
+    return token;
+}
+
+template<typename key, typename value>
+inline MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(CORINFO_RESOLVED_TOKEN * pResolvedToken, LightWeightMap<key, value>* buffers)
+{
+    MethodContext::Agnostic_CORINFO_RESOLVED_TOKEN token;
+    ZeroMemory(&token, sizeof(token));
+    token.inValue = CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken);
+    token.outValue = RestoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, buffers);
+    return token;
+}