Skip to content

Commit 0d71de6

Browse files
committed
refactor(minifier): use the original vec in-place in minimize_statements
Use the original vec in-place instead of re-building the statements vec. Re-buiding the vec will append data to the end of the memory arena, which is not cache friendly.
1 parent 78fa81e commit 0d71de6

File tree

1 file changed

+30
-40
lines changed

1 file changed

+30
-40
lines changed

crates/oxc_minifier/src/peephole/minimize_statements.rs

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ impl<'a> PeepholeOptimizations {
3131
/// ## MinimizeExitPoints:
3232
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/MinimizeExitPoints.java>
3333
pub fn minimize_statements(&self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut Ctx<'a, '_>) {
34-
let mut result: Vec<'a, Statement<'a>> = ctx.ast.vec_with_capacity(stmts.len());
34+
let mut old_stmts = stmts.take_in(ctx.ast);
3535
let mut is_control_flow_dead = false;
3636
let mut keep_var = KeepVar::new(ctx.ast);
37-
let mut new_stmts = stmts.take_in(ctx.ast);
38-
for i in 0..new_stmts.len() {
39-
let stmt = new_stmts[i].take_in(ctx.ast);
37+
for i in 0..old_stmts.len() {
38+
let stmt = old_stmts[i].take_in(ctx.ast);
4039
if is_control_flow_dead
4140
&& !stmt.is_module_declaration()
4241
&& !matches!(stmt.as_declaration(), Some(Declaration::FunctionDeclaration(_)))
@@ -45,31 +44,24 @@ impl<'a> PeepholeOptimizations {
4544
continue;
4645
}
4746
if self
48-
.minimize_statement(
49-
stmt,
50-
i,
51-
&mut new_stmts,
52-
&mut result,
53-
&mut is_control_flow_dead,
54-
ctx,
55-
)
47+
.minimize_statement(stmt, i, &mut old_stmts, stmts, &mut is_control_flow_dead, ctx)
5648
.is_break()
5749
{
5850
break;
5951
}
6052
}
6153
if let Some(stmt) = keep_var.get_variable_declaration_statement() {
62-
result.push(stmt);
54+
stmts.push(stmt);
6355
}
6456

6557
// Drop a trailing unconditional jump statement if applicable
66-
if let Some(last_stmt) = result.last() {
58+
if let Some(last_stmt) = stmts.last() {
6759
match last_stmt {
6860
// "while (x) { y(); continue; }" => "while (x) { y(); }"
6961
Statement::ContinueStatement(s) if s.label.is_none() => {
7062
let mut changed = false;
7163
if let Some(Ancestor::ForStatementBody(_)) = ctx.ancestors().nth(1) {
72-
result.pop();
64+
stmts.pop();
7365
changed = true;
7466
}
7567
if changed {
@@ -79,7 +71,7 @@ impl<'a> PeepholeOptimizations {
7971
// "function f() { x(); return; }" => "function f() { x(); }"
8072
Statement::ReturnStatement(s) if s.argument.is_none() => {
8173
if let Ancestor::FunctionBodyStatements(_) = ctx.parent() {
82-
result.pop();
74+
stmts.pop();
8375
ctx.state.changed = true;
8476
}
8577
}
@@ -88,25 +80,25 @@ impl<'a> PeepholeOptimizations {
8880
}
8981

9082
// Merge certain statements in reverse order
91-
if result.len() >= 2 && ctx.options().sequences {
92-
if let Some(Statement::ReturnStatement(_)) = result.last() {
93-
'return_loop: while result.len() >= 2 {
94-
let prev_index = result.len() - 2;
95-
let prev_stmt = &result[prev_index];
83+
if stmts.len() >= 2 && ctx.options().sequences {
84+
if let Some(Statement::ReturnStatement(_)) = stmts.last() {
85+
'return_loop: while stmts.len() >= 2 {
86+
let prev_index = stmts.len() - 2;
87+
let prev_stmt = &stmts[prev_index];
9688
match prev_stmt {
9789
Statement::ExpressionStatement(_) => {
98-
if let Some(Statement::ReturnStatement(last_return)) = result.last() {
90+
if let Some(Statement::ReturnStatement(last_return)) = stmts.last() {
9991
if last_return.argument.is_none() {
10092
break 'return_loop;
10193
}
10294
}
10395
ctx.state.changed = true;
10496
// "a(); return b;" => "return a(), b;"
105-
let last_stmt = result.pop().unwrap();
97+
let last_stmt = stmts.pop().unwrap();
10698
let Statement::ReturnStatement(mut last_return) = last_stmt else {
10799
unreachable!()
108100
};
109-
let prev_stmt = result.pop().unwrap();
101+
let prev_stmt = stmts.pop().unwrap();
110102
let Statement::ExpressionStatement(mut expr_stmt) = prev_stmt else {
111103
unreachable!()
112104
};
@@ -115,7 +107,7 @@ impl<'a> PeepholeOptimizations {
115107
let right_span = last_return.span;
116108
let last_return_stmt =
117109
ctx.ast.statement_return(right_span, Some(argument));
118-
result.push(last_return_stmt);
110+
stmts.push(last_return_stmt);
119111
}
120112
// Merge the last two statements
121113
Statement::IfStatement(if_stmt) => {
@@ -129,11 +121,11 @@ impl<'a> PeepholeOptimizations {
129121
};
130122

131123
ctx.state.changed = true;
132-
let last_stmt = result.pop().unwrap();
124+
let last_stmt = stmts.pop().unwrap();
133125
let Statement::ReturnStatement(last_return) = last_stmt else {
134126
unreachable!()
135127
};
136-
let prev_stmt = result.pop().unwrap();
128+
let prev_stmt = stmts.pop().unwrap();
137129
let Statement::IfStatement(prev_if) = prev_stmt else { unreachable!() };
138130
let mut prev_if = prev_if.unbox();
139131
let Statement::ReturnStatement(prev_return) = prev_if.consequent else {
@@ -181,24 +173,24 @@ impl<'a> PeepholeOptimizations {
181173
};
182174
let last_return_stmt =
183175
ctx.ast.statement_return(right_span, Some(argument));
184-
result.push(last_return_stmt);
176+
stmts.push(last_return_stmt);
185177
}
186178
_ => break 'return_loop,
187179
}
188180
}
189-
} else if let Some(Statement::ThrowStatement(_)) = result.last() {
190-
'throw_loop: while result.len() >= 2 {
191-
let prev_index = result.len() - 2;
192-
let prev_stmt = &result[prev_index];
181+
} else if let Some(Statement::ThrowStatement(_)) = stmts.last() {
182+
'throw_loop: while stmts.len() >= 2 {
183+
let prev_index = stmts.len() - 2;
184+
let prev_stmt = &stmts[prev_index];
193185
match prev_stmt {
194186
Statement::ExpressionStatement(_) => {
195187
ctx.state.changed = true;
196188
// "a(); throw b;" => "throw a(), b;"
197-
let last_stmt = result.pop().unwrap();
189+
let last_stmt = stmts.pop().unwrap();
198190
let Statement::ThrowStatement(mut last_throw) = last_stmt else {
199191
unreachable!()
200192
};
201-
let prev_stmt = result.pop().unwrap();
193+
let prev_stmt = stmts.pop().unwrap();
202194
let Statement::ExpressionStatement(mut expr_stmt) = prev_stmt else {
203195
unreachable!()
204196
};
@@ -209,7 +201,7 @@ impl<'a> PeepholeOptimizations {
209201
);
210202
let right_span = last_throw.span;
211203
let last_throw_stmt = ctx.ast.statement_throw(right_span, argument);
212-
result.push(last_throw_stmt);
204+
stmts.push(last_throw_stmt);
213205
}
214206
// Merge the last two statements
215207
Statement::IfStatement(if_stmt) => {
@@ -223,11 +215,11 @@ impl<'a> PeepholeOptimizations {
223215
};
224216

225217
ctx.state.changed = true;
226-
let last_stmt = result.pop().unwrap();
218+
let last_stmt = stmts.pop().unwrap();
227219
let Statement::ThrowStatement(last_throw) = last_stmt else {
228220
unreachable!()
229221
};
230-
let prev_stmt = result.pop().unwrap();
222+
let prev_stmt = stmts.pop().unwrap();
231223
let Statement::IfStatement(prev_if) = prev_stmt else { unreachable!() };
232224
let mut prev_if = prev_if.unbox();
233225
let Statement::ThrowStatement(prev_throw) = prev_if.consequent else {
@@ -265,15 +257,13 @@ impl<'a> PeepholeOptimizations {
265257
)
266258
};
267259
let last_throw_stmt = ctx.ast.statement_throw(right_span, argument);
268-
result.push(last_throw_stmt);
260+
stmts.push(last_throw_stmt);
269261
}
270262
_ => break 'throw_loop,
271263
}
272264
}
273265
}
274266
}
275-
276-
*stmts = result;
277267
}
278268

279269
fn minimize_statement(

0 commit comments

Comments
 (0)