Skip to content

Commit cd73b4f

Browse files
davmasonDaniel Ramos
andauthored
Port perfmap work to 7 (#85072)
Co-authored-by: Daniel Ramos <[email protected]>
1 parent 5b71fde commit cd73b4f

File tree

2 files changed

+116
-66
lines changed

2 files changed

+116
-66
lines changed

src/coreclr/vm/perfmap.cpp

Lines changed: 102 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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.
@@ -21,14 +22,23 @@
2122
Volatile<bool> PerfMap::s_enabled = false;
2223
PerfMap * PerfMap::s_Current = nullptr;
2324
bool 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.
2636
void 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-
220200
void 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.
411461
void NativeImagePerfMap::LogDataForModule(Module * pModule)
412462
{

src/coreclr/vm/perfmap.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,8 @@ class PerfMap
1818
private:
1919
static Volatile<bool> s_enabled;
2020

21-
// The one and only PerfMap for the process.
22-
static PerfMap * s_Current;
23-
24-
// Indicates whether optimization tiers should be shown for methods in perf maps
25-
static bool s_ShowOptimizationTiers;
21+
// Set to true if an error is encountered when writing to the file.
22+
static unsigned s_StubsMapped;
2623

2724
// The file stream to write the map to.
2825
CFileStream * m_FileStream;
@@ -33,16 +30,16 @@ class PerfMap
3330
// Set to true if an error is encountered when writing to the file.
3431
bool m_ErrorEncountered;
3532

36-
// Set to true if an error is encountered when writing to the file.
37-
unsigned m_StubsMapped;
38-
3933
// Construct a new map for the specified pid.
4034
PerfMap(int pid);
4135

42-
// Write a line to the map file.
43-
void WriteLine(SString & line);
44-
4536
protected:
37+
// Indicates whether optimization tiers should be shown for methods in perf maps
38+
static bool s_ShowOptimizationTiers;
39+
40+
// The one and only PerfMap for the process.
41+
static PerfMap * s_Current;
42+
4643
// Construct a new map without a specified file name.
4744
// Used for offline creation of NGEN map files.
4845
PerfMap();
@@ -53,16 +50,16 @@ class PerfMap
5350
// Open the perf map file for write.
5451
void OpenFile(SString& path);
5552

56-
// Does the actual work to log a method to the map.
57-
void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier);
58-
5953
// Does the actual work to log an image
6054
void LogImage(PEAssembly * pPEAssembly);
6155

6256
// Get the image signature and store it as a string.
6357
static void GetNativeImageSignature(PEAssembly * pPEAssembly, WCHAR * pwszSig, unsigned int nSigSize);
6458

6559
public:
60+
// Write a line to the map file.
61+
void WriteLine(SString & line);
62+
6663
// Initialize the map for the current process.
6764
static void Initialize();
6865

@@ -91,6 +88,9 @@ class NativeImagePerfMap : PerfMap
9188
// Specify the address format since it's now possible for 'perf script' to output file offsets or RVAs.
9289
bool m_EmitRVAs;
9390

91+
// Does the actual work to log a method to the map.
92+
void LogMethod(MethodDesc * pMethod, PCODE pCode, size_t codeSize, const char *optimizationTier);
93+
9494
// Log a pre-compiled method to the map.
9595
void LogPreCompiledMethod(MethodDesc * pMethod, PCODE pCode, PEImageLayout *pLoadedLayout, const char *optimizationTier);
9696

0 commit comments

Comments
 (0)