79
79
event_names : Vec < String > ,
80
80
kernel_symbols : Option < KernelSymbols > ,
81
81
kernel_image_mapping : Option < KernelImageMapping > ,
82
- simpleperf_symbol_tables_user : HashMap < Vec < u8 > , SymbolTableFromSimpleperf > ,
83
- simpleperf_symbol_tables_jit : HashMap < Vec < u8 > , Vec < SimpleperfSymbol > > ,
84
- simpleperf_symbol_tables_kernel_image : Option < Vec < SimpleperfSymbol > > ,
85
- simpleperf_symbol_tables_kernel_modules : HashMap < Vec < u8 > , SymbolTableFromSimpleperf > ,
86
- simpleperf_jit_app_cache_library : SyntheticJitLibrary ,
82
+ simpleperf : SimpleperfConverterData ,
87
83
pe_mappings : PeMappings ,
88
84
jit_category_manager : JitCategoryManager ,
89
85
arg_count_to_include_in_process_name : usize ,
@@ -113,6 +109,19 @@ where
113
109
should_emit_cswitch_markers : bool ,
114
110
}
115
111
112
+ struct SimpleperfConverterData {
113
+ symbol_tables : SimpleperfSymbolTables ,
114
+ jit_app_cache_library : SyntheticJitLibrary ,
115
+ }
116
+
117
+ #[ derive( Default ) ]
118
+ struct SimpleperfSymbolTables {
119
+ user : HashMap < Vec < u8 > , SymbolTableFromSimpleperf > ,
120
+ jit : HashMap < Vec < u8 > , Vec < SimpleperfSymbol > > ,
121
+ kernel_image : Option < Vec < SimpleperfSymbol > > ,
122
+ kernel_modules : HashMap < Vec < u8 > , SymbolTableFromSimpleperf > ,
123
+ }
124
+
116
125
const DEFAULT_OFF_CPU_SAMPLING_INTERVAL_NS : u64 = 1_000_000 ; // 1ms
117
126
118
127
impl < U > Converter < U >
@@ -150,81 +159,6 @@ where
150
159
} ;
151
160
let kernel_symbols = KernelSymbols :: new_for_running_kernel ( ) . ok ( ) ;
152
161
153
- let mut simpleperf_symbol_tables_user = HashMap :: new ( ) ;
154
- let mut simpleperf_symbol_tables_jit = HashMap :: new ( ) ;
155
- let mut simpleperf_symbol_tables_kernel_image = None ;
156
- let mut simpleperf_symbol_tables_kernel_modules = HashMap :: new ( ) ;
157
- let simpleperf_jit_category: SubcategoryHandle = profile
158
- . handle_for_category ( Category ( "JIT app cache" , CategoryColor :: Green ) )
159
- . into ( ) ;
160
- let allow_jit_function_recycling = profile_creation_props. reuse_threads ;
161
- let simpleperf_jit_app_cache_library = SyntheticJitLibrary :: new (
162
- "JIT app cache" . to_string ( ) ,
163
- simpleperf_jit_category,
164
- & mut profile,
165
- allow_jit_function_recycling,
166
- ) ;
167
- if let Some ( simpleperf_symbol_tables) = simpleperf_symbol_tables {
168
- let dex_category: SubcategoryHandle = profile
169
- . handle_for_category ( Category ( "DEX" , CategoryColor :: Green ) )
170
- . into ( ) ;
171
- let oat_category: SubcategoryHandle = profile
172
- . handle_for_category ( Category ( "OAT" , CategoryColor :: Green ) )
173
- . into ( ) ;
174
- for f in simpleperf_symbol_tables {
175
- if f. r#type == DSO_KERNEL {
176
- simpleperf_symbol_tables_kernel_image = Some ( f. symbol ) ;
177
- continue ;
178
- }
179
-
180
- let path = f. path . clone ( ) . into_bytes ( ) ;
181
- if is_simpleperf_jit_path ( & f. path ) {
182
- simpleperf_symbol_tables_jit. insert ( path, f. symbol ) ;
183
- continue ;
184
- }
185
-
186
- let is_jit = false ;
187
- let ( category, art_info) = if f. path . ends_with ( ".oat" ) {
188
- ( Some ( oat_category) , Some ( AndroidArtInfo :: JavaFrame ) )
189
- } else if f. r#type == DSO_DEX_FILE || f. path . ends_with ( ".odex" ) || is_jit {
190
- ( Some ( dex_category) , Some ( AndroidArtInfo :: JavaFrame ) )
191
- } else if f. path . ends_with ( "libart.so" ) {
192
- ( None , Some ( AndroidArtInfo :: LibArt ) )
193
- } else {
194
- ( None , None )
195
- } ;
196
-
197
- let ( min_vaddr, file_offset_of_min_vaddr_in_elf_file) = match f. type_specific_msg {
198
- Some ( SimpleperfTypeSpecificInfo :: ElfFile ( elf) ) => {
199
- ( f. min_vaddr , Some ( elf. file_offset_of_min_vaddr ) )
200
- }
201
- _ => ( f. min_vaddr , None ) ,
202
- } ;
203
- let symbols: Vec < _ > = f
204
- . symbol
205
- . iter ( )
206
- . map ( |s| fxprof_processed_profile:: Symbol {
207
- address : s. vaddr as u32 ,
208
- size : Some ( s. len ) ,
209
- name : demangle_any ( & s. name ) ,
210
- } )
211
- . collect ( ) ;
212
- let symbol_table = SymbolTable :: new ( symbols) ;
213
- let symbol_table = SymbolTableFromSimpleperf {
214
- file_offset_of_min_vaddr_in_elf_file,
215
- min_vaddr,
216
- symbol_table : Arc :: new ( symbol_table) ,
217
- category,
218
- art_info,
219
- } ;
220
- if f. r#type == DSO_KERNEL_MODULE {
221
- simpleperf_symbol_tables_kernel_modules. insert ( path, symbol_table) ;
222
- } else {
223
- simpleperf_symbol_tables_user. insert ( path, symbol_table) ;
224
- }
225
- }
226
- }
227
-
228
162
let timestamp_converter = TimestampConverter {
229
163
reference_raw : first_sample_time,
230
164
raw_to_ns_factor : 1 ,
@@ -237,6 +171,12 @@ where
237
171
None
238
172
} ;
239
173
174
+ let simpleperf = SimpleperfConverterData :: new (
175
+ simpleperf_symbol_tables,
176
+ profile_creation_props,
177
+ & mut profile,
178
+ ) ;
179
+
240
180
Self {
241
181
profile,
242
182
cache,
@@ -259,11 +199,7 @@ where
259
199
event_names : interpretation. event_names ,
260
200
kernel_symbols,
261
201
kernel_image_mapping : None ,
262
- simpleperf_symbol_tables_user,
263
- simpleperf_symbol_tables_jit,
264
- simpleperf_symbol_tables_kernel_image,
265
- simpleperf_symbol_tables_kernel_modules,
266
- simpleperf_jit_app_cache_library,
202
+ simpleperf,
267
203
pe_mappings : PeMappings :: new ( ) ,
268
204
jit_category_manager : JitCategoryManager :: new ( ) ,
269
205
fold_recursive_prefix : profile_creation_props. fold_recursive_prefix ,
@@ -279,7 +215,8 @@ where
279
215
280
216
pub fn finish ( mut self ) -> Profile {
281
217
let mut profile = self . profile ;
282
- self . simpleperf_jit_app_cache_library
218
+ self . simpleperf
219
+ . jit_app_cache_library
283
220
. finish_and_set_symbol_table ( & mut profile) ;
284
221
self . processes . finish (
285
222
& mut profile,
@@ -823,7 +760,7 @@ where
823
760
}
824
761
825
762
const PROT_EXEC : u32 = 0b100 ;
826
- if e. protection & PROT_EXEC == 0 && !self . simpleperf_symbol_tables_user . contains_key ( & * path)
763
+ if e. protection & PROT_EXEC == 0 && !self . simpleperf . symbol_tables . user . contains_key ( & * path)
827
764
{
828
765
// Ignore non-executable mappings.
829
766
// Don't ignore mappings that simpleperf found symbols for, even if they're
@@ -1246,7 +1183,7 @@ where
1246
1183
Some ( kernel_symbols. symbol_table . clone ( ) )
1247
1184
}
1248
1185
_ => {
1249
- if let Some ( symbols) = self . simpleperf_symbol_tables_kernel_image . take ( ) {
1186
+ if let Some ( symbols) = self . simpleperf . symbol_tables . kernel_image . take ( ) {
1250
1187
let symbols: Vec < _ > = symbols
1251
1188
. into_iter ( )
1252
1189
. filter_map ( |s| {
@@ -1267,7 +1204,9 @@ where
1267
1204
}
1268
1205
}
1269
1206
} else {
1270
- self . simpleperf_symbol_tables_kernel_modules
1207
+ self . simpleperf
1208
+ . symbol_tables
1209
+ . kernel_modules
1271
1210
. get ( path_slice)
1272
1211
. map ( |s| s. symbol_table . clone ( ) )
1273
1212
} ;
@@ -1335,7 +1274,7 @@ where
1335
1274
. unwrap_or_else ( || ( format ! ( "jit_fun_{address:x}" ) , mapping_size as u32 ) ) ;
1336
1275
1337
1276
let process = self . processes . get_by_pid ( e. pid , & mut self . profile ) ;
1338
- let synthetic_lib = & mut self . simpleperf_jit_app_cache_library ;
1277
+ let synthetic_lib = & mut self . simpleperf . jit_app_cache_library ;
1339
1278
let info = LibMappingInfo :: new_java_mapping (
1340
1279
synthetic_lib. lib_handle ( ) ,
1341
1280
Some ( synthetic_lib. default_category ( ) ) ,
@@ -1348,7 +1287,7 @@ where
1348
1287
path_slice : & [ u8 ] ,
1349
1288
start_avma : u64 ,
1350
1289
) -> Option < ( String , u32 ) > {
1351
- let symbols = self . simpleperf_symbol_tables_jit . get ( path_slice) ?;
1290
+ let symbols = self . simpleperf . symbol_tables . jit . get ( path_slice) ?;
1352
1291
let index = symbols
1353
1292
. binary_search_by_key ( & start_avma, |sym| sym. vaddr )
1354
1293
. ok ( ) ?;
@@ -1413,7 +1352,7 @@ where
1413
1352
1414
1353
// Case 1: There are symbols in the file, if we are importing a perf.data file
1415
1354
// that was recorded with simpleperf.
1416
- if let Some ( symbol_table) = self . simpleperf_symbol_tables_user . get ( original_path) {
1355
+ if let Some ( symbol_table) = self . simpleperf . symbol_tables . user . get ( original_path) {
1417
1356
let relative_address_at_start = if let Some ( file_offset_of_min_vaddr) =
1418
1357
& symbol_table. file_offset_of_min_vaddr_in_elf_file
1419
1358
{
@@ -1754,6 +1693,113 @@ where
1754
1693
}
1755
1694
}
1756
1695
1696
+ impl SimpleperfConverterData {
1697
+ pub fn new (
1698
+ symbol_tables : Option < Vec < SimpleperfFileRecord > > ,
1699
+ profile_creation_props : & ProfileCreationProps ,
1700
+ profile : & mut Profile ,
1701
+ ) -> Self {
1702
+ // See https://source.android.com/docs/core/runtime/jit-compiler#architectural-overview for the
1703
+ // ART JIT architecture and the tiers.
1704
+
1705
+ let jit_category: SubcategoryHandle = profile
1706
+ . handle_for_category ( Category ( "ART JIT" , CategoryColor :: Blue ) )
1707
+ . into ( ) ;
1708
+ let allow_jit_function_recycling = profile_creation_props. reuse_threads ;
1709
+ let jit_app_cache_library = SyntheticJitLibrary :: new (
1710
+ "JIT app cache" . to_string ( ) ,
1711
+ jit_category,
1712
+ profile,
1713
+ allow_jit_function_recycling,
1714
+ ) ;
1715
+
1716
+ Self {
1717
+ symbol_tables : symbol_tables
1718
+ . map ( |st| SimpleperfSymbolTables :: new ( st, profile) )
1719
+ . unwrap_or_default ( ) ,
1720
+ jit_app_cache_library,
1721
+ }
1722
+ }
1723
+ }
1724
+
1725
+ impl SimpleperfSymbolTables {
1726
+ pub fn new ( symbol_tables : Vec < SimpleperfFileRecord > , profile : & mut Profile ) -> Self {
1727
+ let interpreter_category: SubcategoryHandle = profile
1728
+ . handle_for_category ( Category ( "ART Interpreter" , CategoryColor :: Red ) )
1729
+ . into ( ) ;
1730
+ let oat_category: SubcategoryHandle = profile
1731
+ . handle_for_category ( Category (
1732
+ "ART ahead-of-time compiled DEX (OAT)" ,
1733
+ CategoryColor :: Green ,
1734
+ ) )
1735
+ . into ( ) ;
1736
+
1737
+ let mut symbol_tables_user = HashMap :: new ( ) ;
1738
+ let mut symbol_tables_jit = HashMap :: new ( ) ;
1739
+ let mut symbol_tables_kernel_image = None ;
1740
+ let mut symbol_tables_kernel_modules = HashMap :: new ( ) ;
1741
+
1742
+ for f in symbol_tables {
1743
+ if f. r#type == DSO_KERNEL {
1744
+ symbol_tables_kernel_image = Some ( f. symbol ) ;
1745
+ continue ;
1746
+ }
1747
+
1748
+ let path = f. path . clone ( ) . into_bytes ( ) ;
1749
+ if is_simpleperf_jit_path ( & f. path ) {
1750
+ symbol_tables_jit. insert ( path, f. symbol ) ;
1751
+ continue ;
1752
+ }
1753
+
1754
+ let ( category, art_info) = if f. path . ends_with ( ".oat" ) || f. path . ends_with ( ".odex" ) {
1755
+ ( Some ( oat_category) , Some ( AndroidArtInfo :: JavaFrame ) )
1756
+ } else if f. r#type == DSO_DEX_FILE {
1757
+ ( Some ( interpreter_category) , Some ( AndroidArtInfo :: JavaFrame ) )
1758
+ } else if f. path . ends_with ( "libart.so" ) {
1759
+ ( None , Some ( AndroidArtInfo :: LibArt ) )
1760
+ } else {
1761
+ ( None , None )
1762
+ } ;
1763
+
1764
+ let ( min_vaddr, file_offset_of_min_vaddr_in_elf_file) = match f. type_specific_msg {
1765
+ Some ( SimpleperfTypeSpecificInfo :: ElfFile ( elf) ) => {
1766
+ ( f. min_vaddr , Some ( elf. file_offset_of_min_vaddr ) )
1767
+ }
1768
+ _ => ( f. min_vaddr , None ) ,
1769
+ } ;
1770
+ let symbols: Vec < _ > = f
1771
+ . symbol
1772
+ . iter ( )
1773
+ . map ( |s| fxprof_processed_profile:: Symbol {
1774
+ address : s. vaddr as u32 ,
1775
+ size : Some ( s. len ) ,
1776
+ name : demangle_any ( & s. name ) ,
1777
+ } )
1778
+ . collect ( ) ;
1779
+ let symbol_table = SymbolTable :: new ( symbols) ;
1780
+ let symbol_table = SymbolTableFromSimpleperf {
1781
+ file_offset_of_min_vaddr_in_elf_file,
1782
+ min_vaddr,
1783
+ symbol_table : Arc :: new ( symbol_table) ,
1784
+ category,
1785
+ art_info,
1786
+ } ;
1787
+ if f. r#type == DSO_KERNEL_MODULE {
1788
+ symbol_tables_kernel_modules. insert ( path, symbol_table) ;
1789
+ } else {
1790
+ symbol_tables_user. insert ( path, symbol_table) ;
1791
+ }
1792
+ }
1793
+
1794
+ Self {
1795
+ user : symbol_tables_user,
1796
+ jit : symbol_tables_jit,
1797
+ kernel_image : symbol_tables_kernel_image,
1798
+ kernel_modules : symbol_tables_kernel_modules,
1799
+ }
1800
+ }
1801
+ }
1802
+
1757
1803
// #[test]
1758
1804
// fn test_my_jit() {
1759
1805
// let data = std::fs::read("/Users/mstange/Downloads/jitted-123175-0-fixed.so").unwrap();
0 commit comments