1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
use crate::{FileLocation, SymbolMap};
/// A "compact" representation of a symbol table.
/// This is a legacy concept used by the Firefox profiler and kept for
/// compatibility purposes. It's called `SymbolTableAsTuple` in the profiler code.
///
/// The string for the address `addrs[i]` is
/// `std::str::from_utf8(buffer[index[i] as usize .. index[i + 1] as usize])`
pub struct CompactSymbolTable {
/// A sorted array of symbol addresses, as library-relative offsets in
/// bytes, in ascending order.
pub addr: Vec<u32>,
/// Contains positions into `buffer`. For every address `addr[i]`,
/// `index[i]` is the position where the string for that address starts in
/// the buffer. Also contains one extra index at the end which is `buffer.len()`.
/// `index.len() == addr.len() + 1`
pub index: Vec<u32>,
/// A buffer of bytes that contains all strings from this symbol table,
/// in the order of the addresses they correspond to, in utf-8 encoded
/// form, all concatenated together.
pub buffer: Vec<u8>,
}
impl CompactSymbolTable {
pub fn from_symbol_map<FL: FileLocation>(map: &SymbolMap<FL>) -> Self {
let total_str_len = map.iter_symbols().map(|(_, s)| s.len()).sum();
let mut addr = Vec::with_capacity(map.symbol_count());
let mut index = Vec::with_capacity(map.symbol_count() + 1);
let mut buffer = Vec::with_capacity(total_str_len);
for (address, name) in map.iter_symbols() {
addr.push(address);
index.push(buffer.len() as u32);
buffer.extend_from_slice(name.as_bytes());
}
index.push(buffer.len() as u32);
Self {
addr,
index,
buffer,
}
}
}