diff options
author | Andy Ayers <andya@microsoft.com> | 2021-04-20 05:53:40 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-20 05:53:40 +0300 |
commit | 2bc05087e25f458ffe3b3969037e244e720df85c (patch) | |
tree | 3ddb2872dcd813c9a40ed308cced22beab78ab26 /src/coreclr/ToolBox | |
parent | f17e018186667666531c721ebf265bbdac7edd1c (diff) |
Fix SPMI handling of PGO schemas with class profiles (#51521)
SPMI wasn't capturing enough data for PGO schemas that had class profiles,
leading to replay failures.
Diffstat (limited to 'src/coreclr/ToolBox')
-rw-r--r-- | src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index a4badbfcae3..b72d9d7173c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -5486,8 +5486,15 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd size_t maxOffset = 0; for (UINT32 i = 0; i < (*pCountSchemaItems); i++) { - if (pInSchema[i].Offset > maxOffset) - maxOffset = pInSchema[i].Offset; + // Note >= here; for type histograms the count and handle schema entries have the same offset, + // but the handle schema (which comes second) has a larger count. + // + // The sizeof should really be target pointer size, so cross-bitness replay may not work here. + // + if (pInSchema[i].Offset >= maxOffset) + { + maxOffset = pInSchema[i].Offset + pInSchema[i].Count * sizeof(uintptr_t); + } agnosticSchema[i].Offset = (DWORDLONG)pInSchema[i].Offset; agnosticSchema[i].InstrumentationKind = (DWORD)pInSchema[i].InstrumentationKind; @@ -5498,11 +5505,8 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd value.schema_index = GetPgoInstrumentationResults->AddBuffer((unsigned char*)agnosticSchema, sizeof(Agnostic_PgoInstrumentationSchema) * (*pCountSchemaItems)); free(agnosticSchema); - // This isn't strictly accurate, but I think it'll do - size_t bufSize = maxOffset + 16; - - value.data_index = GetPgoInstrumentationResults->AddBuffer((unsigned char*)*pInstrumentationData, (unsigned)bufSize); - value.dataByteCount = (unsigned)bufSize; + value.data_index = GetPgoInstrumentationResults->AddBuffer((unsigned char*)*pInstrumentationData, (unsigned)maxOffset); + value.dataByteCount = (unsigned)maxOffset; value.result = (DWORD)result; GetPgoInstrumentationResults->Add(CastHandle(ftnHnd), value); @@ -5517,14 +5521,46 @@ void MethodContext::dmpGetPgoInstrumentationResults(DWORDLONG key, const Agnosti Agnostic_PgoInstrumentationSchema* pBuf = (Agnostic_PgoInstrumentationSchema*)GetPgoInstrumentationResults->GetBuffer(value.schema_index); + BYTE* pInstrumentationData = (BYTE*)GetPgoInstrumentationResults->GetBuffer(value.data_index); + printf("\n"); for (DWORD i = 0; i < value.countSchemaItems; i++) { - printf(" %u-{Offset %016llX ILOffset %u Kind %u(0x%x) Count %u Other %u}\n", + printf(" %u-{Offset %016llX ILOffset %u Kind %u(0x%x) Count %u Other %u Data ", i, pBuf[i].Offset, pBuf[i].ILOffset, pBuf[i].InstrumentationKind, pBuf[i].InstrumentationKind, pBuf[i].Count, pBuf[i].Other); + + switch((ICorJitInfo::PgoInstrumentationKind)pBuf[i].InstrumentationKind) + { + case ICorJitInfo::PgoInstrumentationKind::BasicBlockIntCount: + printf("B %u", *(unsigned*)(pInstrumentationData + pBuf[i].Offset)); + break; + case ICorJitInfo::PgoInstrumentationKind::EdgeIntCount: + printf("E %u", *(unsigned*)(pInstrumentationData + pBuf[i].Offset)); + break; + case ICorJitInfo::PgoInstrumentationKind::TypeHandleHistogramCount: + printf("T %u", *(unsigned*)(pInstrumentationData + pBuf[i].Offset)); + break; + case ICorJitInfo::PgoInstrumentationKind::TypeHandleHistogramTypeHandle: + for (unsigned int j = 0; j < pBuf[i].Count; j++) + { + printf("[%u] %016llX ", j, CastHandle(*(uintptr_t*)(pInstrumentationData + pBuf[i].Offset + j * sizeof(uintptr_t)))); + } + break; + case ICorJitInfo::PgoInstrumentationKind::GetLikelyClass: + { + // (N)umber, (L)ikelihood, (C)lass + printf("N %u L %u C %016llX", (unsigned)(pBuf[i].Other >> 8), (unsigned)(pBuf[i].Other && 0xFF), CastHandle(*(uintptr_t*)(pInstrumentationData + pBuf[i].Offset))); + } + break; + default: + printf("?"); + break; + } + + printf("}\n"); } } - printf("} data_index-%u [TODO, dump actual count data]", value.data_index); + printf("} data_index-%u", value.data_index); } HRESULT MethodContext::repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, |