Skip to content

Commit e024ccc

Browse files
authored
write: reserve capacity for attribute Vecs during conversion (#829)
This reduces the cost of their allocation. Avoiding them completely would be better, but that requires a more complex API.
1 parent cdaed4e commit e024ccc

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

src/write/unit.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl Unit {
184184
let ranges = RangeListTable::default();
185185
let locations = LocationListTable::default();
186186
let root = UnitEntryId::new(base_id, 0);
187-
let mut entry = DebuggingInformationEntry::reserve(root);
187+
let mut entry = DebuggingInformationEntry::new_reserved(root);
188188
entry.tag = constants::DW_TAG_compile_unit;
189189
let entries = vec![entry];
190190
let offsets = UnitOffsets {
@@ -273,7 +273,8 @@ impl Unit {
273273
pub fn add_reserved(&mut self, child: UnitEntryId, parent: UnitEntryId, tag: constants::DwTag) {
274274
while self.entries.len() < self.reserved {
275275
let id = UnitEntryId::new(self.base_id, self.entries.len());
276-
self.entries.push(DebuggingInformationEntry::reserve(id));
276+
self.entries
277+
.push(DebuggingInformationEntry::new_reserved(id));
277278
}
278279
let entry = self.get_mut(child);
279280
debug_assert_eq!(entry.parent, None);
@@ -499,7 +500,7 @@ pub struct DebuggingInformationEntry {
499500

500501
impl DebuggingInformationEntry {
501502
/// Create a new `DebuggingInformationEntry`.
502-
fn reserve(id: UnitEntryId) -> Self {
503+
fn new_reserved(id: UnitEntryId) -> Self {
503504
DebuggingInformationEntry {
504505
id,
505506
parent: None,
@@ -570,6 +571,14 @@ impl DebuggingInformationEntry {
570571
.map(|attr| &mut attr.value)
571572
}
572573

574+
/// Reserve capacity for additional attributes.
575+
///
576+
/// This may give a performance improvement when the number of attributes
577+
/// is known.
578+
pub fn reserve(&mut self, additional: usize) {
579+
self.attrs.reserve(additional);
580+
}
581+
573582
/// Set an attribute.
574583
///
575584
/// Replaces any existing attribute with the same name.
@@ -578,7 +587,7 @@ impl DebuggingInformationEntry {
578587
///
579588
/// Panics if `name` is `DW_AT_sibling`. Use `set_sibling` instead.
580589
pub fn set(&mut self, name: constants::DwAt, value: AttributeValue) {
581-
assert_ne!(name, constants::DW_AT_sibling);
590+
debug_assert_ne!(name, constants::DW_AT_sibling);
582591
if let Some(attr) = self.attrs.iter_mut().find(|attr| attr.name == name) {
583592
attr.value = value;
584593
return;
@@ -587,8 +596,6 @@ impl DebuggingInformationEntry {
587596
}
588597

589598
/// Delete an attribute.
590-
///
591-
/// Replaces any existing attribute with the same name.
592599
pub fn delete(&mut self, name: constants::DwAt) {
593600
self.attrs.retain(|x| x.name != name);
594601
}
@@ -1805,6 +1812,7 @@ pub(crate) mod convert {
18051812
entries: &mut read::EntriesRaw<'_, '_, R>,
18061813
specs: &[read::AttributeSpecification],
18071814
) -> ConvertResult<()> {
1815+
entry.attrs.reserve(specs.len());
18081816
for spec in specs {
18091817
let attr = entries.read_attribute(*spec)?;
18101818
match attr.name() {
@@ -2585,18 +2593,17 @@ pub(crate) mod convert {
25852593
entry: &ConvertUnitEntry<'_, R>,
25862594
) -> UnitEntryId {
25872595
let parent = entry.parent.unwrap_or(self.unit.root());
2588-
match id {
2596+
let id = match id {
25892597
Some(id) => {
25902598
self.unit.add_reserved(id, parent, entry.tag);
2591-
self.unit.get_mut(id).set_sibling(entry.sibling);
25922599
id
25932600
}
2594-
None => {
2595-
let id = self.unit.add(parent, entry.tag);
2596-
self.unit.get_mut(id).set_sibling(entry.sibling);
2597-
id
2598-
}
2599-
}
2601+
None => self.unit.add(parent, entry.tag),
2602+
};
2603+
let new_entry = self.unit.get_mut(id);
2604+
new_entry.set_sibling(entry.sibling);
2605+
new_entry.reserve(entry.attrs.len());
2606+
id
26002607
}
26012608

26022609
/// Write the unit to the given sections.
@@ -2968,6 +2975,7 @@ pub(crate) mod convert {
29682975
from_entries: &mut read::EntriesRaw<'_, '_, R>,
29692976
specs: &[read::AttributeSpecification],
29702977
) -> ConvertResult<()> {
2978+
self.attrs.reserve(specs.len());
29712979
for spec in specs {
29722980
let attr = from_entries.read_attribute(*spec)?;
29732981
match attr.name() {

0 commit comments

Comments
 (0)