diff --git a/server/TracySourceView.cpp b/server/TracySourceView.cpp index 7b99fa99..7997cd8b 100644 --- a/server/TracySourceView.cpp +++ b/server/TracySourceView.cpp @@ -4118,27 +4118,50 @@ void SourceView::SelectAsmLines( uint32_t file, uint32_t line, const Worker& wor const auto& addr = *addresses; if( changeAsmLine ) { + for( auto& v : addr ) + { + if( v >= m_baseAddr && v < m_baseAddr + m_codeLen ) + { + m_selectedAddresses.emplace( v ); + } + } if( targetAddr != 0 ) { m_targetAddr = targetAddr; } else { - for( auto& v : addr ) + if( m_asmTarget.file != file || m_asmTarget.line != line ) { - if( v >= m_baseAddr && v < m_baseAddr + m_codeLen ) + m_asmTarget.file = file; + m_asmTarget.line = line; + m_asmTarget.sel = 0; + m_asmTarget.target.clear(); + + std::vector tmp; + tmp.reserve( m_selectedAddresses.size() ); + for( auto& v : m_selectedAddresses ) tmp.emplace_back( v ); + pdqsort_branchless( tmp.begin(), tmp.end() ); + + bool first = true; + auto lit = m_asm.begin(); + for( auto& v : tmp ) { - m_targetAddr = v; - break; + const auto prev = lit; + while( lit->addr != v ) lit++; + if( first || lit - prev > 1 ) + { + first = false; + m_asmTarget.target.emplace_back( v ); + } } + m_targetAddr = m_asmTarget.target[0]; + } + else + { + m_asmTarget.sel = ( m_asmTarget.sel + 1 ) % m_asmTarget.target.size(); + m_targetAddr = m_asmTarget.target[m_asmTarget.sel]; } - } - } - for( auto& v : addr ) - { - if( v >= m_baseAddr && v < m_baseAddr + m_codeLen ) - { - m_selectedAddresses.emplace( v ); } } } diff --git a/server/TracySourceView.hpp b/server/TracySourceView.hpp index 7abdddd5..3d5fed85 100644 --- a/server/TracySourceView.hpp +++ b/server/TracySourceView.hpp @@ -248,6 +248,14 @@ private: GetWindowCallback m_gwcb; Tokenizer m_tokenizer; + + struct + { + uint32_t file = 0; + uint32_t line = 0; + size_t sel; + std::vector target; + } m_asmTarget; }; }