@@ -3,6 +3,7 @@ use std::env;
3
3
use std:: ffi:: OsString ;
4
4
use std:: fs;
5
5
use std:: path:: Path ;
6
+ use std:: path:: PathBuf ;
6
7
use std:: process:: Command ;
7
8
use std:: time:: { Duration , Instant } ;
8
9
@@ -77,67 +78,11 @@ fn main() {
77
78
print_memory ( ) ;
78
79
print_time ( dur) ;
79
80
if wrapper == "perf-stat-self-profile" {
80
- let crate_name = args
81
- . windows ( 2 )
82
- . find ( |args| args[ 0 ] == "--crate-name" )
83
- . and_then ( |args| args[ 1 ] . to_str ( ) )
84
- . expect ( "rustc to be invoked with crate name" ) ;
85
- let mut prefix = None ;
86
- let mut full_path = None ;
87
- // We don't know the pid of rustc, and can't easily get it -- we only know the
88
- // `perf` pid. So just blindly look in the directory to hopefully find it.
89
- for entry in fs:: read_dir ( & prof_out_dir) . unwrap ( ) {
90
- let entry = entry. unwrap ( ) ;
91
- if entry
92
- . file_name ( )
93
- . to_str ( )
94
- . map_or ( false , |s| s. starts_with ( crate_name) )
95
- {
96
- if entry. file_name ( ) . to_str ( ) . unwrap ( ) . ends_with ( "mm_profdata" ) {
97
- full_path = Some ( entry. path ( ) ) ;
98
- break ;
99
- }
100
- let file = entry. file_name ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) ;
101
- let new_prefix = Some ( file[ ..file. find ( '.' ) . unwrap ( ) ] . to_owned ( ) ) ;
102
- assert ! (
103
- prefix. is_none( ) || prefix == new_prefix,
104
- "prefix={:?}, new_prefix={:?}" ,
105
- prefix,
106
- new_prefix
107
- ) ;
108
- prefix = new_prefix;
109
- }
110
- }
111
- if let Some ( profile_data) = full_path {
112
- // measureme 0.8 has a single file
113
- println ! ( "!self-profile-file:{}" , profile_data. to_str( ) . unwrap( ) ) ;
114
- let filename = profile_data. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
115
- let json = match run_summarize ( "summarize" , & prof_out_dir, filename) {
116
- Ok ( s) => s,
117
- Err ( e1) => {
118
- match run_summarize ( "summarize-9.0" , & prof_out_dir, filename) {
119
- Ok ( s) => s,
120
- Err ( e2) => {
121
- panic ! ( "failed to run summarize and summarize-9.0. Errors:\n summarize: {:?}\n summarize-9.0: {:?}" , e1, e2) ;
122
- }
123
- }
124
- }
125
- } ;
126
- println ! ( "!self-profile-output:{}" , json) ;
127
- } else {
128
- let prefix = prefix. expect ( & format ! ( "found prefix {:?}" , prof_out_dir) ) ;
129
- let json = run_summarize ( "summarize" , & prof_out_dir, & prefix)
130
- . or_else ( |_| run_summarize ( "summarize-0.7" , & prof_out_dir, & prefix) )
131
- . expect ( "able to run summarize or summarize-0.7" ) ;
132
- println ! ( "!self-profile-dir:{}" , prof_out_dir. to_str( ) . unwrap( ) ) ;
133
- println ! ( "!self-profile-prefix:{}" , prefix) ;
134
- println ! ( "!self-profile-output:{}" , json) ;
135
- }
81
+ process_self_profile_output ( prof_out_dir, & args[ ..] ) ;
136
82
}
137
83
}
138
84
139
85
"xperf-stat" | "xperf-stat-self-profile" => {
140
- // TODO handle self-profiling
141
86
// Read the path to tracelog.exe from either an environment variable, falling back to assuming it's on the PATH.
142
87
let tracelog = std:: env:: var ( "TRACELOG" ) . unwrap_or ( "tracelog.exe" . to_string ( ) ) ;
143
88
let mut cmd = Command :: new ( tracelog) ;
@@ -148,7 +93,17 @@ fn main() {
148
93
assert ! ( status. success( ) , "tracelog did not complete successfully" ) ;
149
94
150
95
let mut tool = Command :: new ( tool) ;
151
- tool. args ( args) ;
96
+ tool. args ( & args) ;
97
+
98
+ let prof_out_dir = std:: env:: current_dir ( ) . unwrap ( ) . join ( "self-profile-output" ) ;
99
+ if wrapper == "xperf-stat-self-profile" {
100
+ tool. arg ( & format ! (
101
+ "-Zself-profile={}" ,
102
+ prof_out_dir. to_str( ) . unwrap( )
103
+ ) ) ;
104
+ let _ = fs:: remove_dir_all ( & prof_out_dir) ;
105
+ let _ = fs:: create_dir_all ( & prof_out_dir) ;
106
+ }
152
107
153
108
let start = Instant :: now ( ) ;
154
109
let status = tool. status ( ) . expect ( "tool failed to start" ) ;
@@ -172,6 +127,10 @@ fn main() {
172
127
173
128
let counters_file = std:: env:: current_dir ( ) . unwrap ( ) . join ( "pmc_counters.txt" ) ;
174
129
println ! ( "!counters-file:{}" , counters_file. to_str( ) . unwrap( ) ) ;
130
+
131
+ if wrapper == "xperf-stat-self-profile" {
132
+ process_self_profile_output ( prof_out_dir, & args[ ..] ) ;
133
+ }
175
134
}
176
135
177
136
"self-profile" => {
@@ -325,6 +284,65 @@ fn main() {
325
284
}
326
285
}
327
286
287
+ fn process_self_profile_output ( prof_out_dir : PathBuf , args : & [ OsString ] ) {
288
+ let crate_name = args
289
+ . windows ( 2 )
290
+ . find ( |args| args[ 0 ] == "--crate-name" )
291
+ . and_then ( |args| args[ 1 ] . to_str ( ) )
292
+ . expect ( "rustc to be invoked with crate name" ) ;
293
+ let mut prefix = None ;
294
+ let mut full_path = None ;
295
+ // We don't know the pid of rustc, and can't easily get it -- we only know the
296
+ // `perf` pid. So just blindly look in the directory to hopefully find it.
297
+ for entry in fs:: read_dir ( & prof_out_dir) . unwrap ( ) {
298
+ let entry = entry. unwrap ( ) ;
299
+ if entry
300
+ . file_name ( )
301
+ . to_str ( )
302
+ . map_or ( false , |s| s. starts_with ( crate_name) )
303
+ {
304
+ if entry. file_name ( ) . to_str ( ) . unwrap ( ) . ends_with ( "mm_profdata" ) {
305
+ full_path = Some ( entry. path ( ) ) ;
306
+ break ;
307
+ }
308
+ let file = entry. file_name ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) ;
309
+ let new_prefix = Some ( file[ ..file. find ( '.' ) . unwrap ( ) ] . to_owned ( ) ) ;
310
+ assert ! (
311
+ prefix. is_none( ) || prefix == new_prefix,
312
+ "prefix={:?}, new_prefix={:?}" ,
313
+ prefix,
314
+ new_prefix
315
+ ) ;
316
+ prefix = new_prefix;
317
+ }
318
+ }
319
+ if let Some ( profile_data) = full_path {
320
+ // measureme 0.8 has a single file
321
+ println ! ( "!self-profile-file:{}" , profile_data. to_str( ) . unwrap( ) ) ;
322
+ let filename = profile_data. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
323
+ let json = match run_summarize ( "summarize" , & prof_out_dir, filename) {
324
+ Ok ( s) => s,
325
+ Err ( e1) => {
326
+ match run_summarize ( "summarize-9.0" , & prof_out_dir, filename) {
327
+ Ok ( s) => s,
328
+ Err ( e2) => {
329
+ panic ! ( "failed to run summarize and summarize-9.0. Errors:\n summarize: {:?}\n summarize-9.0: {:?}" , e1, e2) ;
330
+ }
331
+ }
332
+ }
333
+ } ;
334
+ println ! ( "!self-profile-output:{}" , json) ;
335
+ } else {
336
+ let prefix = prefix. expect ( & format ! ( "found prefix {:?}" , prof_out_dir) ) ;
337
+ let json = run_summarize ( "summarize" , & prof_out_dir, & prefix)
338
+ . or_else ( |_| run_summarize ( "summarize-0.7" , & prof_out_dir, & prefix) )
339
+ . expect ( "able to run summarize or summarize-0.7" ) ;
340
+ println ! ( "!self-profile-dir:{}" , prof_out_dir. to_str( ) . unwrap( ) ) ;
341
+ println ! ( "!self-profile-prefix:{}" , prefix) ;
342
+ println ! ( "!self-profile-output:{}" , json) ;
343
+ }
344
+ }
345
+
328
346
/// Run a command via bash, in order to redirect its output to a file.
329
347
/// `redirect` should be something like "> out" or "2> out".
330
348
fn bash_command ( tool : OsString , args : Vec < OsString > , redirect : & str ) -> Command {
0 commit comments