diff options
author | Andy Ayers <andya@microsoft.com> | 2021-03-11 22:47:42 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-11 22:47:42 +0300 |
commit | 830a540b6d2ff3b85980464cb626aa1463ed144d (patch) | |
tree | 8f08d891f3a6be055e96b3bc465cd9bc4ad2a3a5 /src/coreclr/ToolBox | |
parent | 2b39df88c81a17961c01596c83139ea3e401b86a (diff) |
SPMI: add pgo data fingerprint to method identity (#49416)
This ensures that pgo and non-pgo machine contexts for the same method with
otherwise identical jit flags won't get merged, and likewise for pgo contexts
with different counter values.
Diffstat (limited to 'src/coreclr/ToolBox')
-rw-r--r-- | src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index aeed2683d0f..0a7da7e4b56 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -6681,6 +6681,58 @@ int MethodContext::dumpMethodIdentityInfoToBuffer(char* buff, int len, bool igno buff += t; len -= t; + // Fingerprint the root method PGO data (if any) and append it to the ID info. + // + if ((GetPgoInstrumentationResults != nullptr) && + (GetPgoInstrumentationResults->GetIndex(CastHandle(pInfo->ftn)) != -1)) + { + ICorJitInfo::PgoInstrumentationSchema* schema = nullptr; + UINT32 schemaCount = 0; + BYTE* schemaData = nullptr; + HRESULT pgoHR = repGetPgoInstrumentationResults(pInfo->ftn, &schema, &schemaCount, &schemaData); + + size_t minOffset = (size_t) ~0; + size_t maxOffset = 0; + uint32_t totalCount = 0; + + if (SUCCEEDED(pgoHR)) + { + // Locate the range of the counter data. + // + for (UINT32 i = 0; i < schemaCount; i++) + { + if ((schema[i].InstrumentationKind == ICorJitInfo::PgoInstrumentationKind::BasicBlockIntCount) + || (schema[i].InstrumentationKind == ICorJitInfo::PgoInstrumentationKind::EdgeIntCount)) + { + if (schema[i].Offset < minOffset) + { + minOffset = schema[i].Offset; + } + + if (schema[i].Offset > maxOffset) + { + maxOffset = schema[i].Offset; + } + + totalCount += *(uint32_t*)(schemaData + schema[i].Offset); + } + } + + // Hash the counter values. + // + if (minOffset < maxOffset) + { + char pgoHash[MD5_HASH_BUFFER_SIZE]; + dumpMD5HashToBuffer(schemaData + minOffset, (int)(maxOffset + sizeof(int) - minOffset), pgoHash, + MD5_HASH_BUFFER_SIZE); + + t = sprintf_s(buff, len, " Pgo Counters %u, Count %u, Hash: %s", schemaCount, totalCount, pgoHash); + buff += t; + len -= t; + } + } + } + return (int)(buff - obuff); } |