Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2021-04-20 05:53:40 +0300
committerGitHub <noreply@github.com>2021-04-20 05:53:40 +0300
commit2bc05087e25f458ffe3b3969037e244e720df85c (patch)
tree3ddb2872dcd813c9a40ed308cced22beab78ab26 /src/coreclr/ToolBox
parentf17e018186667666531c721ebf265bbdac7edd1c (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.cpp54
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,