Skip to content

Commit 9b63c29

Browse files
committed
Turbopack: skip codegen effects when tracing
1 parent 58fa45f commit 9b63c29

File tree

12 files changed

+117
-52
lines changed

12 files changed

+117
-52
lines changed

turbopack/crates/turbopack-ecmascript/benches/analyzer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub fn benchmark(c: &mut Criterion) {
6464
None,
6565
None,
6666
);
67-
let var_graph = create_graph(&program, &eval_context);
67+
let var_graph = create_graph(&program, &eval_context, false);
6868

6969
let input = BenchInput {
7070
program,
@@ -90,7 +90,7 @@ struct BenchInput {
9090
}
9191

9292
fn bench_create_graph(b: &mut Bencher, input: &BenchInput) {
93-
b.iter(|| create_graph(&input.program, &input.eval_context));
93+
b.iter(|| create_graph(&input.program, &input.eval_context, false));
9494
}
9595

9696
fn bench_link(b: &mut Bencher, input: &BenchInput) {

turbopack/crates/turbopack-ecmascript/benches/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ extern crate turbo_tasks_malloc;
33
use criterion::{criterion_group, criterion_main};
44

55
mod analyzer;
6-
mod full;
6+
mod references;
77

88
criterion_group!(analyzer_benches, analyzer::benchmark);
9-
criterion_group!(full_benches, full::benchmark);
9+
criterion_group!(full_benches, references::benchmark);
1010
criterion_main!(analyzer_benches, full_benches);

turbopack/crates/turbopack-ecmascript/benches/full.rs renamed to turbopack/crates/turbopack-ecmascript/benches/references.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ pub fn benchmark(c: &mut Criterion) {
5353
.resolved_cell();
5454

5555
let mut cases = vec![];
56-
for file in [
57-
r#"packages/next/dist/compiled/babel-packages/packages-bundle.js"#,
58-
r#"node_modules/.pnpm/react-dom@19.2.0-canary-03fda05d-20250820_react@19.2.0-canary-03fda05d-20250820/node_modules/react-dom/cjs/react-dom-client.development.js"#,
56+
for (file, is_tracing) in [
57+
(r#"packages/next/dist/compiled/babel-packages/packages-bundle.js"#, false),
58+
(r#"packages/next/dist/compiled/babel-packages/packages-bundle.js"#, true),
59+
(r#"node_modules/.pnpm/react-dom@19.2.0-canary-03fda05d-20250820_react@19.2.0-canary-03fda05d-20250820/node_modules/react-dom/cjs/react-dom-client.development.js"#, false),
60+
(r#"node_modules/.pnpm/react-dom@19.2.0-canary-03fda05d-20250820_react@19.2.0-canary-03fda05d-20250820/node_modules/react-dom/cjs/react-dom-client.development.js"#, true),
5961
] {
6062
let module = EcmascriptModuleAsset::builder(
6163
ResolvedVc::upcast(
@@ -67,6 +69,7 @@ pub fn benchmark(c: &mut Criterion) {
6769
EcmascriptInputTransforms::empty().to_resolved().await?,
6870
EcmascriptOptions {
6971
tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly),
72+
is_tracing,
7073
..Default::default()
7174
}
7275
.resolved_cell(),
@@ -76,21 +79,21 @@ pub fn benchmark(c: &mut Criterion) {
7679
.to_resolved()
7780
.await?;
7881

79-
cases.push((file, module));
82+
cases.push((file.rsplit("/").next().unwrap(), if is_tracing { "tracing" } else { "full" }, module));
8083
}
8184
anyhow::Ok(cases)
8285
}))
8386
.unwrap();
8487

85-
let mut group = c.benchmark_group("full");
88+
let mut group = c.benchmark_group("references");
8689
group.warm_up_time(Duration::from_secs(1));
87-
group.measurement_time(Duration::from_secs(20));
90+
group.measurement_time(Duration::from_secs(10));
8891

89-
for case in cases {
92+
for (file, param, module) in cases {
9093
group.bench_with_input(
91-
BenchmarkId::new("full", case.0),
94+
BenchmarkId::new(file, param),
9295
&BenchInput {
93-
module: case.1,
96+
module,
9497
storage: tt.clone(),
9598
},
9699
bench_full,

turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl VarGraph {
274274

275275
/// You should use same [Mark] for this function and
276276
/// [swc_ecma_transforms_base::resolver::resolver_with_mark]
277-
pub fn create_graph(m: &Program, eval_context: &EvalContext) -> VarGraph {
277+
pub fn create_graph(m: &Program, eval_context: &EvalContext, is_tracing: bool) -> VarGraph {
278278
let mut graph = VarGraph {
279279
values: Default::default(),
280280
free_var_ids: Default::default(),
@@ -283,6 +283,7 @@ pub fn create_graph(m: &Program, eval_context: &EvalContext) -> VarGraph {
283283

284284
m.visit_with_ast_path(
285285
&mut Analyzer {
286+
is_tracing,
286287
data: &mut graph,
287288
state: analyzer_state::AnalyzerState::new(),
288289
eval_context,
@@ -788,6 +789,8 @@ pub fn as_parent_path_skip(
788789
}
789790

790791
struct Analyzer<'a> {
792+
is_tracing: bool,
793+
791794
data: &'a mut VarGraph,
792795
state: analyzer_state::AnalyzerState,
793796

@@ -1274,6 +1277,10 @@ impl Analyzer<'_> {
12741277
member_expr: &'ast MemberExpr,
12751278
ast_path: &AstNodePath<AstParentNodeRef<'r>>,
12761279
) {
1280+
if self.is_tracing {
1281+
return;
1282+
}
1283+
12771284
let obj_value = Box::new(self.eval_context.eval(&member_expr.obj));
12781285
let prop_value = match &member_expr.prop {
12791286
// TODO avoid clone
@@ -1315,7 +1322,9 @@ impl Analyzer<'_> {
13151322
start_ast_path,
13161323
} => {
13171324
self.effects = prev_effects;
1318-
self.effects.push(Effect::Unreachable { start_ast_path });
1325+
if !self.is_tracing {
1326+
self.effects.push(Effect::Unreachable { start_ast_path });
1327+
}
13191328
always_returns = true;
13201329
}
13211330
EarlyReturn::Conditional {
@@ -2008,7 +2017,7 @@ impl VisitAstPath for Analyzer<'_> {
20082017
}
20092018

20102019
// If this variable is unresolved, track it as a free (unbound) variable
2011-
if is_unresolved(ident, self.eval_context.unresolved_mark)
2020+
if !self.is_tracing && is_unresolved(ident, self.eval_context.unresolved_mark)
20122021
|| self.eval_context.force_free_values.contains(&ident.to_id())
20132022
{
20142023
self.add_effect(Effect::FreeVar {
@@ -2043,13 +2052,16 @@ impl VisitAstPath for Analyzer<'_> {
20432052
// We are in some scope that will rebind this
20442053
return;
20452054
}
2046-
// Otherwise 'this' is free
2047-
self.add_effect(Effect::FreeVar {
2048-
var: atom!("this"),
2049-
ast_path: as_parent_path(ast_path),
2050-
span: node.span(),
2051-
in_try: is_in_try(ast_path),
2052-
})
2055+
2056+
if !self.is_tracing {
2057+
// Otherwise 'this' is free
2058+
self.add_effect(Effect::FreeVar {
2059+
var: atom!("this"),
2060+
ast_path: as_parent_path(ast_path),
2061+
span: node.span(),
2062+
in_try: is_in_try(ast_path),
2063+
})
2064+
}
20532065
}
20542066

20552067
fn visit_meta_prop_expr<'ast: 'r, 'r>(
@@ -2292,8 +2304,9 @@ impl VisitAstPath for Analyzer<'_> {
22922304
n: &'ast UnaryExpr,
22932305
ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>,
22942306
) {
2295-
if n.op == UnaryOp::TypeOf {
2307+
if n.op == UnaryOp::TypeOf && !self.is_tracing {
22962308
let arg_value = Box::new(self.eval_context.eval(&n.arg));
2309+
22972310
self.add_effect(Effect::TypeOf {
22982311
arg: arg_value,
22992312
ast_path: as_parent_path(ast_path),
@@ -2414,7 +2427,10 @@ impl Analyzer<'_> {
24142427
(Some(then), Some(r#else)) => ConditionalKind::IfElse { then, r#else },
24152428
(Some(then), None) => ConditionalKind::If { then },
24162429
(None, Some(r#else)) => ConditionalKind::Else { r#else },
2417-
(None, None) => unreachable!(),
2430+
(None, None) => {
2431+
// No effects, ignore
2432+
return;
2433+
}
24182434
};
24192435
self.add_effect(Effect::Conditional {
24202436
condition,

turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3828,7 +3828,7 @@ mod tests {
38283828
None,
38293829
);
38303830

3831-
let mut var_graph = create_graph(&m, &eval_context);
3831+
let mut var_graph = create_graph(&m, &eval_context, false);
38323832
let var_cache = Default::default();
38333833

38343834
let mut named_values = var_graph

turbopack/crates/turbopack-ecmascript/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ pub struct EcmascriptOptions {
200200
/// parsing fails. This is useful to keep the module graph structure intact when syntax errors
201201
/// are temporarily introduced.
202202
pub keep_last_successful_parse: bool,
203+
/// Whether the modules in this context are never chunked/codegen-ed, but only used for
204+
/// tracing.
205+
pub is_tracing: bool,
203206
}
204207

205208
#[turbo_tasks::value]

0 commit comments

Comments
 (0)