Skip to content

Commit 050c09f

Browse files
committed
[lldb][NFCI] Replace use of DWARFAttribute in DWARFAbbreviationDecl
DWARFAttribute is used in 2 classes: DWARFAbbreviationDecl and DWARFAttributes. The former stores a std::vector of them and the latter has a small structure called AttributeValue that contains a DWARFAttribute. DWARFAttributes maintains a llvm::SmallVector of AttributeValues. My end goal is to have `DWARFAttributes` have a llvm::SmallVector specialized on DWARFAttribute. In order to do that, we'll have to move the other elements of AttributeValue into DWARFAttribute itself. But we don't want to do this while DWARFAbbreviationDecl is using DWARFAttribute because it will needlessly increase the size of DWARFAbbreviationDecl. So instead I will create a small type containing only what DWARFAbbreviationDecl needs and call it `AttributeSpec`. This is the exact same thing that LLVM does today. I've elected to swap std::vector for llvm::SmallVector here with a pre-allocated size of 8. I've collected time and memory measurements before this change and after it as well. Using a c++ project with 10,000 object files and no dSYM, I place a breakpoint by file + lineno and see how long it takes to resolve. Before this patch: Time (mean ± σ): 13.577 s ± 0.024 s [User: 12.418 s, System: 1.247 s] Total number of bytes allocated: 1.38 GiB Total number of allocations: 6.47 million allocations After this patch: Time (mean ± σ): 13.287 s ± 0.020 s [User: 12.128 s, System: 1.250 s] Total number of bytes allocated: 1.59 GiB Total number of allocations: 4.61 million allocations So we consume more memory than before, but we actually make less allocations on average. I also measured with an llvm::SmallVector with a pre-allocated size of 4 instead of 8 to measure how well it performs: Time (mean ± σ): 13.246 s ± 0.048 s [User: 12.074 s, System: 1.268 s] Total memory consumption: 1.50 GiB Total number of allocations: 5.74 million Of course this data may look very different depending on the actual program being debugged, but each of the object files had 100+ AbbreviationDeclarations each with between 0 and 10 Attributes, so I feel this was a fair example to consider. Differential Revision: https://reviews.llvm.org/D150418
1 parent b97859b commit 050c09f

File tree

3 files changed

+39
-17
lines changed

3 files changed

+39
-17
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data,
5353
return llvm::make_error<llvm::object::GenericBinaryError>(
5454
"malformed abbreviation declaration attribute");
5555

56-
DWARFFormValue::ValueType val;
56+
if (form == DW_FORM_implicit_const) {
57+
int64_t value = data.GetSLEB128(offset_ptr);
58+
m_attributes.emplace_back(attr, form, value);
59+
continue;
60+
}
5761

58-
if (form == DW_FORM_implicit_const)
59-
val.value.sval = data.GetSLEB128(offset_ptr);
60-
61-
m_attributes.push_back(DWARFAttribute(attr, form, val));
62+
m_attributes.emplace_back(attr, form);
6263
}
6364

6465
return llvm::make_error<llvm::object::GenericBinaryError>(
@@ -72,10 +73,8 @@ bool DWARFAbbreviationDeclaration::IsValid() {
7273

7374
uint32_t
7475
DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const {
75-
uint32_t i;
76-
const uint32_t kNumAttributes = m_attributes.size();
77-
for (i = 0; i < kNumAttributes; ++i) {
78-
if (m_attributes[i].get_attr() == attr)
76+
for (size_t i = 0; i < m_attributes.size(); ++i) {
77+
if (m_attributes[i].GetAttribute() == attr)
7978
return i;
8079
}
8180
return DW_INVALID_INDEX;

lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@
1616

1717
class DWARFAbbreviationDeclaration {
1818
public:
19+
struct AttributeSpec {
20+
AttributeSpec(dw_attr_t attr, dw_form_t form, int64_t value)
21+
: m_attr(attr), m_form(form), m_value(value) {}
22+
23+
AttributeSpec(dw_attr_t attr, dw_form_t form)
24+
: m_attr(attr), m_form(form), m_value(0) {}
25+
26+
bool IsImplicitConst() const {
27+
return m_form == lldb_private::dwarf::DW_FORM_implicit_const;
28+
}
29+
30+
int64_t GetImplicitConstValue() const { return m_value; }
31+
32+
dw_attr_t GetAttribute() const { return m_attr; }
33+
34+
dw_form_t GetForm() const { return m_form; }
35+
36+
private:
37+
dw_attr_t m_attr;
38+
dw_form_t m_form;
39+
int64_t m_value;
40+
};
41+
1942
enum { InvalidCode = 0 };
2043
DWARFAbbreviationDeclaration();
2144

@@ -28,17 +51,21 @@ class DWARFAbbreviationDeclaration {
2851
bool HasChildren() const { return m_has_children; }
2952
size_t NumAttributes() const { return m_attributes.size(); }
3053
dw_form_t GetFormByIndex(uint32_t idx) const {
31-
return m_attributes.size() > idx ? m_attributes[idx].get_form()
54+
return m_attributes.size() > idx ? m_attributes[idx].GetForm()
3255
: dw_form_t(0);
3356
}
3457

3558
// idx is assumed to be valid when calling GetAttrAndFormByIndex()
3659
void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr,
3760
DWARFFormValue &form_value) const {
38-
m_attributes[idx].get(attr, form_value.FormRef(), form_value.ValueRef());
61+
const AttributeSpec &spec = m_attributes[idx];
62+
attr = spec.GetAttribute();
63+
form_value.FormRef() = spec.GetForm();
64+
if (spec.IsImplicitConst())
65+
form_value.SetSigned(spec.GetImplicitConstValue());
3966
}
4067
dw_form_t GetFormByIndexUnchecked(uint32_t idx) const {
41-
return m_attributes[idx].get_form();
68+
return m_attributes[idx].GetForm();
4269
}
4370
uint32_t FindAttributeIndex(dw_attr_t attr) const;
4471

@@ -59,7 +86,7 @@ class DWARFAbbreviationDeclaration {
5986
uint32_t m_code = InvalidCode;
6087
dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
6188
uint8_t m_has_children = 0;
62-
DWARFAttribute::collection m_attributes;
89+
llvm::SmallVector<AttributeSpec, 4> m_attributes;
6390
};
6491

6592
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H

lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class DWARFAttribute {
3131
form = m_form;
3232
val = m_value;
3333
}
34-
typedef std::vector<DWARFAttribute> collection;
35-
typedef collection::iterator iterator;
36-
typedef collection::const_iterator const_iterator;
37-
3834
protected:
3935
dw_attr_t m_attr;
4036
dw_form_t m_form;

0 commit comments

Comments
 (0)