Draw jumps in assembly view.

This commit is contained in:
Bartosz Taudul 2020-04-04 03:34:54 +02:00
parent bda5c1d13e
commit aae161e31a
2 changed files with 68 additions and 2 deletions

View File

@ -17,6 +17,9 @@
namespace tracy namespace tracy
{ {
enum { JumpSeparation = 6 };
enum { JumpArrow = 9 };
SourceView::SourceView( ImFont* font ) SourceView::SourceView( ImFont* font )
: m_font( font ) : m_font( font )
, m_file( nullptr ) , m_file( nullptr )
@ -33,6 +36,7 @@ SourceView::SourceView( ImFont* font )
, m_highlightAddr( 0 ) , m_highlightAddr( 0 )
, m_asmRelative( false ) , m_asmRelative( false )
, m_asmShowSourceLocation( true ) , m_asmShowSourceLocation( true )
, m_showJumps( true )
{ {
} }
@ -372,6 +376,10 @@ void SourceView::Render( const Worker& worker )
ImGui::Spacing(); ImGui::Spacing();
ImGui::SameLine(); ImGui::SameLine();
SmallCheckbox( ICON_FA_FILE_IMPORT " Show source locations", &m_asmShowSourceLocation ); SmallCheckbox( ICON_FA_FILE_IMPORT " Show source locations", &m_asmShowSourceLocation );
ImGui::SameLine();
ImGui::Spacing();
ImGui::SameLine();
SmallCheckbox( ICON_FA_SHARE " Draw jumps", &m_showJumps );
} }
uint64_t jumpOut = 0; uint64_t jumpOut = 0;
@ -393,14 +401,20 @@ void SourceView::Render( const Worker& worker )
} }
else else
{ {
ImGuiListClipper clipper( (int)m_asm.size() ); const auto th = ImGui::GetTextLineHeightWithSpacing();
ImGuiListClipper clipper( (int)m_asm.size(), th );
while( clipper.Step() ) while( clipper.Step() )
{ {
assert( clipper.StepNo == 3 );
const auto wpos = ImGui::GetCursorScreenPos();
static std::vector<uint64_t> insList;
insList.clear();
if( iptotal == 0 ) if( iptotal == 0 )
{ {
for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ ) for( auto i=clipper.DisplayStart; i<clipper.DisplayEnd; i++ )
{ {
RenderAsmLine( m_asm[i], 0, 0, worker, jumpOut ); RenderAsmLine( m_asm[i], 0, 0, worker, jumpOut );
insList.emplace_back( m_asm[i].addr );
} }
} }
else else
@ -411,6 +425,50 @@ void SourceView::Render( const Worker& worker )
auto it = ipcount.find( line.addr ); auto it = ipcount.find( line.addr );
const auto ipcnt = it == ipcount.end() ? 0 : it->second; const auto ipcnt = it == ipcount.end() ? 0 : it->second;
RenderAsmLine( line, ipcnt, iptotal, worker, jumpOut ); RenderAsmLine( line, ipcnt, iptotal, worker, jumpOut );
insList.emplace_back( line.addr );
}
}
if( m_showJumps && !m_jumpTable.empty() )
{
auto draw = ImGui::GetWindowDrawList();
const auto ts = ImGui::CalcTextSize( " " );
const auto th2 = ts.y / 2;
const auto th4 = ts.y / 4;
const auto xoff = ( iptotal == 0 ? 0 : ( 7 * ts.x + ts.y ) ) + 19 * ts.x + ( m_asmShowSourceLocation ? 36 * ts.x : 0 );
const auto minAddr = m_asm[clipper.DisplayStart].addr;
const auto maxAddr = m_asm[clipper.DisplayEnd-1].addr;
const auto mjl = m_maxJumpLevel;
int i = -1;
for( auto& v : m_jumpTable )
{
i++;
if( v.second.min > maxAddr || v.second.max < minAddr ) continue;
const auto col = GetHsvColor( i, 0 );
if( v.first >= minAddr && v.first <= maxAddr )
{
auto iit = std::lower_bound( insList.begin(), insList.end(), v.first );
assert( iit != insList.end() );
const auto y = ( iit - insList.begin() ) * th;
draw->AddLine( wpos + ImVec2( xoff + JumpSeparation * ( mjl - v.second.level ), y + th2 ), wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow, y + th2 ), col );
draw->AddLine( wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow, y + th2 ), wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow - th4, y + th2 - th4 ), col );
draw->AddLine( wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow, y + th2 ), wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow - th4, y + th2 + th4 ), col );
}
for( auto& s : v.second.source )
{
if( s >= minAddr && s <= maxAddr )
{
auto iit = std::lower_bound( insList.begin(), insList.end(), s );
assert( iit != insList.end() );
const auto y = ( iit - insList.begin() ) * th;
draw->AddLine( wpos + ImVec2( xoff + JumpSeparation * ( mjl - v.second.level ), y + th2 ), wpos + ImVec2( xoff + JumpSeparation * mjl + JumpArrow, y + th2 ), col );
}
}
auto it0 = std::lower_bound( insList.begin(), insList.end(), v.second.min );
auto it1 = std::lower_bound( insList.begin(), insList.end(), v.second.max );
const auto y0 = ( it0 == insList.end() || *it0 != v.second.min ) ? -th : ( it0 - insList.begin() ) * th;
const auto y1 = it1 == insList.end() ? ( insList.size() + 1 ) * th : ( it1 - insList.begin() ) * th;
draw->AddLine( wpos + ImVec2( xoff + JumpSeparation * ( mjl - v.second.level ), y0 + th2 ), wpos + ImVec2( xoff + JumpSeparation * ( mjl - v.second.level ), y1 + th2 ), col );
} }
} }
} }
@ -665,7 +723,14 @@ void SourceView::RenderAsmLine( const AsmLine& line, uint32_t ipcnt, uint32_t ip
ImGui::ItemSize( ImVec2( stw * 32, ty ), 0 ); ImGui::ItemSize( ImVec2( stw * 32, ty ), 0 );
} }
} }
if( m_showJumps )
{
ImGui::SameLine( 0, 2*ty + JumpArrow + m_maxJumpLevel * JumpSeparation );
}
else
{
ImGui::SameLine( 0, ty ); ImGui::SameLine( 0, ty );
}
const auto msz = line.mnemonic.size(); const auto msz = line.mnemonic.size();
memcpy( buf, line.mnemonic.c_str(), msz ); memcpy( buf, line.mnemonic.c_str(), msz );

View File

@ -73,6 +73,7 @@ private:
unordered_flat_map<uint64_t, JumpData> m_jumpTable; unordered_flat_map<uint64_t, JumpData> m_jumpTable;
int m_maxJumpLevel; int m_maxJumpLevel;
bool m_showJumps;
}; };
} }