15
15
#include " lldb/Utility/ConstString.h"
16
16
#include " lldb/Utility/LLDBLog.h"
17
17
#include " lldb/Utility/Log.h"
18
+ #include " llvm/ADT/STLExtras.h"
18
19
#include " llvm/DebugInfo/DIContext.h"
19
20
#include " llvm/DebugInfo/DWARF/DWARFExpression.h"
20
21
#include < optional>
@@ -396,34 +397,34 @@ void UnwindPlan::AppendRow(Row row) {
396
397
*m_row_list.back () = std::move (row);
397
398
}
398
399
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 ();
405
403
}
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 ())
407
412
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
+ }
410
418
}
411
419
412
420
const 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 ())
414
424
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 ();
427
428
}
428
429
429
430
bool UnwindPlan::IsValidRowIndex (uint32_t idx) const {
@@ -442,20 +443,13 @@ const UnwindPlan::Row *UnwindPlan::GetRowAtIndex(uint32_t idx) const {
442
443
443
444
const UnwindPlan::Row *UnwindPlan::GetLastRow () const {
444
445
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" );
447
448
return nullptr ;
448
449
}
449
450
return m_row_list.back ().get ();
450
451
}
451
452
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
-
459
453
bool UnwindPlan::PlanValidAtAddress (Address addr) {
460
454
// If this UnwindPlan has no rows, it is an invalid UnwindPlan.
461
455
if (GetRowCount () == 0 ) {
@@ -479,9 +473,9 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
479
473
// If the 0th Row of unwind instructions is missing, or if it doesn't provide
480
474
// a register to use to find the Canonical Frame Address, this is not a valid
481
475
// 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) {
485
479
Log *log = GetLog (LLDBLog::Unwind);
486
480
if (log ) {
487
481
StreamString s;
@@ -500,17 +494,15 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
500
494
return false ;
501
495
}
502
496
503
- if (!m_plan_valid_address_range.GetBaseAddress ().IsValid () ||
504
- m_plan_valid_address_range.GetByteSize () == 0 )
497
+ if (m_plan_valid_ranges.empty ())
505
498
return true ;
506
499
507
500
if (!addr.IsValid ())
508
501
return true ;
509
502
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
+ });
514
506
}
515
507
516
508
void 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 {
567
559
s.Printf (" not specified.\n " );
568
560
break ;
569
561
}
570
- if (m_plan_valid_address_range.GetBaseAddress ().IsValid () &&
571
- m_plan_valid_address_range.GetByteSize () > 0 ) {
562
+ if (!m_plan_valid_ranges.empty ()) {
572
563
s.PutCString (" Address range of this UnwindPlan: " );
573
564
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);
576
567
s.EOL ();
577
568
}
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 " ;
584
573
}
585
574
}
586
575
0 commit comments