@@ -8,13 +8,14 @@ use crate::compile::benchmark::BenchmarkName;
8
8
use crate :: toolchain:: Toolchain ;
9
9
use crate :: utils:: fs:: EnsureImmutableFile ;
10
10
use crate :: { async_command_output, command_output, utils} ;
11
+ use analyzeme:: ArtifactSize ;
11
12
use anyhow:: Context ;
12
13
use bencher:: Bencher ;
13
- use database:: QueryLabel ;
14
14
use std:: collections:: HashMap ;
15
15
use std:: env;
16
16
use std:: fs;
17
17
use std:: future:: Future ;
18
+ use std:: io:: ErrorKind ;
18
19
use std:: path:: { Path , PathBuf } ;
19
20
use std:: pin:: Pin ;
20
21
use std:: process:: { self , Command } ;
@@ -467,7 +468,7 @@ fn store_artifact_sizes_into_stats(stats: &mut Stats, profile: &SelfProfile) {
467
468
for artifact in profile. artifact_sizes . iter ( ) {
468
469
stats
469
470
. stats
470
- . insert ( format ! ( "size:{}" , artifact. label) , artifact. size as f64 ) ;
471
+ . insert ( format ! ( "size:{}" , artifact. label) , artifact. value as f64 ) ;
471
472
}
472
473
}
473
474
@@ -479,6 +480,8 @@ enum DeserializeStatError {
479
480
ParseError ( String , #[ source] :: std:: num:: ParseFloatError ) ,
480
481
#[ error( "could not process xperf data" ) ]
481
482
XperfError ( #[ from] anyhow:: Error ) ,
483
+ #[ error( "io error" ) ]
484
+ IOError ( #[ from] std:: io:: Error ) ,
482
485
}
483
486
484
487
enum SelfProfileFiles {
@@ -574,7 +577,7 @@ fn process_stat_output(
574
577
return Err ( DeserializeStatError :: NoOutput ( output) ) ;
575
578
}
576
579
let ( profile, files) = match ( self_profile_dir, self_profile_crate) {
577
- ( Some ( dir) , Some ( krate) ) => parse_self_profile ( dir, krate) ,
580
+ ( Some ( dir) , Some ( krate) ) => parse_self_profile ( dir, krate) ? ,
578
581
_ => ( None , None ) ,
579
582
} ;
580
583
Ok ( ( stats, profile, files) )
@@ -616,115 +619,41 @@ pub struct SelfProfile {
616
619
pub artifact_sizes : Vec < ArtifactSize > ,
617
620
}
618
621
619
- #[ derive( serde:: Deserialize , Clone ) ]
620
- pub struct ArtifactSize {
621
- pub label : QueryLabel ,
622
- #[ serde( rename = "value" ) ]
623
- pub size : u64 ,
624
- }
625
-
626
622
fn parse_self_profile (
627
623
dir : PathBuf ,
628
624
crate_name : String ,
629
- ) -> ( Option < SelfProfile > , Option < SelfProfileFiles > ) {
630
- // First, find the mm_profdata file prefix, or a single file containing the self-profile
631
- // results.
632
- let mut prefix = None ;
625
+ ) -> std:: io:: Result < ( Option < SelfProfile > , Option < SelfProfileFiles > ) > {
626
+ // First, find the `.mm_profdata` file with the self-profile data.
633
627
let mut full_path = None ;
634
628
// We don't know the pid of rustc, and can't easily get it -- we only know the
635
629
// `perf` pid. So just blindly look in the directory to hopefully find it.
636
- for entry in fs:: read_dir ( & dir) . unwrap ( ) {
637
- let entry = entry. unwrap ( ) ;
638
- if entry
639
- . file_name ( )
640
- . to_str ( )
641
- . map_or ( false , |s| s. starts_with ( & crate_name) )
642
- {
643
- if entry. file_name ( ) . to_str ( ) . unwrap ( ) . ends_with ( "mm_profdata" ) {
644
- full_path = Some ( entry. path ( ) ) ;
645
- break ;
646
- }
647
- let file = entry. file_name ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) ;
648
- let new_prefix = Some ( file[ ..file. find ( '.' ) . unwrap ( ) ] . to_owned ( ) ) ;
649
- assert ! (
650
- prefix. is_none( ) || prefix == new_prefix,
651
- "prefix={:?}, new_prefix={:?}" ,
652
- prefix,
653
- new_prefix
654
- ) ;
655
- prefix = new_prefix;
630
+ for entry in fs:: read_dir ( dir) ? {
631
+ let entry = entry?;
632
+ if entry. file_name ( ) . to_str ( ) . map_or ( false , |s| {
633
+ s. starts_with ( & crate_name) && s. ends_with ( "mm_profdata" )
634
+ } ) {
635
+ full_path = Some ( entry. path ( ) ) ;
636
+ break ;
656
637
}
657
638
}
658
639
let ( profile, files) = if let Some ( profile_path) = full_path {
659
- // measureme 0.8 has a single file
660
- let filename = profile_path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
661
- let json = run_summarize ( "summarize" , & dir, filename)
662
- . unwrap_or_else ( |e1| match run_summarize ( "summarize-9.0" , & dir, filename) {
663
- Ok ( s) => s,
664
- Err ( e2) => {
665
- panic ! ( "failed to run summarize and summarize-9.0. Errors:\n summarize: {:?}\n summarize-9.0: {:?}" , e1, e2) ;
666
- }
667
- } ) ;
668
- let profile: SelfProfile = serde_json:: from_str ( & json) . unwrap ( ) ;
669
- ( profile, SelfProfileFiles :: Eight { file : profile_path } )
670
- } else {
671
- let Some ( prefix) = prefix else {
672
- return ( None , None ) ;
640
+ // measureme 0.8+ uses a single file
641
+ let data = fs:: read ( & profile_path) ?;
642
+ let results = analyzeme:: ProfilingData :: from_paged_buffer ( data, None )
643
+ . map_err ( |error| {
644
+ eprintln ! ( "Cannot read self-profile data: {error:?}" ) ;
645
+ std:: io:: Error :: new ( ErrorKind :: InvalidData , error)
646
+ } ) ?
647
+ . perform_analysis ( ) ;
648
+ let profile = SelfProfile {
649
+ artifact_sizes : results. artifact_sizes ,
673
650
} ;
674
-
675
- let mut string_index = PathBuf :: new ( ) ;
676
- let mut string_data = PathBuf :: new ( ) ;
677
- let mut events = PathBuf :: new ( ) ;
678
- for entry in fs:: read_dir ( & dir) . unwrap ( ) {
679
- let filename = entry. unwrap ( ) . file_name ( ) ;
680
- let filename_str = filename. to_str ( ) . unwrap ( ) ;
681
- let path = dir. join ( filename_str) ;
682
- if filename_str. ends_with ( ".events" ) {
683
- assert ! ( filename_str. contains( & prefix) , "{:?}" , path) ;
684
- events = path;
685
- } else if filename_str. ends_with ( ".string_data" ) {
686
- assert ! ( filename_str. contains( & prefix) , "{:?}" , path) ;
687
- string_data = path;
688
- } else if filename_str. ends_with ( ".string_index" ) {
689
- assert ! ( filename_str. contains( & prefix) , "{:?}" , path) ;
690
- string_index = path;
691
- }
692
- }
693
-
694
- let files = SelfProfileFiles :: Seven {
695
- string_index,
696
- string_data,
697
- events,
698
- } ;
699
-
700
- let json = run_summarize ( "summarize" , & dir, & prefix)
701
- . or_else ( |_| run_summarize ( "summarize-0.7" , & dir, & prefix) )
702
- . expect ( "able to run summarize or summarize-0.7" ) ;
703
- let profile: SelfProfile = serde_json:: from_str ( & json) . unwrap ( ) ;
704
- ( profile, files)
651
+ let files = SelfProfileFiles :: Eight { file : profile_path } ;
652
+ ( Some ( profile) , Some ( files) )
653
+ } else {
654
+ // The old "3 files format" is not supported by analyzeme anymore, so we don't handle it
655
+ // here.
656
+ ( None , None )
705
657
} ;
706
- ( Some ( profile) , Some ( files) )
707
- }
708
-
709
- fn run_summarize ( name : & str , prof_out_dir : & Path , prefix : & str ) -> anyhow:: Result < String > {
710
- let mut cmd = Command :: new ( name) ;
711
- cmd. current_dir ( prof_out_dir) ;
712
- cmd. arg ( "summarize" ) . arg ( "--json" ) ;
713
- cmd. arg ( prefix) ;
714
- let status = cmd
715
- . status ( )
716
- . with_context ( || format ! ( "Command::new({}).status() failed" , name) ) ?;
717
- if !status. success ( ) {
718
- anyhow:: bail!(
719
- "failed to run {} in {:?} with prefix {:?}" ,
720
- name,
721
- prof_out_dir,
722
- prefix
723
- )
724
- }
725
- let json = prof_out_dir. join ( format ! (
726
- "{}.json" ,
727
- prefix. strip_suffix( ".mm_profdata" ) . unwrap_or( prefix)
728
- ) ) ;
729
- fs:: read_to_string ( & json) . with_context ( || format ! ( "failed to read {:?}" , json) )
658
+ Ok ( ( profile, files) )
730
659
}
0 commit comments