@@ -2,10 +2,11 @@ use criterion::{Bencher, Criterion, criterion_main};
22use std:: hint:: black_box;
33
44use gimli:: {
5- AttributeValue , DebugAbbrev , DebugAddr , DebugAddrBase , DebugAranges , DebugInfo , DebugLine ,
6- DebugLineOffset , DebugLoc , DebugLocLists , DebugPubNames , DebugPubTypes , DebugRanges ,
7- DebugRngLists , Encoding , EndianSlice , EntriesTreeNode , Expression , LittleEndian , LocationLists ,
8- NativeEndian , Operation , RangeLists , RangeListsOffset , Reader , ReaderOffset , leb128,
5+ Attribute , AttributeSpecification , AttributeValue , DebugAbbrev , DebugAddr , DebugAddrBase ,
6+ DebugAranges , DebugInfo , DebugLine , DebugLineOffset , DebugLoc , DebugLocLists , DebugPubNames ,
7+ DebugPubTypes , DebugRanges , DebugRngLists , Encoding , EndianSlice , EntriesRaw , EntriesTreeNode ,
8+ Expression , LittleEndian , LocationLists , NativeEndian , Operation , RangeLists , RangeListsOffset ,
9+ Reader , ReaderOffset , leb128,
910} ;
1011use std:: env;
1112use std:: fs:: File ;
@@ -129,7 +130,11 @@ fn bench_read() {
129130 ) ;
130131 c. bench_function ( "read::EntriesTree" , bench_entries_tree :: < 1 > ) ;
131132 c. bench_function ( "read::EntriesTree (attrs twice)" , bench_entries_tree :: < 2 > ) ;
132- c. bench_function ( "read::EntriesRaw" , bench_entries_raw) ;
133+ c. bench_function ( "read::EntriesRaw::read_attribute" , bench_entries_raw_call) ;
134+ c. bench_function (
135+ "read::EntriesRaw::read_attribute_inline" ,
136+ bench_entries_raw_inline,
137+ ) ;
133138
134139 let mut c = Criterion :: default ( ) . configure_from_args ( ) ;
135140 c. bench_function ( "parse .debug_abbrev" , bench_parsing_debug_abbrev) ;
@@ -291,7 +296,51 @@ fn parse_debug_info_tree<const COUNT: usize, R: Reader>(node: EntriesTreeNode<R>
291296 }
292297}
293298
294- fn bench_entries_raw ( b : & mut Bencher ) {
299+ fn bench_entries_raw_call ( b : & mut Bencher ) {
300+ let debug_abbrev = read_section ( "debug_abbrev" ) ;
301+ let debug_abbrev = DebugAbbrev :: new ( & debug_abbrev, LittleEndian ) ;
302+
303+ let debug_info = read_section ( "debug_info" ) ;
304+
305+ b. iter ( || {
306+ let debug_info = DebugInfo :: new ( & debug_info, LittleEndian ) ;
307+
308+ let mut iter = debug_info. units ( ) ;
309+ while let Some ( unit) = iter. next ( ) . expect ( "Should parse compilation unit" ) {
310+ let abbrevs = unit
311+ . abbreviations ( & debug_abbrev)
312+ . expect ( "Should parse abbreviations" ) ;
313+
314+ let mut raw = unit
315+ . entries_raw ( & abbrevs, None )
316+ . expect ( "Should have entries" ) ;
317+ while !raw. is_empty ( ) {
318+ if let Some ( abbrev) = raw
319+ . read_abbreviation ( )
320+ . expect ( "Should parse abbreviation code" )
321+ {
322+ for spec in abbrev. attributes ( ) . iter ( ) . cloned ( ) {
323+ let attr = read_attribute ( & mut raw, spec) . expect ( "Should parse attribute" ) ;
324+ let name = attr. name ( ) ;
325+ black_box ( name) ;
326+ let value = attr. raw_value ( ) ;
327+ black_box ( value) ;
328+ }
329+ }
330+ }
331+ }
332+ } ) ;
333+ }
334+
335+ #[ inline( never) ]
336+ fn read_attribute < R : Reader > (
337+ input : & mut EntriesRaw < R > ,
338+ spec : AttributeSpecification ,
339+ ) -> gimli:: Result < Attribute < R > > {
340+ input. read_attribute_inline ( spec)
341+ }
342+
343+ fn bench_entries_raw_inline ( b : & mut Bencher ) {
295344 let debug_abbrev = read_section ( "debug_abbrev" ) ;
296345 let debug_abbrev = DebugAbbrev :: new ( & debug_abbrev, LittleEndian ) ;
297346
@@ -315,7 +364,9 @@ fn bench_entries_raw(b: &mut Bencher) {
315364 . expect ( "Should parse abbreviation code" )
316365 {
317366 for spec in abbrev. attributes ( ) . iter ( ) . cloned ( ) {
318- let attr = raw. read_attribute ( spec) . expect ( "Should parse attribute" ) ;
367+ let attr = raw
368+ . read_attribute_inline ( spec)
369+ . expect ( "Should parse attribute" ) ;
319370 let name = attr. name ( ) ;
320371 black_box ( name) ;
321372 let value = attr. raw_value ( ) ;
0 commit comments