Refactor address_transform.rs to use less memory (#1260)

The crates/debug/src/transform/address_transform.rs is unoptimized in terms of data structures. This PR refactors this file to remove creation of intermediate in-heap structures, thus improves overall performance of the DWARF transformation.

* Reduce amount of memory allocated in translate_ranges_raw
* refactor translate_ranges
* Don't transform non-unit .debug_line
* type annotation for TransformRangeXXXIter's
* Fix empty generated wasm positions
This commit is contained in:
Yury Delendik
2020-03-23 16:36:29 -05:00
committed by GitHub
parent 2fdc7f1a8e
commit 021ebb3748
4 changed files with 233 additions and 89 deletions

View File

@@ -6,9 +6,8 @@ use gimli::{
write, DebugLine, DebugLineOffset, DebugStr, DebuggingInformationEntry, LineEncoding, Unit,
};
use more_asserts::assert_le;
use std::collections::BTreeMap;
use std::iter::FromIterator;
use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::wasm::DefinedFuncIndex;
#[derive(Debug)]
enum SavedLineProgramRow {
@@ -28,10 +27,16 @@ enum SavedLineProgramRow {
EndOfSequence(u64),
}
#[derive(Debug)]
struct FuncRows {
index: DefinedFuncIndex,
sorted_rows: Vec<(u64, SavedLineProgramRow)>,
}
#[derive(Debug, Eq, PartialEq)]
enum ReadLineProgramState {
SequenceEnded,
ReadSequence,
ReadSequence(DefinedFuncIndex),
IgnoreSequence,
}
@@ -119,7 +124,8 @@ where
}
let mut rows = program.rows();
let mut saved_rows = BTreeMap::new();
let mut func_rows = Vec::new();
let mut saved_rows: Vec<(u64, SavedLineProgramRow)> = Vec::new();
let mut state = ReadLineProgramState::SequenceEnded;
while let Some((_header, row)) = rows.next_row()? {
if state == ReadLineProgramState::IgnoreSequence {
@@ -129,6 +135,17 @@ where
continue;
}
let saved_row = if row.end_sequence() {
let index = match state {
ReadLineProgramState::ReadSequence(index) => index,
_ => panic!(),
};
saved_rows.sort_by_key(|r| r.0);
func_rows.push(FuncRows {
index,
sorted_rows: saved_rows,
});
saved_rows = Vec::new();
state = ReadLineProgramState::SequenceEnded;
SavedLineProgramRow::EndOfSequence(row.address())
} else {
@@ -138,7 +155,16 @@ where
state = ReadLineProgramState::IgnoreSequence;
continue;
}
state = ReadLineProgramState::ReadSequence;
match addr_tr.find_func_index(row.address()) {
Some(index) => {
state = ReadLineProgramState::ReadSequence(index);
}
None => {
// Some non-existent address found.
state = ReadLineProgramState::IgnoreSequence;
continue;
}
}
}
SavedLineProgramRow::Normal {
address: row.address(),
@@ -157,15 +183,21 @@ where
isa: row.isa(),
}
};
saved_rows.insert(row.address(), saved_row);
saved_rows.push((row.address(), saved_row));
}
let saved_rows = Vec::from_iter(saved_rows.into_iter());
for (i, map) in addr_tr.map() {
if map.len == 0 {
continue; // no code generated
}
let symbol = i.index();
for FuncRows {
index,
sorted_rows: saved_rows,
} in func_rows
{
let map = match addr_tr.map().get(index) {
Some(map) if map.len > 0 => map,
_ => {
continue; // no code generated
}
};
let symbol = index.index();
let base_addr = map.offset;
out_program.begin_sequence(Some(write::Address::Symbol { symbol, addend: 0 }));
// TODO track and place function declaration line here