1
- use crate :: runtime_group_step_name;
2
- use crate :: toolchain:: Toolchain ;
3
- use crate :: utils:: fs:: EnsureImmutableFile ;
4
- use anyhow:: Context ;
5
- use benchlib:: benchmark:: passes_filter;
6
- use cargo_metadata:: Message ;
7
1
use core:: option:: Option ;
8
2
use core:: option:: Option :: Some ;
9
3
use core:: result:: Result :: Ok ;
10
4
use std:: collections:: HashMap ;
11
- use std:: io:: BufReader ;
12
5
use std:: path:: { Path , PathBuf } ;
13
- use std:: process:: { Child , Command , Stdio } ;
6
+ use std:: process:: Command ;
7
+
8
+ use anyhow:: Context ;
14
9
use tempfile:: TempDir ;
15
10
11
+ use benchlib:: benchmark:: passes_filter;
12
+
13
+ use crate :: cargo:: CargoArtifactIter ;
14
+ use crate :: runtime_group_step_name;
15
+ use crate :: toolchain:: Toolchain ;
16
+ use crate :: utils:: fs:: EnsureImmutableFile ;
17
+
16
18
/// Directory containing runtime benchmarks.
17
19
/// We measure how long does it take to execute these crates, which is a proxy of the quality
18
20
/// of code generated by rustc.
@@ -217,16 +219,16 @@ pub fn prepare_runtime_benchmark_suite(
217
219
. with_context ( || {
218
220
anyhow:: anyhow!( "Cannot start compilation of {}" , benchmark_crate. name)
219
221
} )
220
- . and_then ( |process | {
221
- parse_benchmark_group ( process , & benchmark_crate. name ) . with_context ( || {
222
+ . and_then ( |iter | {
223
+ parse_benchmark_group ( iter , & benchmark_crate. name ) . with_context ( || {
222
224
anyhow:: anyhow!( "Cannot compile runtime benchmark {}" , benchmark_crate. name)
223
225
} )
224
226
} ) ;
225
227
match result {
226
228
Ok ( group) => groups. push ( group) ,
227
229
Err ( error) => {
228
230
log:: error!(
229
- "Cannot compile runtime benchmark group `{}`" ,
231
+ "Cannot compile runtime benchmark group `{}` {error:?} " ,
230
232
benchmark_crate. name
231
233
) ;
232
234
failed_to_compile. insert (
@@ -276,66 +278,47 @@ fn check_duplicates(groups: &[BenchmarkGroup]) -> anyhow::Result<()> {
276
278
/// Locates the benchmark binary of a runtime benchmark crate compiled by cargo, and then executes it
277
279
/// to find out what benchmarks do they contain.
278
280
fn parse_benchmark_group (
279
- mut cargo_process : Child ,
281
+ mut cargo_iter : CargoArtifactIter ,
280
282
group_name : & str ,
281
283
) -> anyhow:: Result < BenchmarkGroup > {
282
284
let mut group: Option < BenchmarkGroup > = None ;
283
285
284
- let stream = BufReader :: new ( cargo_process. stdout . take ( ) . unwrap ( ) ) ;
285
- let mut messages = String :: new ( ) ;
286
- for message in Message :: parse_stream ( stream) {
287
- let message = message?;
288
- match message {
289
- Message :: CompilerArtifact ( artifact) => {
290
- if let Some ( ref executable) = artifact. executable {
291
- // Found a binary compiled by a runtime benchmark crate.
292
- // Execute it so that we find all the benchmarks it contains.
293
- if artifact. target . kind . iter ( ) . any ( |k| k == "bin" ) {
294
- if group. is_some ( ) {
295
- return Err ( anyhow:: anyhow!( "Runtime benchmark group `{group_name}` has produced multiple binaries" ) ) ;
296
- }
297
-
298
- let path = executable. as_std_path ( ) . to_path_buf ( ) ;
299
- let benchmarks = gather_benchmarks ( & path) . map_err ( |err| {
300
- anyhow:: anyhow!(
301
- "Cannot gather benchmarks from `{}`: {err:?}" ,
302
- path. display( )
303
- )
304
- } ) ?;
305
- log:: info!( "Compiled {}" , path. display( ) ) ;
306
-
307
- group = Some ( BenchmarkGroup {
308
- binary : path,
309
- name : group_name. to_string ( ) ,
310
- benchmark_names : benchmarks,
311
- } ) ;
312
- }
286
+ for artifact in & mut cargo_iter {
287
+ let artifact = artifact?;
288
+ if let Some ( ref executable) = artifact. executable {
289
+ // Found a binary compiled by a runtime benchmark crate.
290
+ // Execute it so that we find all the benchmarks it contains.
291
+ if artifact. target . kind . iter ( ) . any ( |k| k == "bin" ) {
292
+ if group. is_some ( ) {
293
+ return Err ( anyhow:: anyhow!(
294
+ "Runtime benchmark group `{group_name}` has produced multiple binaries"
295
+ ) ) ;
313
296
}
297
+
298
+ let path = executable. as_std_path ( ) . to_path_buf ( ) ;
299
+ let benchmarks = gather_benchmarks ( & path) . map_err ( |err| {
300
+ anyhow:: anyhow!(
301
+ "Cannot gather benchmarks from `{}`: {err:?}" ,
302
+ path. display( )
303
+ )
304
+ } ) ?;
305
+ log:: info!( "Compiled {}" , path. display( ) ) ;
306
+
307
+ group = Some ( BenchmarkGroup {
308
+ binary : path,
309
+ name : group_name. to_string ( ) ,
310
+ benchmark_names : benchmarks,
311
+ } ) ;
314
312
}
315
- Message :: TextLine ( line) => {
316
- println ! ( "{line}" )
317
- }
318
- Message :: CompilerMessage ( msg) => {
319
- let message = msg. message . rendered . unwrap_or ( msg. message . message ) ;
320
- messages. push_str ( & message) ;
321
- print ! ( "{message}" ) ;
322
- }
323
- _ => { }
324
313
}
325
314
}
326
-
327
- let output = cargo_process. wait ( ) ?;
328
- if !output. success ( ) {
329
- Err ( anyhow:: anyhow!(
330
- "Failed to compile runtime benchmark, exit code {}\n {messages}" ,
331
- output. code( ) . unwrap_or( 1 ) ,
332
- ) )
333
- } else {
334
- let group = group. ok_or_else ( || {
335
- anyhow:: anyhow!( "Runtime benchmark group `{group_name}` has not produced any binary" )
336
- } ) ?;
337
- Ok ( group)
338
- }
315
+ cargo_iter
316
+ . finish ( )
317
+ . with_context ( || format ! ( "Failed to compile runtime benchmark `{group_name}`" ) ) ?;
318
+ let group = group. ok_or_else ( || {
319
+ anyhow:: anyhow!( "Runtime benchmark group `{group_name}` has not produced any binary" )
320
+ } ) ?;
321
+ Ok ( group)
339
322
}
340
323
341
324
/// Starts the compilation of a single runtime benchmark crate.
@@ -345,18 +328,13 @@ fn start_cargo_build(
345
328
benchmark_dir : & Path ,
346
329
target_dir : Option < & Path > ,
347
330
opts : & RuntimeCompilationOpts ,
348
- ) -> anyhow:: Result < Child > {
331
+ ) -> anyhow:: Result < CargoArtifactIter > {
349
332
let mut command = Command :: new ( & toolchain. components . cargo ) ;
350
333
command
351
334
. env ( "RUSTC" , & toolchain. components . rustc )
352
335
. arg ( "build" )
353
336
. arg ( "--release" )
354
- . arg ( "--message-format" )
355
- . arg ( "json-diagnostic-short" )
356
- . current_dir ( benchmark_dir)
357
- . stdin ( Stdio :: null ( ) )
358
- . stdout ( Stdio :: piped ( ) )
359
- . stderr ( Stdio :: null ( ) ) ;
337
+ . current_dir ( benchmark_dir) ;
360
338
361
339
if let Some ( ref debug_info) = opts. debug_info {
362
340
command. env ( "CARGO_PROFILE_RELEASE_DEBUG" , debug_info) ;
@@ -371,10 +349,8 @@ fn start_cargo_build(
371
349
#[ cfg( feature = "precise-cachegrind" ) ]
372
350
command. arg ( "--features" ) . arg ( "benchlib/precise-cachegrind" ) ;
373
351
374
- let child = command
375
- . spawn ( )
376
- . map_err ( |error| anyhow:: anyhow!( "Failed to start cargo: {:?}" , error) ) ?;
377
- Ok ( child)
352
+ CargoArtifactIter :: from_cargo_cmd ( command)
353
+ . map_err ( |error| anyhow:: anyhow!( "Failed to start cargo: {:?}" , error) )
378
354
}
379
355
380
356
/// Uses a command from `benchlib` to find the benchmark names from the given
0 commit comments