1
0
mirror of https://github.com/wolfpld/tracy synced 2025-04-30 04:43:53 +00:00

Mixed source/assembly symbol view.

This commit is contained in:
Bartosz Taudul 2020-04-08 22:04:00 +02:00
parent 5f4145ef0a
commit 006919ec55
2 changed files with 270 additions and 221 deletions

View File

@ -31,7 +31,6 @@ SourceView::SourceView( ImFont* font )
, m_dataSize( 0 )
, m_targetLine( 0 )
, m_selectedLine( 0 )
, m_showAsm( false )
, m_codeLen( 0 )
, m_highlightAddr( 0 )
, m_asmRelative( false )
@ -53,7 +52,6 @@ void SourceView::OpenSource( const char* fileName, int line )
m_baseAddr = 0;
m_symAddr = 0;
m_currentAddr = 0;
m_showAsm = false;
ParseSource( fileName, nullptr );
assert( !m_lines.empty() );
@ -69,10 +67,24 @@ void SourceView::OpenSymbol( const char* fileName, int line, uint64_t baseAddr,
m_currentAddr = symAddr;
ParseSource( fileName, &worker );
Disassemble( baseAddr, worker );
if( m_lines.empty() ) m_showAsm = true;
if( !Disassemble( baseAddr, worker ) ) m_showAsm = false;
assert( m_showAsm || !m_lines.empty() );
if( !m_lines.empty() )
{
if( !m_asm.empty() )
{
m_displayMode = DisplayMixed;
}
else
{
m_displayMode = DisplaySource;
}
}
else
{
assert( !m_asm.empty() );
m_displayMode = DisplayAsm;
}
}
void SourceView::ParseSource( const char* fileName, const Worker* worker )
@ -343,47 +355,59 @@ void SourceView::RenderSymbolView( const Worker& worker )
{
assert( m_symAddr != 0 );
if( !m_asm.empty() && !m_lines.empty() )
auto sym = worker.GetSymbolData( m_symAddr );
assert( sym );
if( sym->isInline )
{
if( SmallCheckbox( ICON_FA_MICROCHIP " Show assembly", &m_showAsm ) )
auto parent = worker.GetSymbolData( m_baseAddr );
if( parent )
{
if( m_showAsm )
{
m_targetAddr = m_symAddr;
TextFocused( "Symbol:", worker.GetString( parent->name ) );
}
else
{
m_targetLine = m_selectedLine;
char tmp[16];
sprintf( tmp, "0x%x", m_baseAddr );
TextFocused( "Symbol:", tmp );
}
}
else
{
TextFocused( "Symbol:", worker.GetString( sym->name ) );
}
TextDisabledUnformatted( "Mode:" );
ImGui::SameLine();
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, ImVec2( 0, 0 ) );
if( !m_lines.empty() )
{
ImGui::RadioButton( "Source", &m_displayMode, DisplaySource );
if( !m_asm.empty() )
{
if( !m_lines.empty() )
ImGui::SameLine();
ImGui::RadioButton( "Assembly", &m_displayMode, DisplayAsm );
ImGui::SameLine();
ImGui::RadioButton( "Mixed", &m_displayMode, DisplayMixed );
}
}
else
{
ImGui::RadioButton( "Assembly", &m_displayMode, DisplayAsm );
}
ImGui::PopStyleVar();
if( !m_asm.empty() )
{
ImGui::SameLine();
ImGui::Spacing();
ImGui::SameLine();
}
TextFocused( "Code size:", MemSizeToString( m_codeLen ) );
}
uint32_t iptotal = 0;
unordered_flat_map<uint64_t, uint32_t> ipcount;
uint32_t iptotalSrc = 0, iptotalAsm = 0;
unordered_flat_map<uint64_t, uint32_t> ipcountSrc, ipcountAsm;
auto ipmap = worker.GetSymbolInstructionPointers( m_symAddr );
if( ipmap )
{
if( m_showAsm )
{
for( auto& ip : *ipmap )
{
auto addr = worker.GetCanonicalPointer( ip.first );
assert( ipcount.find( addr ) == ipcount.end() );
ipcount.emplace( addr, ip.second );
iptotal += ip.second;
}
}
else
{
for( auto& ip : *ipmap )
{
@ -394,58 +418,131 @@ void SourceView::RenderSymbolView( const Worker& worker )
if( strcmp( ffn, m_file ) == 0 )
{
const auto line = frame->data[0].line;
auto it = ipcount.find( line );
if( it == ipcount.end() )
auto it = ipcountSrc.find( line );
if( it == ipcountSrc.end() )
{
ipcount.emplace( line, ip.second );
ipcountSrc.emplace( line, ip.second );
}
else
{
it->second += ip.second;
}
iptotal += ip.second;
}
}
iptotalSrc += ip.second;
}
}
if( iptotal > 0 )
auto addr = worker.GetCanonicalPointer( ip.first );
assert( ipcountAsm.find( addr ) == ipcountAsm.end() );
ipcountAsm.emplace( addr, ip.second );
iptotalAsm += ip.second;
}
if( iptotalAsm > 0 )
{
ImGui::SameLine();
ImGui::Spacing();
ImGui::SameLine();
TextFocused( "Samples:", RealToString( iptotal ) );
TextFocused( "Samples:", RealToString( iptotalAsm ) );
}
}
auto sym = worker.GetSymbolData( m_symAddr );
ImGui::Separator();
uint64_t jumpOut = 0;
switch( m_displayMode )
{
case DisplaySource:
RenderSymbolSourceView( iptotalSrc, ipcountSrc, worker );
break;
case DisplayAsm:
jumpOut = RenderSymbolAsmView( iptotalAsm, ipcountAsm, worker );
break;
case DisplayMixed:
ImGui::Columns( 2 );
RenderSymbolSourceView( iptotalSrc, ipcountSrc, worker );
ImGui::NextColumn();
jumpOut = RenderSymbolAsmView( iptotalAsm, ipcountAsm, worker );
ImGui::EndColumns();
break;
default:
assert( false );
break;
}
if( jumpOut != 0 )
{
auto sym = worker.GetSymbolData( jumpOut );
if( sym )
{
ImGui::SameLine();
ImGui::Spacing();
ImGui::SameLine();
TextFocused( "Symbol:", worker.GetString( sym->name ) );
if( sym->isInline )
auto line = sym->line;
auto file = line == 0 ? nullptr : worker.GetString( sym->file );
if( file && !SourceFileValid( file, worker.GetCaptureTime() ) )
{
auto parent = worker.GetSymbolData( m_baseAddr );
if( parent )
file = nullptr;
line = 0;
}
if( line > 0 || sym->size.Val() > 0 )
{
ImGui::SameLine();
ImGui::TextDisabled( "(%s)", worker.GetString( parent->name ) );
OpenSymbol( file, line, jumpOut, jumpOut, worker );
}
}
}
}
if( !m_showAsm )
{
void SourceView::RenderSymbolSourceView( uint32_t iptotal, unordered_flat_map<uint64_t, uint32_t> ipcount, const Worker& worker )
{
TextColoredUnformatted( ImVec4( 1.f, 1.f, 0.2f, 1.f ), ICON_FA_EXCLAMATION_TRIANGLE );
ImGui::SameLine();
TextColoredUnformatted( ImVec4( 1.f, 0.3f, 0.3f, 1.f ), "The source file contents might not reflect the actual profiled code!" );
ImGui::SameLine();
TextColoredUnformatted( ImVec4( 1.f, 1.f, 0.2f, 1.f ), ICON_FA_EXCLAMATION_TRIANGLE );
ImGui::BeginChild( "##sourceView", ImVec2( 0, 0 ), true );
if( m_font ) ImGui::PushFont( m_font );
if( m_targetLine != 0 )
{
int lineNum = 1;
for( auto& line : m_lines )
{
if( m_targetLine == lineNum )
{
m_targetLine = 0;
ImGui::SetScrollHereY();
}
RenderLine( line, lineNum++, 0, iptotal, &worker );
}
}
else
{
ImGuiListClipper clipper( (int)m_lines.size() );
while( clipper.Step() )
{
if( iptotal == 0 )
{
for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ )
{
RenderLine( m_lines[i], i+1, 0, 0, &worker );
}
}
else
{
for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ )
{
auto it = ipcount.find( i+1 );
const auto ipcnt = it == ipcount.end() ? 0 : it->second;
RenderLine( m_lines[i], i+1, ipcnt, iptotal, &worker );
}
}
}
}
if( m_font ) ImGui::PopFont();
ImGui::EndChild();
}
uint64_t SourceView::RenderSymbolAsmView( uint32_t iptotal, unordered_flat_map<uint64_t, uint32_t> ipcount, const Worker& worker )
{
SmallCheckbox( ICON_FA_SEARCH_LOCATION " Relative locations", &m_asmRelative );
ImGui::SameLine();
ImGui::Spacing();
@ -455,13 +552,11 @@ void SourceView::RenderSymbolView( const Worker& worker )
ImGui::Spacing();
ImGui::SameLine();
SmallCheckbox( ICON_FA_SHARE " Draw jumps", &m_showJumps );
}
ImGui::BeginChild( "##asmView", ImVec2( 0, 0 ), true );
if( m_font ) ImGui::PushFont( m_font );
uint64_t jumpOut = 0;
ImGui::BeginChild( "##sourceView", ImVec2( 0, 0 ), true );
if( m_font ) ImGui::PushFont( m_font );
if( m_showAsm )
{
if( m_targetAddr != 0 )
{
for( auto& line : m_asm )
@ -549,67 +644,11 @@ void SourceView::RenderSymbolView( const Worker& worker )
}
}
}
}
else
{
if( m_targetLine != 0 )
{
int lineNum = 1;
for( auto& line : m_lines )
{
if( m_targetLine == lineNum )
{
m_targetLine = 0;
ImGui::SetScrollHereY();
}
RenderLine( line, lineNum++, 0, iptotal, &worker );
}
}
else
{
ImGuiListClipper clipper( (int)m_lines.size() );
while( clipper.Step() )
{
if( iptotal == 0 )
{
for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ )
{
RenderLine( m_lines[i], i+1, 0, 0, &worker );
}
}
else
{
for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ )
{
auto it = ipcount.find( i+1 );
const auto ipcnt = it == ipcount.end() ? 0 : it->second;
RenderLine( m_lines[i], i+1, ipcnt, iptotal, &worker );
}
}
}
}
}
if( m_font ) ImGui::PopFont();
ImGui::EndChild();
if( jumpOut != 0 )
{
auto sym = worker.GetSymbolData( jumpOut );
if( sym )
{
auto line = sym->line;
auto file = line == 0 ? nullptr : worker.GetString( sym->file );
if( file && !SourceFileValid( file, worker.GetCaptureTime() ) )
{
file = nullptr;
line = 0;
}
if( line > 0 || sym->size.Val() > 0 )
{
OpenSymbol( file, line, jumpOut, jumpOut, worker );
}
}
}
return jumpOut;
}
static void PrintPercentage( float val )
@ -690,7 +729,7 @@ void SourceView::RenderLine( const Line& line, int lineNum, uint32_t ipcnt, uint
TextDisabledUnformatted( buf );
if( ImGui::IsItemClicked() )
{
m_showAsm = true;
m_displayMode = DisplayMixed;
m_currentAddr = (*addresses)[0];
m_targetAddr = (*addresses)[0];
}
@ -790,7 +829,7 @@ void SourceView::RenderAsmLine( const AsmLine& line, uint32_t ipcnt, uint32_t ip
m_currentAddr = line.addr;
m_targetLine = srcline;
m_selectedLine = srcline;
m_showAsm = false;
m_displayMode = DisplayMixed;
}
}
ImGui::SameLine( 0, 0 );

View File

@ -38,6 +38,13 @@ class SourceView
std::vector<uint64_t> source;
};
enum
{
DisplaySource,
DisplayAsm,
DisplayMixed
};
public:
SourceView( ImFont* font );
~SourceView();
@ -53,6 +60,9 @@ private:
void RenderSimpleSourceView();
void RenderSymbolView( const Worker& worker );
void RenderSymbolSourceView( uint32_t iptotal, unordered_flat_map<uint64_t, uint32_t> ipcount, const Worker& worker );
uint64_t RenderSymbolAsmView( uint32_t iptotal, unordered_flat_map<uint64_t, uint32_t> ipcount, const Worker& worker );
void RenderLine( const Line& line, int lineNum, uint32_t ipcnt, uint32_t iptotal, const Worker* worker );
void RenderAsmLine( const AsmLine& line, uint32_t ipcnt, uint32_t iptotal, const Worker& worker, uint64_t& jumpOut );
@ -67,7 +77,7 @@ private:
size_t m_dataSize;
int m_targetLine;
int m_selectedLine;
bool m_showAsm;
int m_displayMode;
uint32_t m_codeLen;
DecayValue<uint64_t> m_highlightAddr;
bool m_asmRelative;