1515#include " lldb/Utility/ConstString.h"
1616#include " lldb/Utility/LLDBLog.h"
1717#include " lldb/Utility/Log.h"
18+ #include " llvm/ADT/STLExtras.h"
1819#include " llvm/DebugInfo/DIContext.h"
1920#include " llvm/DebugInfo/DWARF/DWARFExpression.h"
2021#include < optional>
@@ -396,34 +397,34 @@ void UnwindPlan::AppendRow(Row row) {
396397 *m_row_list.back () = std::move (row);
397398}
398399
399- void UnwindPlan::InsertRow (Row row, bool replace_existing) {
400- collection::iterator it = m_row_list.begin ();
401- while (it != m_row_list.end ()) {
402- if ((*it)->GetOffset () >= row.GetOffset ())
403- break ;
404- it++;
400+ struct RowLess {
401+ bool operator ()(addr_t a, const UnwindPlan::RowSP &b) const {
402+ return a < b->GetOffset ();
405403 }
406- if (it == m_row_list.end () || (*it)->GetOffset () != row.GetOffset ())
404+ bool operator ()(const UnwindPlan::RowSP &a, addr_t b) const {
405+ return a->GetOffset () < b;
406+ }
407+ };
408+
409+ void UnwindPlan::InsertRow (Row row, bool replace_existing) {
410+ auto it = llvm::lower_bound (m_row_list, row.GetOffset (), RowLess ());
411+ if (it == m_row_list.end () || it->get ()->GetOffset () > row.GetOffset ())
407412 m_row_list.insert (it, std::make_shared<Row>(std::move (row)));
408- else if (replace_existing)
409- **it = std::move (row);
413+ else {
414+ assert (it->get ()->GetOffset () == row.GetOffset ());
415+ if (replace_existing)
416+ **it = std::move (row);
417+ }
410418}
411419
412420const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset (int offset) const {
413- if (m_row_list.empty ())
421+ auto it = offset == -1 ? m_row_list.end ()
422+ : llvm::upper_bound (m_row_list, offset, RowLess ());
423+ if (it == m_row_list.begin ())
414424 return nullptr ;
415- if (offset == -1 )
416- return m_row_list.back ().get ();
417-
418- RowSP row;
419- collection::const_iterator pos, end = m_row_list.end ();
420- for (pos = m_row_list.begin (); pos != end; ++pos) {
421- if ((*pos)->GetOffset () <= static_cast <lldb::offset_t >(offset))
422- row = *pos;
423- else
424- break ;
425- }
426- return row.get ();
425+ // upper_bound returns the row strictly greater than our desired offset, which
426+ // means that the row before it is a match.
427+ return std::prev (it)->get ();
427428}
428429
429430bool UnwindPlan::IsValidRowIndex (uint32_t idx) const {
@@ -442,20 +443,13 @@ const UnwindPlan::Row *UnwindPlan::GetRowAtIndex(uint32_t idx) const {
442443
443444const UnwindPlan::Row *UnwindPlan::GetLastRow () const {
444445 if (m_row_list.empty ()) {
445- Log *log = GetLog (LLDBLog::Unwind);
446- LLDB_LOGF (log, " UnwindPlan::GetLastRow() when rows are empty" );
446+ LLDB_LOG ( GetLog (LLDBLog::Unwind),
447+ " UnwindPlan::GetLastRow() when rows are empty" );
447448 return nullptr ;
448449 }
449450 return m_row_list.back ().get ();
450451}
451452
452- int UnwindPlan::GetRowCount () const { return m_row_list.size (); }
453-
454- void UnwindPlan::SetPlanValidAddressRange (const AddressRange &range) {
455- if (range.GetBaseAddress ().IsValid () && range.GetByteSize () != 0 )
456- m_plan_valid_address_range = range;
457- }
458-
459453bool UnwindPlan::PlanValidAtAddress (Address addr) {
460454 // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
461455 if (GetRowCount () == 0 ) {
@@ -479,9 +473,9 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
479473 // If the 0th Row of unwind instructions is missing, or if it doesn't provide
480474 // a register to use to find the Canonical Frame Address, this is not a valid
481475 // UnwindPlan.
482- if ( GetRowAtIndex ( 0 ) == nullptr ||
483- GetRowAtIndex ( 0 )-> GetCFAValue (). GetValueType () ==
484- Row::FAValue::unspecified) {
476+ const Row *row0 = GetRowForFunctionOffset ( 0 );
477+ if (!row0 ||
478+ row0-> GetCFAValue (). GetValueType () == Row::FAValue::unspecified) {
485479 Log *log = GetLog (LLDBLog::Unwind);
486480 if (log) {
487481 StreamString s;
@@ -500,17 +494,15 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
500494 return false ;
501495 }
502496
503- if (!m_plan_valid_address_range.GetBaseAddress ().IsValid () ||
504- m_plan_valid_address_range.GetByteSize () == 0 )
497+ if (m_plan_valid_ranges.empty ())
505498 return true ;
506499
507500 if (!addr.IsValid ())
508501 return true ;
509502
510- if (m_plan_valid_address_range.ContainsFileAddress (addr))
511- return true ;
512-
513- return false ;
503+ return llvm::any_of (m_plan_valid_ranges, [&](const AddressRange &range) {
504+ return range.ContainsFileAddress (addr);
505+ });
514506}
515507
516508void UnwindPlan::Dump (Stream &s, Thread *thread, lldb::addr_t base_addr) const {
@@ -567,20 +559,17 @@ void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const {
567559 s.Printf (" not specified.\n " );
568560 break ;
569561 }
570- if (m_plan_valid_address_range.GetBaseAddress ().IsValid () &&
571- m_plan_valid_address_range.GetByteSize () > 0 ) {
562+ if (!m_plan_valid_ranges.empty ()) {
572563 s.PutCString (" Address range of this UnwindPlan: " );
573564 TargetSP target_sp (thread->CalculateTarget ());
574- m_plan_valid_address_range. Dump (&s, target_sp. get (),
575- Address::DumpStyleSectionNameOffset);
565+ for ( const AddressRange &range : m_plan_valid_ranges)
566+ range. Dump (&s, target_sp. get (), Address::DumpStyleSectionNameOffset);
576567 s.EOL ();
577568 }
578- collection::const_iterator pos, begin = m_row_list.begin (),
579- end = m_row_list.end ();
580- for (pos = begin; pos != end; ++pos) {
581- s.Printf (" row[%u]: " , (uint32_t )std::distance (begin, pos));
582- (*pos)->Dump (s, this , thread, base_addr);
583- s.Printf (" \n " );
569+ for (const auto &[index, row_sp] : llvm::enumerate (m_row_list)) {
570+ s.Format (" row[{0}]: " , index);
571+ row_sp->Dump (s, this , thread, base_addr);
572+ s << " \n " ;
584573 }
585574}
586575
0 commit comments