Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 67 additions & 50 deletions src/coreclr/vm/perfmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,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.
Expand All @@ -21,14 +22,23 @@
Volatile<bool> 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()
{
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();
Expand All @@ -49,7 +59,10 @@ void PerfMap::Initialize()
}

s_enabled = true;
}

if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == ALL || CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapEnabled) == JITDUMP)
{
const char* jitdumpPath;
char jitdumpPathBuffer[4096];

Expand All @@ -65,6 +78,13 @@ void PerfMap::Initialize()
}

PAL_PerfJitDump_Start(jitdumpPath);

if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerfMapShowOptimizationTiers) != 0)
{
s_ShowOptimizationTiers = true;
}

s_enabled = true;
}
}

Expand All @@ -89,8 +109,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))
Expand Down Expand Up @@ -119,7 +137,7 @@ PerfMap::PerfMap()
// Initialize with no failures.
m_ErrorEncountered = false;

m_StubsMapped = 0;
s_StubsMapped = 0;
}

// Clean-up resources.
Expand Down Expand Up @@ -157,6 +175,11 @@ void PerfMap::WriteLine(SString& line)
{
STANDARD_VM_CONTRACT;

if (m_FileStream == nullptr || m_ErrorEncountered)
{
return;
}

EX_TRY
{
// Write the line.
Expand All @@ -177,50 +200,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)
{
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.
if (optimizationTier != nullptr && s_ShowOptimizationTiers)
{
name.AppendPrintf("[%s]", optimizationTier);
}
SString line;
line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetUTF8());

// Write the line.
WriteLine(line);
PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetUTF8(), nullptr, nullptr);
}
EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
}


void PerfMap::LogImageLoad(PEAssembly * pPEAssembly)
{
if (s_enabled)
if (s_enabled && s_Current != nullptr)
{
s_Current->LogImage(pPEAssembly);
}
Expand Down Expand Up @@ -259,6 +241,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;
Expand All @@ -270,7 +261,30 @@ void PerfMap::LogJITCompiledMethod(MethodDesc * pMethod, PCODE pCode, size_t cod
optimizationTier = PrepareCodeConfig::GetJitOptimizationTierStr(pConfig, pMethod);
}

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);
}
SString line;
line.Printf(FMT_CODE_ADDR " %x %s\n", pCode, codeSize, name.GetUTF8());

// Write the line.
if(s_Current != nullptr)
{
s_Current->WriteLine(line);
}
PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetUTF8(), nullptr, nullptr);
}
EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);

}

// Log a pre-compiled method to the perfmap.
Expand Down Expand Up @@ -327,7 +341,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;
}
Expand All @@ -346,12 +360,15 @@ void PerfMap::LogStubs(const char* stubType, const char* stubOwner, PCODE pCode,

SString name;
// Build the map file line.
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.GetUTF8());

// Write the line.
s_Current->WriteLine(line);
if(s_Current != nullptr)
{
s_Current->WriteLine(line);
}
PAL_PerfJitDump_LogMethod((void*)pCode, codeSize, name.GetUTF8(), nullptr, nullptr);
}
EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/vm/perfmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class PerfMap
// 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;

Expand All @@ -33,9 +36,6 @@ 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);

Expand Down