Skip to content

Commit c1eadfb

Browse files
committed
Add AccessPatternHint::SequentialLookup.
1 parent 524f322 commit c1eadfb

File tree

5 files changed

+70
-31
lines changed

5 files changed

+70
-31
lines changed

samply-api/src/symbolicate/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::collections::HashMap;
22
use std::sync::Arc;
33

44
use samply_symbols::{
5-
FileAndPathHelper, FramesLookupResult, LibraryInfo, LookupAddress, SourceFilePath,
6-
SourceFilePathHandle, SymbolManager, SymbolMap,
5+
AccessPatternHint, FileAndPathHelper, FramesLookupResult, LibraryInfo, LookupAddress,
6+
SourceFilePath, SourceFilePathHandle, SymbolManager, SymbolMap,
77
};
88

99
use crate::error::Error;
@@ -94,6 +94,7 @@ impl<'a, H: FileAndPathHelper + 'static> SymbolicateApi<'a, H> {
9494
..Default::default()
9595
};
9696
let symbol_map = self.symbol_manager.load_symbol_map(&info).await?;
97+
symbol_map.set_access_pattern_hint(AccessPatternHint::SequentialLookup);
9798
let mut symbolication_result = LookedUpAddresses::for_addresses(&addresses);
9899

99100
symbolication_result.set_total_symbol_count(symbol_map.symbol_count() as u32);

samply-symbols/src/breakpad/index.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ pub enum BreakpadParseError {
789789
NoModuleInfoInSymFile,
790790
}
791791

792-
#[derive(Debug, Clone)]
792+
#[derive(Debug, Clone, Copy)]
793793
pub struct BreakpadPublicSymbolInfo<'a> {
794794
pub name: &'a str,
795795
}

samply-symbols/src/breakpad/symbol_map.rs

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::generation::SymbolMapGeneration;
1818
use crate::source_file_path::SourceFilePathHandle;
1919
use crate::symbol_map::{GetInnerSymbolMap, SymbolMapTrait};
2020
use crate::{
21-
Error, FileContents, FileContentsWrapper, FrameDebugInfo, FramesLookupResult, LookupAddress,
22-
SourceFilePath, SymbolInfo, SyncAddressInfo,
21+
AccessPatternHint, Error, FileContents, FileContentsWrapper, FrameDebugInfo,
22+
FramesLookupResult, LookupAddress, SourceFilePath, SymbolInfo, SyncAddressInfo,
2323
};
2424

2525
pub fn get_symbol_map_for_breakpad_sym<FC: FileContents + 'static>(
@@ -138,6 +138,7 @@ struct BreakpadSymbolMapSymbolCache<'a> {
138138
func_symbols: HashMap<u64, BreakpadFuncSymbolInfo<'a>>,
139139
lines: Vec<SourceLine>,
140140
inlinees: Vec<Inlinee>,
141+
only_store_latest: bool,
141142
}
142143

