@@ -2,20 +2,19 @@ use std::collections::HashMap;
22use std:: sync:: Arc ;
33
44use 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
99use crate :: error:: Error ;
10- use crate :: symbolicate:: looked_up_addresses:: PathResolver ;
10+ use crate :: symbolicate:: looked_up_addresses:: { AddressResult , AddressResults , PathResolver } ;
1111use crate :: symbolicate:: response_json:: { PerLibResult , Response } ;
1212use crate :: to_debug_id;
1313
1414pub mod looked_up_addresses;
1515pub mod request_json;
1616pub mod response_json;
1717
18- use looked_up_addresses:: LookedUpAddresses ;
1918use request_json:: Lib ;
2019
2120impl < H : FileAndPathHelper > PathResolver for SymbolMap < H > {
@@ -63,7 +62,7 @@ impl<'a, H: FileAndPathHelper + 'static> SymbolicateApi<'a, H> {
6362 let mut symbolicated_addresses = HashMap :: new ( ) ;
6463 for ( lib, addresses) in requested_addresses. into_iter ( ) {
6564 let address_results = self
66- . symbolicate_requested_addresses_for_lib ( & lib, addresses)
65+ . symbolicate_requested_addresses_for_lib ( & lib, & addresses)
6766 . await ;
6867 symbolicated_addresses. insert ( lib, address_results) ;
6968 }
@@ -73,48 +72,42 @@ impl<'a, H: FileAndPathHelper + 'static> SymbolicateApi<'a, H> {
7372 async fn symbolicate_requested_addresses_for_lib (
7473 & self ,
7574 lib : & Lib ,
76- mut addresses : Vec < u32 > ,
75+ addresses : & [ u32 ] ,
7776 ) -> Result < PerLibResult < H > , samply_symbols:: Error > {
78- // Sort the addresses before the lookup, to have a higher chance of hitting
79- // the same external file for subsequent addresses.
80- addresses. sort_unstable ( ) ;
81- addresses. dedup ( ) ;
82-
8377 let debug_id = to_debug_id ( & lib. breakpad_id ) ?;
8478
85- let mut external_addresses = Vec :: new ( ) ;
86-
87- // Do the synchronous work first, and accumulate external_addresses which need
88- // to be handled asynchronously. This allows us to group async file loads by
89- // the external file.
90-
9179 let info = LibraryInfo {
9280 debug_name : Some ( lib. debug_name . to_string ( ) ) ,
9381 debug_id : Some ( debug_id) ,
9482 ..Default :: default ( )
9583 } ;
9684 let symbol_map = self . symbol_manager . load_symbol_map ( & info) . await ?;
97- let mut symbolication_result = LookedUpAddresses :: for_addresses ( & addresses) ;
98-
99- symbolication_result. set_total_symbol_count ( symbol_map. symbol_count ( ) as u32 ) ;
100-
101- for & address in & addresses {
102- if let Some ( address_info) = symbol_map. lookup_sync ( LookupAddress :: Relative ( address) ) {
103- symbolication_result. add_address_symbol (
104- address,
105- address_info. symbol . address ,
106- address_info. symbol . name ,
107- address_info. symbol . size ,
108- ) ;
109- match address_info. frames {
110- Some ( FramesLookupResult :: Available ( frames) ) => {
111- symbolication_result. add_address_debug_info ( address, frames)
112- }
113- Some ( FramesLookupResult :: External ( ext_address) ) => {
114- external_addresses. push ( ( address, ext_address) ) ;
115- }
116- None => { }
85+
86+ // Create a BTreeMap for the lookup results. This lets us iterate over the
87+ // addresses in ascending order - the sort happens when the map is created.
88+ let mut address_results: AddressResults =
89+ addresses. iter ( ) . map ( |& addr| ( addr, None ) ) . collect ( ) ;
90+ symbol_map. set_access_pattern_hint ( AccessPatternHint :: SequentialLookup ) ;
91+
92+ // Do the synchronous work first, and accumulate external_addresses which need
93+ // to be handled asynchronously. This allows us to group async file loads by
94+ // the external file.
95+ let mut external_addresses = Vec :: new ( ) ;
96+
97+ for ( & address, address_result) in & mut address_results {
98+ let Some ( address_info) = symbol_map. lookup_sync ( LookupAddress :: Relative ( address) )
99+ else {
100+ continue ;
101+ } ;
102+ * address_result = Some ( AddressResult :: new ( address_info. symbol ) ) ;
103+ match address_info. frames {
104+ Some ( FramesLookupResult :: Available ( frames) ) => {
105+ address_result. as_mut ( ) . unwrap ( ) . set_debug_info ( frames)
106+ }
107+ Some ( FramesLookupResult :: External ( ext_address) ) => {
108+ external_addresses. push ( ( address, ext_address) ) ;
117109 }
110+ None => { }
118111 }
119112 }
120113
@@ -126,12 +119,13 @@ impl<'a, H: FileAndPathHelper + 'static> SymbolicateApi<'a, H> {
126119
127120 for ( address, ext_address) in external_addresses {
128121 if let Some ( frames) = symbol_map. lookup_external ( & ext_address) . await {
129- symbolication_result. add_address_debug_info ( address, frames) ;
122+ let address_result = address_results. get_mut ( & address) . unwrap ( ) ;
123+ address_result. as_mut ( ) . unwrap ( ) . set_debug_info ( frames) ;
130124 }
131125 }
132126
133127 let outcome = PerLibResult {
134- address_results : symbolication_result ,
128+ address_results,
135129 symbol_map : Arc :: new ( symbol_map) ,
136130 } ;
137131
0 commit comments