diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index a356862e5a3443..9d8c64356a9a5d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -4153,6 +4153,7 @@ CORINFO_MODULE_HANDLE MethodContext::repEmbedModuleHandle(CORINFO_MODULE_HANDLE return (CORINFO_MODULE_HANDLE)value.B; } +const DWORDLONG CONTINUATION_TYPE_PSEUDO_CLASS_HANDLE = (DWORDLONG)0x12345678beef0000; void MethodContext::recEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection, CORINFO_CLASS_HANDLE result) { if (EmbedClassHandle == nullptr) @@ -4176,12 +4177,25 @@ void MethodContext::dmpEmbedClassHandle(DWORDLONG key, DLDL value) CORINFO_CLASS_HANDLE MethodContext::repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection) { DWORDLONG key = CastHandle(handle); + if (key == CONTINUATION_TYPE_PSEUDO_CLASS_HANDLE) + { + if ((EmbedClassHandle->GetCount() > 0) && (EmbedClassHandle->GetItem(0).A != 0)) + { + // Some other embedded handle required an indirection, so do the same for the pseudo handle + // (avoids spurious improvements in R2R scenarios) + *ppIndirection = (void*)CONTINUATION_TYPE_PSEUDO_CLASS_HANDLE; + return nullptr; + } + + *ppIndirection = nullptr; + return handle; + } + DLDL value = LookupByKeyOrMiss(EmbedClassHandle, key, ": key %016" PRIX64 "", key); DEBUG_REP(dmpEmbedClassHandle(key, value)); - if (ppIndirection != nullptr) - *ppIndirection = (void*)value.A; + *ppIndirection = (void*)value.A; return (CORINFO_CLASS_HANDLE)value.B; } @@ -6958,17 +6972,26 @@ CORINFO_CLASS_HANDLE MethodContext::repGetContinuationType(size_t dataSize, { AssertMapExistsNoMessage(GetContinuationType); - int objRefsBuffer = GetContinuationType->Contains((unsigned char*)objRefs, (unsigned)objRefsSize); - if (objRefsBuffer == -1) - LogException(EXCEPTIONCODE_MC, "SuperPMI assertion failed (missing obj refs buffer)", ""); - Agnostic_GetContinuationTypeIn key; ZeroMemory(&key, sizeof(key)); key.dataSize = (DWORDLONG)dataSize; - key.objRefs = objRefsBuffer; + key.objRefs = (DWORD)GetContinuationType->Contains((unsigned char*)objRefs, (unsigned)objRefsSize); key.objRefsSize = (DWORD)objRefsSize; - DWORDLONG value = LookupByKeyOrMiss(GetContinuationType, key, ": dataSize %016" PRIX64 ", objRefs %u", key.dataSize, key.objRefs); + DWORDLONG value; + int index = GetContinuationType->GetIndex(key); + if (index == -1) + { + // This handle is more or less opaque, we can tolerate a miss here and + // just fake up handle. Otherwise SPMI will be useless for + // any async change that results in changes in live state. + value = CONTINUATION_TYPE_PSEUDO_CLASS_HANDLE; + } + else + { + value = GetContinuationType->GetItem(index); + } + DEBUG_REP(dmpGetContinuationType(key, value)); return (CORINFO_CLASS_HANDLE)value;