Improve performance of BTreeMap::search().last()
This commit is contained in:
committed by
Dan Gohman
parent
cafe821f24
commit
5362bd1a23
@@ -4,7 +4,7 @@ use cranelift_entity::{EntityRef, PrimaryMap};
|
|||||||
use cranelift_wasm::DefinedFuncIndex;
|
use cranelift_wasm::DefinedFuncIndex;
|
||||||
use gimli::write;
|
use gimli::write;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::ops::Bound::{Included, Unbounded};
|
use std::iter::FromIterator;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
pub type GeneratedAddress = usize;
|
pub type GeneratedAddress = usize;
|
||||||
@@ -26,7 +26,10 @@ pub struct FunctionMap {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AddressTransform {
|
pub struct AddressTransform {
|
||||||
lookup: BTreeMap<WasmAddress, (SymbolIndex, GeneratedAddress, GeneratedAddress)>,
|
lookup: Vec<(
|
||||||
|
WasmAddress,
|
||||||
|
(SymbolIndex, GeneratedAddress, GeneratedAddress),
|
||||||
|
)>,
|
||||||
map: PrimaryMap<DefinedFuncIndex, FunctionMap>,
|
map: PrimaryMap<DefinedFuncIndex, FunctionMap>,
|
||||||
func_ranges: Vec<(usize, usize)>,
|
func_ranges: Vec<(usize, usize)>,
|
||||||
}
|
}
|
||||||
@@ -76,6 +79,9 @@ impl AddressTransform {
|
|||||||
addresses: fn_map.into_boxed_slice(),
|
addresses: fn_map.into_boxed_slice(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lookup = Vec::from_iter(lookup.into_iter());
|
||||||
|
|
||||||
AddressTransform {
|
AddressTransform {
|
||||||
lookup,
|
lookup,
|
||||||
map,
|
map,
|
||||||
@@ -92,8 +98,17 @@ impl AddressTransform {
|
|||||||
// It's normally 0 for debug info without the linked code.
|
// It's normally 0 for debug info without the linked code.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let search = self.lookup.range((Unbounded, Included(addr)));
|
let found = match self.lookup.binary_search_by(|entry| entry.0.cmp(&addr)) {
|
||||||
if let Some((_, value)) = search.last() {
|
Ok(i) => Some(&self.lookup[i].1),
|
||||||
|
Err(i) => {
|
||||||
|
if i > 0 {
|
||||||
|
Some(&self.lookup[i - 1].1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(value) = found {
|
||||||
return Some(write::Address::Symbol {
|
return Some(write::Address::Symbol {
|
||||||
symbol: value.0,
|
symbol: value.0,
|
||||||
addend: value.1 as i64,
|
addend: value.1 as i64,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use cranelift_entity::{EntityRef, PrimaryMap};
|
|||||||
use cranelift_wasm::DefinedFuncIndex;
|
use cranelift_wasm::DefinedFuncIndex;
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
use std::ops::Bound::{Included, Unbounded};
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
use gimli;
|
use gimli;
|
||||||
|
|
||||||
@@ -401,6 +401,8 @@ where
|
|||||||
saved_rows.insert(row.address(), saved_row);
|
saved_rows.insert(row.address(), saved_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let saved_rows = Vec::from_iter(saved_rows.into_iter());
|
||||||
|
|
||||||
for (i, map) in addr_tr.map() {
|
for (i, map) in addr_tr.map() {
|
||||||
let symbol = i.index();
|
let symbol = i.index();
|
||||||
let base_addr = map.offset;
|
let base_addr = map.offset;
|
||||||
@@ -408,14 +410,17 @@ where
|
|||||||
// TODO track and place function declaration line here
|
// TODO track and place function declaration line here
|
||||||
let mut last_address = None;
|
let mut last_address = None;
|
||||||
for addr_map in map.addresses.iter() {
|
for addr_map in map.addresses.iter() {
|
||||||
let mut saved_row = saved_rows.get(&addr_map.wasm);
|
let saved_row =
|
||||||
if saved_row.is_none() {
|
match saved_rows.binary_search_by(|entry| entry.0.cmp(&addr_map.wasm)) {
|
||||||
// No direct match -- repeat search with range.
|
Ok(i) => Some(&saved_rows[i].1),
|
||||||
saved_row = saved_rows
|
Err(i) => {
|
||||||
.range((Unbounded, Included(addr_map.wasm)))
|
if i > 0 {
|
||||||
.last()
|
Some(&saved_rows[i - 1].1)
|
||||||
.map(|p| p.1);
|
} else {
|
||||||
}
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
if let Some(SavedLineProgramRow::Normal {
|
if let Some(SavedLineProgramRow::Normal {
|
||||||
address,
|
address,
|
||||||
op_index,
|
op_index,
|
||||||
|
|||||||
Reference in New Issue
Block a user