1212#include " perfinfo.h"
1313#include " pal.h"
1414
15+
1516// The code addresses are actually native image offsets during crossgen. Print
1617// them as 32-bit numbers for consistent output when cross-targeting and to
1718// make the output more compact.
2122Volatile<bool > PerfMap::s_enabled = false ;
2223PerfMap * PerfMap::s_Current = nullptr ;
2324bool PerfMap::s_ShowOptimizationTiers = false ;
25+ unsigned PerfMap::s_StubsMapped = 0 ;
26+
27+ enum
28+ {
29+ DISABLED,
30+ ALL,
31+ JITDUMP,
32+ PERFMAP
33+ };
2434
2535// Initialize the map for the process - called from EEStartupHelper.
2636void PerfMap::Initialize ()
2737{
2838 LIMITED_METHOD_CONTRACT;
2939
3040 // Only enable the map if requested.
31- if (CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapEnabled))
41+ if (CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapEnabled) == PERFMAP )
3242 {
3343 // Get the current process id.
3444 int currentPid = GetCurrentProcessId ();
@@ -49,7 +59,10 @@ void PerfMap::Initialize()
4959 }
5060
5161 s_enabled = true ;
62+ }
5263
64+ if (CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapEnabled) == JITDUMP)
65+ {
5366 const char * jitdumpPath;
5467 char jitdumpPathBuffer[4096 ];
5568
@@ -65,6 +78,13 @@ void PerfMap::Initialize()
6578 }
6679
6780 PAL_PerfJitDump_Start (jitdumpPath);
81+
82+ if (CLRConfig::GetConfigValue (CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0 )
83+ {
84+ s_ShowOptimizationTiers = true ;
85+ }
86+
87+ s_enabled = true ;
6888 }
6989}
7090
@@ -89,8 +109,6 @@ PerfMap::PerfMap(int pid)
89109 // Initialize with no failures.
90110 m_ErrorEncountered = false ;
91111
92- m_StubsMapped = 0 ;
93-
94112 // Build the path to the map file on disk.
95113 WCHAR tempPath[MAX_LONGPATH+1 ];
96114 if (!GetTempPathW (MAX_LONGPATH, tempPath))
@@ -117,8 +135,6 @@ PerfMap::PerfMap()
117135
118136 // Initialize with no failures.
119137 m_ErrorEncountered = false ;
120-
121- m_StubsMapped = 0 ;
122138}
123139
124140// Clean-up resources.
@@ -156,6 +172,11 @@ void PerfMap::WriteLine(SString& line)
156172{
157173 STANDARD_VM_CONTRACT;
158174
175+ if (m_FileStream == nullptr || m_ErrorEncountered)
176+ {
177+ return ;
178+ }
179+
159180 EX_TRY
160181 {
161182 // Write the line.
@@ -176,50 +197,9 @@ void PerfMap::WriteLine(SString& line)
176197 EX_CATCH{} EX_END_CATCH (SwallowAllExceptions);
177198}
178199
179- // Log a method to the map.
180- void PerfMap::LogMethod (MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier)
181- {
182- CONTRACTL{
183- THROWS;
184- GC_NOTRIGGER;
185- MODE_PREEMPTIVE;
186- PRECONDITION (pMethod != nullptr );
187- PRECONDITION (pCode != nullptr );
188- PRECONDITION (codeSize > 0 );
189- } CONTRACTL_END;
190-
191- if (m_FileStream == nullptr || m_ErrorEncountered)
192- {
193- // A failure occurred, do not log.
194- return ;
195- }
196-
197- // Logging failures should not cause any exceptions to flow upstream.
198- EX_TRY
199- {
200- // Get the full method signature.
201- SString name;
202- pMethod->GetFullMethodInfo (name);
203-
204- // Build the map file line.
205- if (optimizationTier != nullptr && s_ShowOptimizationTiers)
206- {
207- name.AppendPrintf (" [%s]" , optimizationTier);
208- }
209- SString line;
210- line.Printf (FMT_CODE_ADDR " %x %s\n " , pCode, codeSize, name.GetUTF8 ());
211-
212- // Write the line.
213- WriteLine (line);
214- PAL_PerfJitDump_LogMethod ((void *)pCode, codeSize, name.GetUTF8 (), nullptr , nullptr );
215- }
216- EX_CATCH{} EX_END_CATCH (SwallowAllExceptions);
217- }
218-
219-
220200void PerfMap::LogImageLoad (PEAssembly * pPEAssembly)
221201{
222- if (s_enabled)
202+ if (s_enabled && s_Current != nullptr )
223203 {
224204 s_Current->LogImage (pPEAssembly);
225205 }
@@ -258,6 +238,15 @@ void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t cod
258238{
259239 LIMITED_METHOD_CONTRACT;
260240
241+ CONTRACTL{
242+ THROWS;
243+ GC_NOTRIGGER;
244+ MODE_PREEMPTIVE;
245+ PRECONDITION (pMethod != nullptr );
246+ PRECONDITION (pCode != nullptr );
247+ PRECONDITION (codeSize > 0 );
248+ } CONTRACTL_END;
249+
261250 if (!s_enabled)
262251 {
263252 return ;
@@ -269,7 +258,31 @@ void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t cod
269258 optimizationTier = PrepareCodeConfig::GetJitOptimizationTierStr (pConfig, pMethod);
270259 }
271260
272- s_Current->LogMethod (pMethod, pCode, codeSize, optimizationTier);
261+ // Logging failures should not cause any exceptions to flow upstream.
262+ EX_TRY
263+ {
264+ // Get the full method signature.
265+ SString name;
266+ pMethod->GetFullMethodInfo (name);
267+
268+ // Build the map file line.
269+ if (optimizationTier != nullptr && s_ShowOptimizationTiers)
270+ {
271+ name.AppendPrintf (" [%s]" , optimizationTier);
272+ }
273+
274+ SString line;
275+ line.Printf (FMT_CODE_ADDR " %x %s\n " , pCode, codeSize, name.GetUTF8 ());
276+
277+ // Write the line.
278+ if (s_Current != nullptr )
279+ {
280+ s_Current->WriteLine (line);
281+ }
282+ PAL_PerfJitDump_LogMethod ((void *)pCode, codeSize, name.GetUTF8 (), nullptr , nullptr );
283+ }
284+ EX_CATCH{} EX_END_CATCH (SwallowAllExceptions);
285+
273286}
274287
275288// Log a pre-compiled method to the perfmap.
@@ -326,7 +339,7 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode,
326339{
327340 LIMITED_METHOD_CONTRACT;
328341
329- if (!s_enabled || s_Current-> m_FileStream == nullptr )
342+ if (!s_enabled)
330343 {
331344 return ;
332345 }
@@ -344,13 +357,15 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode,
344357 }
345358
346359 SString name;
347- // Build the map file line.
348- name.Printf (" stub<%d> %s<%s>" , ++(s_Current->m_StubsMapped ), stubType, stubOwner);
360+ name.Printf (" stub<%d> %s<%s>" , ++(s_StubsMapped), stubType, stubOwner);
349361 SString line;
350362 line.Printf (FMT_CODE_ADDR " %x %s\n " , pCode, codeSize, name.GetUTF8 ());
351363
352364 // Write the line.
353- s_Current->WriteLine (line);
365+ if (s_Current != nullptr )
366+ {
367+ s_Current->WriteLine (line);
368+ }
354369 PAL_PerfJitDump_LogMethod ((void *)pCode, codeSize, name.GetUTF8 (), nullptr , nullptr );
355370 }
356371 EX_CATCH{} EX_END_CATCH (SwallowAllExceptions);
@@ -407,6 +422,41 @@ NativeImagePerfMap::NativeImagePerfMap(Assembly * pAssembly, BSTR pDestPath)
407422 }
408423}
409424
425+ void NativeImagePerfMap::LogMethod (MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier)
426+ {
427+ CONTRACTL{
428+ THROWS;
429+ GC_NOTRIGGER;
430+ MODE_PREEMPTIVE;
431+ PRECONDITION (pMethod != nullptr );
432+ PRECONDITION (pCode != nullptr );
433+ PRECONDITION (codeSize > 0 );
434+ } CONTRACTL_END;
435+
436+ // Logging failures should not cause any exceptions to flow upstream.
437+ EX_TRY
438+ {
439+ // Get the full method signature.
440+ SString name;
441+ pMethod->GetFullMethodInfo (name);
442+
443+ // Build the map file line.
444+ if (optimizationTier != nullptr && s_ShowOptimizationTiers)
445+ {
446+ name.AppendPrintf (" [%s]" , optimizationTier);
447+ }
448+ SString line;
449+ line.Printf (FMT_CODE_ADDR " %x %s\n " , pCode, codeSize, name.GetUTF8 ());
450+
451+ if (s_Current != nullptr )
452+ {
453+ s_Current->WriteLine (line);
454+ }
455+ PAL_PerfJitDump_LogMethod ((void *)pCode, codeSize, name.GetUTF8 (), nullptr , nullptr );
456+ }
457+ EX_CATCH{} EX_END_CATCH (SwallowAllExceptions);
458+ }
459+
410460// Log data to the perfmap for the specified module.
411461void NativeImagePerfMap::LogDataForModule (Module * pModule)
412462{
0 commit comments