From 492873251e3dfaf04498ff4734af516a1e66d595 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Tue, 14 Feb 2023 14:49:54 -0800 Subject: [PATCH 1/2] Port perfmap work to 6 --- src/coreclr/vm/perfmap.cpp | 162 ++++++++++++++++++++++++------------- src/coreclr/vm/perfmap.h | 28 +++---- 2 files changed, 121 insertions(+), 69 deletions(-) diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index 8eb8925f7e0b7d..03c07b1adaf6de 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -11,6 +11,7 @@ #include "perfinfo.h" #include "pal.h" + // The code addresses are actually native image offsets during crossgen. Print // them as 32-bit numbers for consistent output when cross-targeting and to // make the output more compact. @@ -24,6 +25,15 @@ Volatile PerfMap::s_enabled = false; PerfMap * PerfMap::s_Current = nullptr; bool PerfMap::s_ShowOptimizationTiers = false; +unsigned PerfMap::s_StubsMapped = 0; + +enum +{ + DISABLED, + ALL, + JITDUMP, + PERFMAP +}; // Initialize the map for the process - called from EEStartupHelper. void PerfMap::Initialize() @@ -31,7 +41,7 @@ void PerfMap::Initialize() LIMITED_METHOD_CONTRACT; // Only enable the map if requested. - if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled)) + if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == PERFMAP) { // Get the current process id. int currentPid = GetCurrentProcessId(); @@ -52,10 +62,12 @@ void PerfMap::Initialize() } s_enabled = true; + } -#ifndef CROSSGEN_COMPILE + if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == JITDUMP) + { char jitdumpPath[4096]; - + // CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapJitDumpPath) returns a LPWSTR // Use GetEnvironmentVariableA because it is simpler. // Keep comment here to make it searchable. @@ -67,7 +79,13 @@ void PerfMap::Initialize() } PAL_PerfJitDump_Start(jitdumpPath); -#endif // CROSSGEN_COMPILE + + if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0) + { + s_ShowOptimizationTiers = true; + } + + s_enabled = true; } } @@ -92,8 +110,6 @@ PerfMap::PerfMap(int pid) // Initialize with no failures. m_ErrorEncountered = false; - m_StubsMapped = 0; - // Build the path to the map file on disk. WCHAR tempPath[MAX_LONGPATH+1]; if(!GetTempPathW(MAX_LONGPATH, tempPath)) @@ -121,7 +137,7 @@ PerfMap::PerfMap() // Initialize with no failures. m_ErrorEncountered = false; - m_StubsMapped = 0; + s_StubsMapped = 0; } // Clean-up resources. @@ -159,6 +175,11 @@ void PerfMap::WriteLine(SString& line) { STANDARD_VM_CONTRACT; + if (m_FileStream == nullptr || m_ErrorEncountered) + { + return; + } + EX_TRY { // Write the line. @@ -180,51 +201,9 @@ void PerfMap::WriteLine(SString& line) EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); } -// Log a method to the map. -void PerfMap::LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier) +void PerfMap::LogImageLoad(PEFile *pFile) { - CONTRACTL{ - THROWS; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - PRECONDITION(pMethod != nullptr); - PRECONDITION(pCode != nullptr); - PRECONDITION(codeSize > 0); - } CONTRACTL_END; - - if (m_FileStream == nullptr || m_ErrorEncountered) - { - // A failure occurred, do not log. - return; - } - - // Logging failures should not cause any exceptions to flow upstream. - EX_TRY - { - // Get the full method signature. - SString name; - pMethod->GetFullMethodInfo(name); - - // Build the map file line. - StackScratchBuffer scratch; - if (optimizationTier != nullptr && s_ShowOptimizationTiers) - { - name.AppendPrintf("[%s]", optimizationTier); - } - SString line; - line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetANSI(scratch)); - - // Write the line. - WriteLine(line); - PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetANSI(scratch), nullptr, nullptr); - } - EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); -} - - -void PerfMap::LogImageLoad(PEFile * pFile) -{ - if (s_enabled) + if (s_enabled && s_Current != nullptr) { s_Current->LogImage(pFile); } @@ -263,6 +242,15 @@ void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t cod { LIMITED_METHOD_CONTRACT; + CONTRACTL{ + THROWS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + PRECONDITION(pMethod != nullptr); + PRECONDITION(pCode != nullptr); + PRECONDITION(codeSize > 0); + } CONTRACTL_END; + if (!s_enabled) { return; @@ -276,7 +264,32 @@ void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t cod } #endif // CROSSGEN_COMPILE - s_Current->LogMethod(pMethod, pCode, codeSize, optimizationTier); + // Logging failures should not cause any exceptions to flow upstream. + EX_TRY + { + // Get the full method signature. + SString name; + pMethod->GetFullMethodInfo(name); + + // Build the map file line. + if (optimizationTier != nullptr && s_ShowOptimizationTiers) + { + name.AppendPrintf("[%s]", optimizationTier); + } + + StackScratchBuffer scratch; + SString line; + line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetANSI(scratch)); + + // Write the line. + if(s_Current != nullptr) + { + s_Current->WriteLine(line); + } + PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetANSI(scratch), nullptr, nullptr); + } + EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); + } // Log a pre-compiled method to the perfmap. @@ -335,7 +348,7 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode, { LIMITED_METHOD_CONTRACT; - if (!s_enabled || s_Current->m_FileStream == nullptr) + if (!s_enabled) { return; } @@ -355,12 +368,15 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode, // Build the map file line. StackScratchBuffer scratch; SString name; - name.Printf("stub<%d> %s<%s>", ++(s_Current->m_StubsMapped), stubType, stubOwner); + name.Printf("stub<%d> %s<%s>", ++(s_StubsMapped), stubType, stubOwner); SString line; line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetANSI(scratch)); // Write the line. - s_Current->WriteLine(line); + if(s_Current != nullptr) + { + s_Current->WriteLine(line); + } PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetANSI(scratch), nullptr, nullptr); } EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); @@ -417,6 +433,42 @@ NativeImagePerfMap::NativeImagePerfMap(Assembly * pAssembly, BSTR pDestPath) } } +void NativeImagePerfMap::LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier) +{ + CONTRACTL{ + THROWS; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + PRECONDITION(pMethod != nullptr); + PRECONDITION(pCode != nullptr); + PRECONDITION(codeSize > 0); + } CONTRACTL_END; + + // Logging failures should not cause any exceptions to flow upstream. + EX_TRY + { + // Get the full method signature. + SString name; + pMethod->GetFullMethodInfo(name); + + // Build the map file line. + StackScratchBuffer scratch; + if (optimizationTier != nullptr && s_ShowOptimizationTiers) + { + name.AppendPrintf("[%s]", optimizationTier); + } + SString line; + line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetANSI(scratch)); + + if (s_Current != nullptr) + { + s_Current->WriteLine(line); + } + PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetANSI(scratch), nullptr, nullptr); + } + EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); +} + // Log data to the perfmap for the specified module. void NativeImagePerfMap::LogDataForModule(Module * pModule) { diff --git a/src/coreclr/vm/perfmap.h b/src/coreclr/vm/perfmap.h index 14595813877d8b..636ac81830aa66 100644 --- a/src/coreclr/vm/perfmap.h +++ b/src/coreclr/vm/perfmap.h @@ -18,11 +18,8 @@ class PerfMap private: static Volatile s_enabled; - // The one and only PerfMap for the process. - static PerfMap * s_Current; - - // Indicates whether optimization tiers should be shown for methods in perf maps - static bool s_ShowOptimizationTiers; + // Set to true if an error is encountered when writing to the file. + static unsigned s_StubsMapped; // The file stream to write the map to. CFileStream * m_FileStream; @@ -33,16 +30,16 @@ class PerfMap // Set to true if an error is encountered when writing to the file. bool m_ErrorEncountered; - // Set to true if an error is encountered when writing to the file. - unsigned m_StubsMapped; - // Construct a new map for the specified pid. PerfMap(int pid); - // Write a line to the map file. - void WriteLine(SString & line); - protected: + // Indicates whether optimization tiers should be shown for methods in perf maps + static bool s_ShowOptimizationTiers; + + // The one and only PerfMap for the process. + static PerfMap * s_Current; + // Construct a new map without a specified file name. // Used for offline creation of NGEN map files. PerfMap(); @@ -53,9 +50,6 @@ class PerfMap // Open the perf map file for write. void OpenFile(SString& path); - // Does the actual work to log a method to the map. - void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier); - // Does the actual work to log an image void LogImage(PEFile * pFile); @@ -63,6 +57,9 @@ class PerfMap static void GetNativeImageSignature(PEFile * pFile, WCHAR * pwszSig, unsigned int nSigSize); public: + // Write a line to the map file. + void WriteLine(SString & line); + // Initialize the map for the current process. static void Initialize(); @@ -91,6 +88,9 @@ class NativeImagePerfMap : PerfMap // Specify the address format since it's now possible for 'perf script' to output file offsets or RVAs. bool m_EmitRVAs; + // Does the actual work to log a method to the map. + void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier); + // Log a pre-compiled method to the map. void LogPreCompiledMethod(MethodDesc * pMethod, PCODE pCode, PEImageLayout *pLoadedLayout, const char *optimizationTier); From 02d188695245f66487a6c3102d5169b9d575ff18 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 14 Apr 2023 14:57:20 -0700 Subject: [PATCH 2/2] Update perfmap.cpp --- src/coreclr/vm/perfmap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp index 03c07b1adaf6de..5eda731ec8bd0f 100644 --- a/src/coreclr/vm/perfmap.cpp +++ b/src/coreclr/vm/perfmap.cpp @@ -136,8 +136,6 @@ PerfMap::PerfMap() // Initialize with no failures. m_ErrorEncountered = false; - - s_StubsMapped = 0; } // Clean-up resources.