@@ -7,12 +7,15 @@ use bytes::Buf;
7
7
use headers:: { ContentType , Header } ;
8
8
use hyper:: StatusCode ;
9
9
10
+ use crate :: api:: self_profile:: ArtifactSizeDelta ;
10
11
use crate :: api:: { self_profile, self_profile_processed, self_profile_raw, ServerResult } ;
11
12
use crate :: db:: ArtifactId ;
12
13
use crate :: load:: SiteCtxt ;
13
14
use crate :: selector:: { self , Tag } ;
14
15
use crate :: server:: { Response , ResponseHeaders } ;
15
16
17
+ use std:: collections:: BTreeMap ;
18
+
16
19
pub async fn handle_self_profile_processed_download (
17
20
body : self_profile_processed:: Request ,
18
21
ctxt : & SiteCtxt ,
@@ -142,6 +145,7 @@ pub async fn handle_self_profile_processed_download(
142
145
fn get_self_profile_data (
143
146
cpu_clock : Option < f64 > ,
144
147
self_profile : Option < crate :: selector:: SelfProfileData > ,
148
+ raw_data : Vec < u8 > ,
145
149
) -> ServerResult < self_profile:: SelfProfile > {
146
150
let profile = self_profile
147
151
. as_ref ( )
@@ -178,6 +182,7 @@ fn get_self_profile_data(
178
182
. map ( |qd| qd. incremental_load_time )
179
183
. sum ( ) ,
180
184
} ;
185
+ let artifact_sizes = raw_mmprof_data_to_artifact_sizes ( raw_data) . ok ( ) ;
181
186
let profile = self_profile:: SelfProfile {
182
187
query_data : profile
183
188
. query_data
@@ -195,6 +200,7 @@ fn get_self_profile_data(
195
200
} )
196
201
. collect ( ) ,
197
202
totals,
203
+ artifact_sizes,
198
204
} ;
199
205
200
206
Ok ( profile)
@@ -239,6 +245,8 @@ fn add_uninvoked_base_profile_queries(
239
245
fn get_self_profile_delta (
240
246
profile : & self_profile:: SelfProfile ,
241
247
base_profile : & Option < self_profile:: SelfProfile > ,
248
+ raw_data : Vec < u8 > ,
249
+ base_raw_data : Vec < u8 > ,
242
250
) -> Option < self_profile:: SelfProfileDelta > {
243
251
let base_profile = match base_profile. as_ref ( ) {
244
252
Some ( bp) => bp,
@@ -283,7 +291,21 @@ fn get_self_profile_delta(
283
291
}
284
292
}
285
293
286
- Some ( self_profile:: SelfProfileDelta { totals, query_data } )
294
+ let first = raw_mmprof_data_to_artifact_sizes ( raw_data) . unwrap_or_else ( |_| Vec :: new ( ) ) ;
295
+ let base = raw_mmprof_data_to_artifact_sizes ( base_raw_data) . unwrap_or_else ( |_| Vec :: new ( ) ) ;
296
+ let artifact_sizes = first
297
+ . into_iter ( )
298
+ . zip ( base. into_iter ( ) )
299
+ . map ( |( a1, a2) | ArtifactSizeDelta {
300
+ bytes : a1. bytes - a2. bytes ,
301
+ } )
302
+ . collect ( ) ;
303
+
304
+ Some ( self_profile:: SelfProfileDelta {
305
+ totals,
306
+ query_data,
307
+ artifact_sizes,
308
+ } )
287
309
}
288
310
289
311
fn sort_self_profile (
@@ -489,10 +511,10 @@ pub async fn handle_self_profile_raw(
489
511
) -> ServerResult < self_profile_raw:: Response > {
490
512
log:: info!( "handle_self_profile_raw({:?})" , body) ;
491
513
let mut it = body. benchmark . rsplitn ( 2 , '-' ) ;
492
- let bench_ty = it. next ( ) . ok_or ( format ! ( "no benchmark type" ) ) ?;
514
+ let profile = it. next ( ) . ok_or ( format ! ( "no benchmark type" ) ) ?;
493
515
let bench_name = it. next ( ) . ok_or ( format ! ( "no benchmark name" ) ) ?;
494
516
495
- let cache = body
517
+ let scenario = body
496
518
. run_name
497
519
. parse :: < database:: Scenario > ( )
498
520
. map_err ( |e| format ! ( "invalid run name: {:?}" , e) ) ?;
@@ -506,7 +528,7 @@ pub async fn handle_self_profile_raw(
506
528
date : database:: Date :: empty ( ) ,
507
529
} ) ,
508
530
bench_name,
509
- bench_ty ,
531
+ profile ,
510
532
& body. run_name ,
511
533
)
512
534
. await ;
@@ -526,20 +548,20 @@ pub async fn handle_self_profile_raw(
526
548
_ => first_cid,
527
549
} ;
528
550
551
+ let cids = aids_and_cids
552
+ . into_iter ( )
553
+ . map ( |( _, cid) | cid)
554
+ . collect :: < Vec < _ > > ( ) ;
555
+
529
556
let url_prefix = format ! (
530
557
"https://perf-data.rust-lang.org/self-profile/{}/{}/{}/{}/self-profile-{}" ,
531
558
aid. 0 ,
532
559
bench_name,
533
- bench_ty ,
534
- cache . to_id( ) ,
560
+ profile ,
561
+ scenario . to_id( ) ,
535
562
cid,
536
563
) ;
537
564
538
- let cids = aids_and_cids
539
- . into_iter ( )
540
- . map ( |( _, cid) | cid)
541
- . collect :: < Vec < _ > > ( ) ;
542
-
543
565
return match fetch ( & cids, cid, format ! ( "{}.mm_profdata.sz" , url_prefix) ) . await {
544
566
Ok ( fetched) => Ok ( fetched) ,
545
567
Err ( new_error) => Err ( format ! ( "mm_profdata download failed: {:?}" , new_error, ) ) ,
@@ -570,6 +592,21 @@ pub async fn handle_self_profile_raw(
570
592
}
571
593
}
572
594
595
+ pub async fn fetch_raw_self_profile_data (
596
+ aid : & str ,
597
+ benchmark : & str ,
598
+ profile : & str ,
599
+ scenario : & str ,
600
+ cid : i32 ,
601
+ ) -> Result < Vec < u8 > , Response > {
602
+ let url = format ! (
603
+ "https://perf-data.rust-lang.org/self-profile/{}/{}/{}/{}/self-profile-{}" ,
604
+ aid, benchmark, profile, scenario, cid,
605
+ ) ;
606
+
607
+ get_self_profile_raw_data ( & url) . await
608
+ }
609
+
573
610
pub async fn handle_self_profile (
574
611
body : self_profile:: Request ,
575
612
ctxt : & SiteCtxt ,
@@ -653,17 +690,40 @@ pub async fn handle_self_profile(
653
690
. await ?;
654
691
assert_eq ! ( cpu_responses. len( ) , 1 , "all selectors are exact" ) ;
655
692
let mut cpu_response = cpu_responses. remove ( 0 ) . series ;
656
-
693
+ let mut raw_data = Vec :: new ( ) ;
694
+ let conn = ctxt. conn ( ) . await ;
695
+ for commit in commits. iter ( ) {
696
+ let aid = match commit {
697
+ ArtifactId :: Commit ( c) => c. sha . as_str ( ) ,
698
+ ArtifactId :: Tag ( t) => t. as_str ( ) ,
699
+ } ;
700
+ let aids_and_cids = conn
701
+ . list_self_profile ( commit. clone ( ) , bench_name, profile, & body. run_name )
702
+ . await ;
703
+ if let Some ( ( _, cid) ) = aids_and_cids. first ( ) {
704
+ match fetch_raw_self_profile_data ( aid, bench_name, profile, & body. run_name , * cid) . await
705
+ {
706
+ Ok ( d) => raw_data. push ( d) ,
707
+ Err ( _resp) => {
708
+ eprintln ! ( "could not fetch raw self_profile data" ) ;
709
+ }
710
+ } ;
711
+ }
712
+ }
713
+ let raw_datum = raw_data. remove ( 0 ) ;
714
+ let base_raw_datum = raw_data. remove ( 0 ) ;
657
715
let mut profile = get_self_profile_data (
658
716
cpu_response. next ( ) . unwrap ( ) . 1 ,
659
717
sp_response. next ( ) . unwrap ( ) . 1 ,
718
+ raw_datum. clone ( ) ,
660
719
)
661
720
. map_err ( |e| format ! ( "{}: {}" , body. commit, e) ) ?;
662
721
let base_profile = if body. base_commit . is_some ( ) {
663
722
Some (
664
723
get_self_profile_data (
665
724
cpu_response. next ( ) . unwrap ( ) . 1 ,
666
725
sp_response. next ( ) . unwrap ( ) . 1 ,
726
+ base_raw_datum. clone ( ) ,
667
727
)
668
728
. map_err ( |e| format ! ( "{}: {}" , body. base_commit. as_ref( ) . unwrap( ) , e) ) ?,
669
729
)
@@ -672,11 +732,41 @@ pub async fn handle_self_profile(
672
732
} ;
673
733
674
734
add_uninvoked_base_profile_queries ( & mut profile, & base_profile) ;
675
- let mut base_profile_delta = get_self_profile_delta ( & profile, & base_profile) ;
735
+ let mut base_profile_delta =
736
+ get_self_profile_delta ( & profile, & base_profile, raw_datum, base_raw_datum) ;
676
737
sort_self_profile ( & mut profile, & mut base_profile_delta, sort_idx) ;
677
738
678
739
Ok ( self_profile:: Response {
679
740
base_profile_delta,
680
741
profile,
681
742
} )
682
743
}
744
+
745
+ fn raw_mmprof_data_to_artifact_sizes (
746
+ data : Vec < u8 > ,
747
+ ) -> anyhow:: Result < Vec < self_profile:: ArtifactSize > > {
748
+ let profiling_data = analyzeme:: ProfilingData :: from_paged_buffer ( data, None )
749
+ . map_err ( |_| anyhow:: Error :: msg ( "could not parse profiling data" ) ) ?;
750
+
751
+ let mut artifact_sizes: BTreeMap < _ , u64 > = Default :: default ( ) ;
752
+
753
+ for event in profiling_data. iter_full ( ) {
754
+ // TODO: Use constant from measureme::rustc
755
+ if event. event_kind == "ArtifactSize" {
756
+ if !event. payload . is_integer ( ) {
757
+ anyhow:: bail!( "Found ArtifactSize payload that is not an integer" )
758
+ }
759
+
760
+ let bytes = event. payload . integer ( ) . unwrap ( ) ;
761
+ * artifact_sizes. entry ( event. label ) . or_default ( ) += bytes;
762
+ }
763
+ }
764
+
765
+ Ok ( artifact_sizes
766
+ . iter ( )
767
+ . map ( |( k, v) | self_profile:: ArtifactSize {
768
+ label : k[ ..] . into ( ) ,
769
+ bytes : * v,
770
+ } )
771
+ . collect ( ) )
772
+ }
0 commit comments