Skip to content

Commit 3872503

Browse files
authored
[lldb] Don't hand out UnwindPlan::Row shared_ptrs (#128181)
The whole unwind plan is already stored in a shared pointer, and there's no need to persist Rows individually. If there's ever a need to do that, there are at least two options: - copy the row (they're not that big, and they're being copied left and right during construction already) - use the shared_ptr subobject constructor to create a shared_ptr which points to a Row but holds the entire unwind plan alive This also changes all of the getter functions to return const Row pointers, which is important for safety because all of these objects are cached and potentially accessed from multiple threads. (Technically one could hand out `shared_ptr<const Row>`s, but we don't have a habit of doing that.) As a next step, I'd like to remove the internal UnwindPlan usages of the shared pointer, but I'm doing this separately to gauge feedback, and also because the patch got rather big.
1 parent d3dae84 commit 3872503

File tree

11 files changed

+1007
-1013
lines changed

11 files changed

+1007
-1013
lines changed

lldb/include/lldb/Symbol/UnwindPlan.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ class UnwindPlan {
175175

176176
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len);
177177

178-
const uint8_t *GetDWARFExpressionBytes() {
178+
const uint8_t *GetDWARFExpressionBytes() const {
179179
if (m_type == atDWARFExpression || m_type == isDWARFExpression)
180180
return m_location.expr.opcodes;
181181
return nullptr;
182182
}
183183

184-
int GetDWARFExpressionLength() {
184+
int GetDWARFExpressionLength() const {
185185
if (m_type == atDWARFExpression || m_type == isDWARFExpression)
186186
return m_location.expr.length;
187187
return 0;
@@ -308,13 +308,13 @@ class UnwindPlan {
308308
}
309309
}
310310

311-
const uint8_t *GetDWARFExpressionBytes() {
311+
const uint8_t *GetDWARFExpressionBytes() const {
312312
if (m_type == isDWARFExpression)
313313
return m_value.expr.opcodes;
314314
return nullptr;
315315
}
316316

317-
int GetDWARFExpressionLength() {
317+
int GetDWARFExpressionLength() const {
318318
if (m_type == isDWARFExpression)
319319
return m_value.expr.length;
320320
return 0;
@@ -362,8 +362,10 @@ class UnwindPlan {
362362

363363
void SlideOffset(lldb::addr_t offset) { m_offset += offset; }
364364

365+
const FAValue &GetCFAValue() const { return m_cfa_value; }
365366
FAValue &GetCFAValue() { return m_cfa_value; }
366367

368+
const FAValue &GetAFAValue() const { return m_afa_value; }
367369
FAValue &GetAFAValue() { return m_afa_value; }
368370

369371
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset,
@@ -464,7 +466,7 @@ class UnwindPlan {
464466
// unknown - the final row in the UnwindPlan is returned. In practice, the
465467
// UnwindPlan for a function with no known start address will be the
466468
// architectural default UnwindPlan which will only have one row.
467-
UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const;
469+
const UnwindPlan::Row *GetRowForFunctionOffset(int offset) const;
468470

469471
lldb::RegisterKind GetRegisterKind() const { return m_register_kind; }
470472

@@ -495,9 +497,9 @@ class UnwindPlan {
495497

496498
bool IsValidRowIndex(uint32_t idx) const;
497499

498-
const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const;
500+
const UnwindPlan::Row *GetRowAtIndex(uint32_t idx) const;
499501

500-
const UnwindPlan::RowSP GetLastRow() const;
502+
const UnwindPlan::Row *GetLastRow() const;
501503

502504
lldb_private::ConstString GetSourceName() const;
503505

lldb/include/lldb/Target/RegisterContextUnwind.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ class RegisterContextUnwind : public lldb_private::RegisterContext {
191191

192192
// Get the Frame Address register for a given frame.
193193
bool ReadFrameAddress(lldb::RegisterKind register_kind,
194-
UnwindPlan::Row::FAValue &fa, lldb::addr_t &address);
194+
const UnwindPlan::Row::FAValue &fa,
195+
lldb::addr_t &address);
195196

196197
lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
197198

lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,9 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
116116

117117
// Make a copy of the current instruction Row and save it in m_curr_row
118118
// so we can add updates as we process the instructions.
119-
UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
120-
UnwindPlan::Row *newrow = new UnwindPlan::Row;
121-
if (last_row.get())
122-
*newrow = *last_row.get();
123-
m_curr_row.reset(newrow);
119+
UnwindPlan::RowSP last_row =
120+
std::make_shared<UnwindPlan::Row>(*unwind_plan.GetLastRow());
121+
m_curr_row = std::make_shared<UnwindPlan::Row>(*last_row);
124122

125123
// Add the initial state to the save list with offset 0.
126124
saved_unwind_states.insert({0, {last_row, m_register_values}});

lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
6868
AddressRange &func, Thread &thread, UnwindPlan &unwind_plan) {
6969
bool do_augment_unwindplan = true;
7070

71-
UnwindPlan::RowSP first_row = unwind_plan.GetRowForFunctionOffset(0);
72-
UnwindPlan::RowSP last_row = unwind_plan.GetRowForFunctionOffset(-1);
71+
const UnwindPlan::Row *first_row = unwind_plan.GetRowForFunctionOffset(0);
72+
const UnwindPlan::Row *last_row = unwind_plan.GetLastRow();
7373

7474
int wordsize = 8;
7575
ProcessSP process_sp(thread.GetProcess());

lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
13591359
if (unwind_plan.GetRowCount() < 2)
13601360
return false;
13611361

1362-
UnwindPlan::RowSP first_row = unwind_plan.GetRowAtIndex(0);
1362+
const UnwindPlan::Row *first_row = unwind_plan.GetRowAtIndex(0);
13631363
if (first_row->GetOffset() != 0)
13641364
return false;
13651365
uint32_t cfa_reg = first_row->GetCFAValue().GetRegisterNumber();
@@ -1372,7 +1372,7 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
13721372
first_row->GetCFAValue().GetOffset() != m_wordsize)
13731373
return false;
13741374

1375-
UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset(-1);
1375+
const UnwindPlan::Row *original_last_row = unwind_plan.GetLastRow();
13761376

13771377
size_t offset = 0;
13781378
int row_id = 1;
@@ -1417,7 +1417,7 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
14171417
unwind_plan.GetRowAtIndex(row_id)->GetOffset() <= offset) {
14181418
row_id++;
14191419
}
1420-
UnwindPlan::RowSP original_row = unwind_plan.GetRowAtIndex(row_id - 1);
1420+
const UnwindPlan::Row *original_row = unwind_plan.GetRowAtIndex(row_id - 1);
14211421
if (original_row->GetOffset() == offset) {
14221422
*row = *original_row;
14231423
continue;

lldb/source/Symbol/FuncUnwinders.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,11 +366,11 @@ LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation(
366366
RegisterNumber pc_reg(thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
367367
uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind(eRegisterKindLLDB);
368368

369-
if (a.get() && b.get()) {
370-
UnwindPlan::RowSP a_first_row = a->GetRowAtIndex(0);
371-
UnwindPlan::RowSP b_first_row = b->GetRowAtIndex(0);
369+
if (a && b) {
370+
const UnwindPlan::Row *a_first_row = a->GetRowAtIndex(0);
371+
const UnwindPlan::Row *b_first_row = b->GetRowAtIndex(0);
372372

373-
if (a_first_row.get() && b_first_row.get()) {
373+
if (a_first_row && b_first_row) {
374374
UnwindPlan::Row::AbstractRegisterLocation a_pc_regloc;
375375
UnwindPlan::Row::AbstractRegisterLocation b_pc_regloc;
376376

lldb/source/Symbol/UnwindPlan.cpp

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -412,48 +412,44 @@ void UnwindPlan::InsertRow(const UnwindPlan::RowSP &row_sp,
412412
*it = row_sp;
413413
}
414414

415-
UnwindPlan::RowSP UnwindPlan::GetRowForFunctionOffset(int offset) const {
415+
const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset(int offset) const {
416+
if (m_row_list.empty())
417+
return nullptr;
418+
if (offset == -1)
419+
return m_row_list.back().get();
420+
416421
RowSP row;
417-
if (!m_row_list.empty()) {
418-
if (offset == -1)
419-
row = m_row_list.back();
420-
else {
421-
collection::const_iterator pos, end = m_row_list.end();
422-
for (pos = m_row_list.begin(); pos != end; ++pos) {
423-
if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
424-
row = *pos;
425-
else
426-
break;
427-
}
428-
}
422+
collection::const_iterator pos, end = m_row_list.end();
423+
for (pos = m_row_list.begin(); pos != end; ++pos) {
424+
if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
425+
row = *pos;
426+
else
427+
break;
429428
}
430-
return row;
429+
return row.get();
431430
}
432431

433432
bool UnwindPlan::IsValidRowIndex(uint32_t idx) const {
434433
return idx < m_row_list.size();
435434
}
436435

437-
const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const {
436+
const UnwindPlan::Row *UnwindPlan::GetRowAtIndex(uint32_t idx) const {
438437
if (idx < m_row_list.size())
439-
return m_row_list[idx];
440-
else {
441-
Log *log = GetLog(LLDBLog::Unwind);
442-
LLDB_LOGF(log,
443-
"error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index "
444-
"(number rows is %u)",
445-
idx, (uint32_t)m_row_list.size());
446-
return UnwindPlan::RowSP();
447-
}
438+
return m_row_list[idx].get();
439+
LLDB_LOG(GetLog(LLDBLog::Unwind),
440+
"error: UnwindPlan::GetRowAtIndex(idx = {0}) invalid index "
441+
"(number rows is {1})",
442+
idx, m_row_list.size());
443+
return nullptr;
448444
}
449445

450-
const UnwindPlan::RowSP UnwindPlan::GetLastRow() const {
446+
const UnwindPlan::Row *UnwindPlan::GetLastRow() const {
451447
if (m_row_list.empty()) {
452448
Log *log = GetLog(LLDBLog::Unwind);
453449
LLDB_LOGF(log, "UnwindPlan::GetLastRow() when rows are empty");
454-
return UnwindPlan::RowSP();
450+
return nullptr;
455451
}
456-
return m_row_list.back();
452+
return m_row_list.back().get();
457453
}
458454

459455
int UnwindPlan::GetRowCount() const { return m_row_list.size(); }
@@ -486,7 +482,7 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) {
486482
// If the 0th Row of unwind instructions is missing, or if it doesn't provide
487483
// a register to use to find the Canonical Frame Address, this is not a valid
488484
// UnwindPlan.
489-
if (GetRowAtIndex(0).get() == nullptr ||
485+
if (GetRowAtIndex(0) == nullptr ||
490486
GetRowAtIndex(0)->GetCFAValue().GetValueType() ==
491487
Row::FAValue::unspecified) {
492488
Log *log = GetLog(LLDBLog::Unwind);

lldb/source/Target/RegisterContextUnwind.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ void RegisterContextUnwind::InitializeZerothFrame() {
207207
m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
208208
m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
209209

210-
UnwindPlan::RowSP active_row;
210+
const UnwindPlan::Row *active_row;
211211
lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
212212

213213
// If we have LanguageRuntime UnwindPlan for this unwind, use those
@@ -246,15 +246,15 @@ void RegisterContextUnwind::InitializeZerothFrame() {
246246
active_row =
247247
m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
248248
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
249-
if (active_row.get() && log) {
249+
if (active_row && log) {
250250
StreamString active_row_strm;
251251
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
252252
m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
253253
UnwindLogMsg("%s", active_row_strm.GetData());
254254
}
255255
}
256256

257-
if (!active_row.get()) {
257+
if (!active_row) {
258258
UnwindLogMsg("could not find an unwindplan row for this frame's pc");
259259
m_frame_type = eNotAValidFrame;
260260
return;
@@ -442,8 +442,8 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
442442
m_current_offset = -1;
443443
m_current_offset_backed_up_one = -1;
444444
RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
445-
UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
446-
if (row.get()) {
445+
if (const UnwindPlan::Row *row =
446+
m_full_unwind_plan_sp->GetRowForFunctionOffset(0)) {
447447
if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) {
448448
UnwindLogMsg("failed to get cfa value");
449449
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
@@ -593,7 +593,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
593593
}
594594
}
595595

596-
UnwindPlan::RowSP active_row;
596+
const UnwindPlan::Row *active_row;
597597
RegisterKind row_register_kind = eRegisterKindGeneric;
598598

599599
// If we have LanguageRuntime UnwindPlan for this unwind, use those
@@ -640,7 +640,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
640640
m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
641641
row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
642642
PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
643-
if (active_row.get() && log) {
643+
if (active_row && log) {
644644
StreamString active_row_strm;
645645
active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
646646
m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
@@ -655,7 +655,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
655655
m_current_offset_backed_up_one);
656656
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
657657
PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
658-
if (active_row.get() && log) {
658+
if (active_row && log) {
659659
StreamString active_row_strm;
660660
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
661661
&m_thread,
@@ -667,7 +667,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
667667
}
668668
}
669669

670-
if (!active_row.get()) {
670+
if (!active_row) {
671671
m_frame_type = eNotAValidFrame;
672672
UnwindLogMsg("could not find unwind row for this pc");
673673
return;
@@ -1285,7 +1285,7 @@ RegisterContextUnwind::SavedLocationForRegister(
12851285
RegisterKind unwindplan_registerkind = kNumRegisterKinds;
12861286

12871287
if (m_fast_unwind_plan_sp) {
1288-
UnwindPlan::RowSP active_row =
1288+
const UnwindPlan::Row *active_row =
12891289
m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
12901290
unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind();
12911291
if (regnum.GetAsKind(unwindplan_registerkind) == LLDB_INVALID_REGNUM) {
@@ -1326,12 +1326,12 @@ RegisterContextUnwind::SavedLocationForRegister(
13261326
RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
13271327
LLDB_REGNUM_GENERIC_PC);
13281328

1329-
UnwindPlan::RowSP active_row =
1329+
const UnwindPlan::Row *active_row =
13301330
m_full_unwind_plan_sp->GetRowForFunctionOffset(
13311331
m_current_offset_backed_up_one);
13321332
unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
13331333

1334-
if (got_new_full_unwindplan && active_row.get() && log) {
1334+
if (got_new_full_unwindplan && active_row && log) {
13351335
StreamString active_row_strm;
13361336
ExecutionContext exe_ctx(m_thread.shared_from_this());
13371337
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
@@ -1455,7 +1455,7 @@ RegisterContextUnwind::SavedLocationForRegister(
14551455
if (ForceSwitchToFallbackUnwindPlan()) {
14561456
// Update for the possibly new unwind plan
14571457
unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind();
1458-
UnwindPlan::RowSP active_row =
1458+
const UnwindPlan::Row *active_row =
14591459
m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
14601460

14611461
// Sanity check: Verify that we can fetch a pc value and CFA value
@@ -1799,7 +1799,7 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
17991799

18001800
m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
18011801

1802-
UnwindPlan::RowSP active_row =
1802+
const UnwindPlan::Row *active_row =
18031803
m_fallback_unwind_plan_sp->GetRowForFunctionOffset(
18041804
m_current_offset_backed_up_one);
18051805

@@ -1885,7 +1885,7 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
18851885
return false;
18861886
}
18871887

1888-
UnwindPlan::RowSP active_row =
1888+
const UnwindPlan::Row *active_row =
18891889
m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
18901890

18911891
if (active_row &&
@@ -1967,7 +1967,7 @@ void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
19671967
}
19681968

19691969
bool RegisterContextUnwind::ReadFrameAddress(
1970-
lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
1970+
lldb::RegisterKind row_register_kind, const UnwindPlan::Row::FAValue &fa,
19711971
addr_t &address) {
19721972
RegisterValue reg_value;
19731973

0 commit comments

Comments
 (0)