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}