failed_speculation_profile/
failed_speculation_profile.rs1use std::{env, fs, hint::black_box, time::Instant};
3
4use oxc_allocator::Allocator;
5use oxc_parser::{ParseOptions, Parser, config::RuntimeParserConfig};
6use oxc_span::SourceType;
7
8fn main() {
9 let mut args = env::args().skip(1);
10 let mode = args.next().expect("mode: time or packets");
11 let path = args.next().expect("UTF-8 input path");
12 let source = fs::read_to_string(path).unwrap();
13 if mode == "packets" {
14 assert!(args.next().is_none());
15 packets(&source);
16 return;
17 }
18 assert_eq!(mode, "time");
19 let iterations: usize = args.next().map_or(1, |n| n.parse().unwrap());
20 assert!((1..=100_000).contains(&iterations));
21 assert!(args.next().is_none());
22 let start = Instant::now();
23 let mut rejected = 0;
24 let mut peak_arena_used_bytes = 0;
25 for _ in 0..iterations {
26 let allocator = Allocator::default();
27 rejected += usize::from(
28 black_box(
29 Parser::new(&allocator, black_box(&source), SourceType::ts()).parse_expression(),
30 )
31 .is_err(),
32 );
33 peak_arena_used_bytes = peak_arena_used_bytes.max(allocator.used_bytes());
34 }
35 println!(
36 "{{\"iterations\":{iterations},\"rejected\":{rejected},\"elapsed_ns\":{},\"peak_arena_used_bytes\":{peak_arena_used_bytes}}}",
37 start.elapsed().as_nanos()
38 );
39}
40
41fn packets(source: &str) {
42 for source_type in [
43 SourceType::ts(),
44 SourceType::tsx(),
45 SourceType::jsx(),
46 SourceType::ts().with_script(true),
47 SourceType::ts().with_unambiguous(true),
48 ] {
49 for tokens in [false, true] {
50 for parse_regular_expression in [false, true] {
51 let options = ParseOptions { parse_regular_expression, ..ParseOptions::default() };
52 let allocator = Allocator::default();
53 let result = Parser::new(&allocator, source, source_type)
54 .with_config(RuntimeParserConfig::new(tokens))
55 .with_options(options)
56 .parse();
57 println!(
58 "program {source_type:?} tokens={tokens} regexp={parse_regular_expression}: {:?}\n{:?}\n{:?}\n{:?}\n{:?}\n{:?}",
59 result.program,
60 result.diagnostics,
61 result.tokens,
62 result.module_record,
63 result.irregular_whitespaces,
64 (result.panicked, result.is_flow_language),
65 );
66 let allocator = Allocator::default();
67 let observation = Parser::new(&allocator, source, source_type)
68 .with_config(RuntimeParserConfig::new(tokens))
69 .with_options(options)
70 .parse_observed();
71 let facts = observation.admitted().map(|admitted| {
72 (admitted.has_legacy_literals(), admitted.has_jsdoc_comments())
73 });
74 println!("original admitted source facts: {facts:?}");
75 let allocator = Allocator::default();
76 let result = Parser::new(&allocator, source, source_type)
77 .with_config(RuntimeParserConfig::new(tokens))
78 .with_options(options)
79 .parse_expression();
80 println!(
81 "expression {source_type:?} tokens={tokens} regexp={parse_regular_expression}: {result:?}"
82 );
83 }
84 }
85 }
86}