143144
impl<'a, T: FileContents> BreakpadSymbolMapCache<'a, T> {
@@ -151,24 +152,27 @@ impl<'a, T: FileContents> BreakpadSymbolMapCache<'a, T> {
151152
}
152153

153154
impl<'a> BreakpadSymbolMapSymbolCache<'a> {
154-
pub fn get_public_info<'s, T: FileContents>(
155-
&'s mut self,
155+
pub fn get_public_info<T: FileContents>(
156+
&mut self,
156157
file_offset: u64,
157158
line_length: u32,
158159
data: &'a FileContentsWrapper<T>,
159-
) -> Result<&'s BreakpadPublicSymbolInfo<'a>, Error> {
160-
match self.public_symbols.entry(file_offset) {
161-
Entry::Occupied(info) => Ok(info.into_mut()),
162-
Entry::Vacant(vacant) => {
163-
let line = data
164-
.read_bytes_at(file_offset, line_length.into())
165-
.map_err(|e| {
166-
Error::HelperErrorDuringFileReading("Breakpad PUBLIC symbol".to_string(), e)
167-
})?;
168-
let info = BreakpadPublicSymbol::parse(line)?;
169-
Ok(vacant.insert(info))
170-
}
160+
) -> Result<BreakpadPublicSymbolInfo<'a>, Error> {
161+
if let Some(info) = self.public_symbols.get(&file_offset) {
162+
return Ok(*info);
171163
}
164+
165+
self.clear_if_saving_memory();
166+
167+
let line = data
168+
.read_bytes_at(file_offset, line_length.into())
169+
.map_err(|e| {
170+
Error::HelperErrorDuringFileReading("Breakpad PUBLIC symbol".to_string(), e)
171+
})?;
172+
let info = BreakpadPublicSymbol::parse(line)?;
173+
self.public_symbols.insert(file_offset, info);
174+
175+
Ok(info)
172176
}
173177

174178
pub fn get_func_info<'s, T: FileContents>(
@@ -177,17 +181,28 @@ impl<'a> BreakpadSymbolMapSymbolCache<'a> {
177181
block_length: u32,
178182
data: &'a FileContentsWrapper<T>,
179183
) -> Result<BreakpadFuncSymbolInfo<'a>, Error> {
180-
match self.func_symbols.entry(file_offset) {
181-
Entry::Occupied(info) => Ok(*info.get()),
182-
Entry::Vacant(vacant) => {
183-
let block = data
184-
.read_bytes_at(file_offset, block_length.into())
185-
.map_err(|e| {
186-
Error::HelperErrorDuringFileReading("Breakpad FUNC symbol".to_string(), e)
187-
})?;
188-
let info = BreakpadFuncSymbol::parse(block, &mut self.lines, &mut self.inlinees)?;
189-
Ok(*vacant.insert(info))
190-
}
184+
if let Some(info) = self.func_symbols.get(&file_offset) {
185+
return Ok(*info);
186+
}
187+
188+
self.clear_if_saving_memory();
189+
190+
let block = data
191+
.read_bytes_at(file_offset, block_length.into())
192+
.map_err(|e| {
193+
Error::HelperErrorDuringFileReading("Breakpad FUNC symbol".to_string(), e)
194+
})?;
195+
let info = BreakpadFuncSymbol::parse(block, &mut self.lines, &mut self.inlinees)?;
196+
self.func_symbols.insert(file_offset, info);
197+
Ok(info)
198+
}
199+
200+
fn clear_if_saving_memory(&mut self) {
201+
if self.only_store_latest {
202+
self.public_symbols.clear();
203+
self.func_symbols.clear();
204+
self.inlinees.clear();
205+
self.lines.clear();
191206
}
192207
}
193208
}
@@ -385,6 +400,11 @@ impl<'object, T: FileContents> SymbolMapTrait for BreakpadSymbolMapInner<'object
385400
let s = cache.files.get_string(index.0).ok().unwrap_or("<missing>");
386401
SourceFilePath::BreakpadSpecialPathStr(Cow::Borrowed(s))
387402
}
403+
404+
fn set_access_pattern_hint(&self, hint: AccessPatternHint) {
405+
let mut cache = self.cache.lock().unwrap();
406+
cache.symbols.only_store_latest = hint == AccessPatternHint::SequentialLookup;
407+
}
388408
}
389409

390410
#[cfg(test)]

samply-symbols/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ pub use crate::shared::{
260260
MultiArchDisambiguator, OptionallySendFuture, PeCodeId, SymbolInfo, SyncAddressInfo,
261261
};
262262
pub use crate::source_file_path::{SourceFilePath, SourceFilePathHandle, SourceFilePathIndex};
263-
pub use crate::symbol_map::{SymbolMap, SymbolMapTrait};
263+
pub use crate::symbol_map::{AccessPatternHint, SymbolMap, SymbolMapTrait};
264264

265265
pub struct SymbolManager<H: FileAndPathHelper> {
266266
helper: Arc<H>,

samply-symbols/src/symbol_map.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ pub trait SymbolMapTrait {
2626
fn lookup_sync(&self, address: LookupAddress) -> Option<SyncAddressInfo>;
2727

2828
fn resolve_source_file_path(&self, handle: SourceFilePathHandle) -> SourceFilePath<'_>;
29+
30+
fn set_access_pattern_hint(&self, _hint: AccessPatternHint) {}
31+
}
32+
33+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
34+
pub enum AccessPatternHint {
35+
Arbitrary,
36+
37+
/// Indicates that lookup calls will happen with addresses in ascending
38+
/// order. This lets the symbol map to save memory because it can discard
39+
/// cached information about functions other than the one that contains
40+
/// the current address, because those earlier functions cover lower
41+
/// addresses and their information will not be needed by higher addresses.
42+
SequentialLookup,
2943
}
3044

3145
pub trait SymbolMapTraitWithExternalFileSupport<FC>: SymbolMapTrait {
@@ -220,4 +234,8 @@ impl<H: FileAndPathHelper> SymbolMap<H> {
220234
pub fn resolve_source_file_path(&self, handle: SourceFilePathHandle) -> SourceFilePath<'_> {
221235
self.inner().resolve_source_file_path(handle)
222236
}
237+
238+
pub fn set_access_pattern_hint(&self, hint: AccessPatternHint) {
239+
self.inner().set_access_pattern_hint(hint);
240+
}
223241
}

0 commit comments

Comments
 (0)