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