Skip to content

Commit

Permalink
perf(es/transforms/compat): Migrate parameters to VisitMut (#2804)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj authored Nov 19, 2021
1 parent 1368981 commit 372f5bf
Showing 1 changed file with 99 additions and 114 deletions.
213 changes: 99 additions & 114 deletions crates/swc_ecma_transforms_compat/src/es2015/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use swc_ecma_utils::{
contains_this_expr, member_expr, prepend, prepend_stmts, private_ident, quote_ident,
ExprFactory,
};
use swc_ecma_visit::{noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitMutWith};
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};

pub fn parameters() -> impl 'static + Fold {
Params::default()
as_folder(Params::default())
}

#[derive(Clone, Default)]
Expand Down Expand Up @@ -62,15 +62,13 @@ impl Parallel for Params {
}

impl Params {
fn fold_fn_like(&mut self, ps: Vec<Param>, body: BlockStmt) -> (Vec<Param>, BlockStmt) {
let body_span = body.span;

fn visit_mut_fn_like(&mut self, ps: &mut Vec<Param>, body: &mut BlockStmt) {
let mut params = vec![];
let mut decls = vec![];
let mut unpack_rest = None;
let mut decls_after_unpack = vec![];

for (i, param) in ps.into_iter().enumerate() {
for (i, param) in ps.drain(..).enumerate() {
let span = param.span();

match param.pat {
Expand Down Expand Up @@ -263,7 +261,6 @@ impl Params {
}
}

let mut stmts = body.stmts;
let mut iter: ArrayVec<[_; 3]> = Default::default();

if !decls.is_empty() {
Expand All @@ -283,32 +280,24 @@ impl Params {
declare: false,
})));
}
prepend_stmts(&mut stmts, iter.into_iter());
prepend_stmts(&mut body.stmts, iter.into_iter());

(
params,
BlockStmt {
span: body_span,
stmts,
},
)
*ps = params;
}
}

/// TODO: VisitMut
#[parallel]
impl Fold for Params {
noop_fold_type!();
impl VisitMut for Params {
noop_visit_mut_type!();

fn fold_block_stmt_or_expr(&mut self, body: BlockStmtOrExpr) -> BlockStmtOrExpr {
let body = body.fold_children_with(self);
fn visit_mut_block_stmt_or_expr(&mut self, body: &mut BlockStmtOrExpr) {
body.visit_mut_children_with(self);

if self.vars.is_empty() {
return body;
return;
}

let body = match body {
BlockStmtOrExpr::BlockStmt(v) => v,
match body {
BlockStmtOrExpr::Expr(v) => {
let mut stmts = vec![];
prepend(
Expand All @@ -322,32 +311,31 @@ impl Fold for Params {
);
stmts.push(Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(v),
arg: Some(v.take()),
}));
BlockStmt {
*body = BlockStmtOrExpr::BlockStmt(BlockStmt {
span: DUMMY_SP,
stmts,
}
});
}
_ => {}
};

BlockStmtOrExpr::BlockStmt(body)
}

fn fold_catch_clause(&mut self, f: CatchClause) -> CatchClause {
let f = f.fold_children_with(self);
fn visit_mut_catch_clause(&mut self, f: &mut CatchClause) {
f.visit_mut_children_with(self);

let mut params = vec![];
if f.param.is_some() {
params.push(Param {
span: DUMMY_SP,
decorators: vec![],
pat: f.param.take().unwrap(),
});
}

self.visit_mut_fn_like(&mut params, &mut f.body);

let (mut params, body) = match f.param {
Some(pat) => self.fold_fn_like(
vec![Param {
span: DUMMY_SP,
decorators: vec![],
pat,
}],
f.body,
),
None => self.fold_fn_like(vec![], f.body),
};
assert!(
params.len() == 0 || params.len() == 1,
"fold_fn_like should return 0 ~ 1 parameter while handling catch clause"
Expand All @@ -359,22 +347,19 @@ impl Fold for Params {
Some(params.pop().unwrap())
};

CatchClause {
param: param.map(|param| param.pat),
body,
..f
}
f.param = param.map(|param| param.pat);
}

fn fold_constructor(&mut self, f: Constructor) -> Constructor {
fn visit_mut_constructor(&mut self, f: &mut Constructor) {
if f.body.is_none() {
return f;
return;
}

let f = f.fold_children_with(self);
f.visit_mut_children_with(self);

let params = f
let mut params = f
.params
.take()
.into_iter()
.map(|pat| match pat {
ParamOrTsParamProp::Param(p) => p,
Expand All @@ -384,26 +369,24 @@ impl Fold for Params {
})
.collect();

let (params, body) = self.fold_fn_like(params, f.body.unwrap());
let mut body = f.body.take().unwrap();
self.visit_mut_fn_like(&mut params, &mut body);

Constructor {
params: params.into_iter().map(ParamOrTsParamProp::Param).collect(),
body: Some(body),
..f
}
f.params = params.into_iter().map(ParamOrTsParamProp::Param).collect();
f.body = Some(body);
}

fn fold_expr(&mut self, e: Expr) -> Expr {
fn visit_mut_expr(&mut self, e: &mut Expr) {
let mut vars = self.vars.take();

let e = e.fold_children_with(self);
e.visit_mut_children_with(self);

vars.extend(self.vars.take());
self.vars = vars;

match e {
Expr::Arrow(f) => {
let f = f.fold_children_with(self);
f.visit_mut_children_with(self);

let was_expr = match f.body {
BlockStmtOrExpr::Expr(..) => true,
Expand All @@ -416,26 +399,29 @@ impl Fold for Params {
});

let body_span = f.body.span();
let (params, mut body) = self.fold_fn_like(
f.params
.into_iter()
.map(|pat| Param {
let mut params = f
.params
.take()
.into_iter()
.map(|pat| Param {
span: DUMMY_SP,
decorators: Default::default(),
pat,
})
.collect();

let mut body = match f.body.take() {
BlockStmtOrExpr::BlockStmt(block) => block,
BlockStmtOrExpr::Expr(expr) => BlockStmt {
span: body_span,
stmts: vec![Stmt::Return(ReturnStmt {
span: DUMMY_SP,
decorators: Default::default(),
pat,
})
.collect(),
match f.body {
BlockStmtOrExpr::BlockStmt(block) => block,
BlockStmtOrExpr::Expr(expr) => BlockStmt {
span: body_span,
stmts: vec![Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(expr),
})],
},
arg: Some(expr),
})],
},
);
};

self.visit_mut_fn_like(&mut params, &mut body);

if need_arrow_to_function {
// We are converting an arrow expression to a function expression, and we
Expand All @@ -454,7 +440,7 @@ impl Fold for Params {
body.visit_mut_with(&mut ThisReplacer { to: &this_ident })
}

return Expr::Fn(FnExpr {
*e = Expr::Fn(FnExpr {
ident: None,
function: Function {
params,
Expand All @@ -467,6 +453,7 @@ impl Fold for Params {
return_type: Default::default(),
},
});
return;
}

let body = if was_expr
Expand All @@ -485,70 +472,68 @@ impl Fold for Params {
BlockStmtOrExpr::BlockStmt(body)
};

return Expr::Arrow(ArrowExpr {
*e = Expr::Arrow(ArrowExpr {
params: params.into_iter().map(|param| param.pat).collect(),
body,
..f
span: f.span,
is_async: f.is_async,
is_generator: f.is_generator,
type_params: f.type_params.take(),
return_type: f.return_type.take(),
});
}
_ => e,
_ => {}
}
}

fn fold_function(&mut self, f: Function) -> Function {
fn visit_mut_function(&mut self, f: &mut Function) {
if f.body.is_none() {
return f;
return;
}

let f = f.fold_children_with(self);
f.visit_mut_children_with(self);

let (params, body) = self.fold_fn_like(f.params, f.body.unwrap());
let mut body = f.body.take().unwrap();
self.visit_mut_fn_like(&mut f.params, &mut body);

Function {
params,
body: Some(body),
..f
}
f.body = Some(body);
}

fn fold_getter_prop(&mut self, f: GetterProp) -> GetterProp {
fn visit_mut_getter_prop(&mut self, f: &mut GetterProp) {
if f.body.is_none() {
return f;
return;
}

let f = f.fold_children_with(self);
f.visit_mut_children_with(self);

let (params, body) = self.fold_fn_like(vec![], f.body.unwrap());
let mut params = vec![];
let mut body = f.body.take().unwrap();
self.visit_mut_fn_like(&mut params, &mut body);
debug_assert_eq!(params, vec![]);

GetterProp {
body: Some(body),
..f
}
f.body = Some(body);
}

fn fold_setter_prop(&mut self, f: SetterProp) -> SetterProp {
fn visit_mut_setter_prop(&mut self, f: &mut SetterProp) {
if f.body.is_none() {
return f;
return;
}

let f = f.fold_children_with(self);
f.visit_mut_children_with(self);

let mut params = vec![Param {
span: DUMMY_SP,
decorators: Default::default(),
pat: f.param.take(),
}];

let mut body = f.body.take().unwrap();
self.visit_mut_fn_like(&mut params, &mut body);

let (mut params, body) = self.fold_fn_like(
vec![Param {
span: DUMMY_SP,
decorators: Default::default(),
pat: f.param,
}],
f.body.unwrap(),
);
debug_assert!(params.len() == 1);

SetterProp {
param: params.pop().unwrap().pat,
body: Some(body),
..f
}
f.param = params.pop().unwrap().pat;
f.body = Some(body);
}
}

Expand Down

1 comment on commit 372f5bf

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 372f5bf Previous: 1368981 Ratio
base_tr_fixer 33529 ns/iter (± 6425) 32191 ns/iter (± 6946) 1.04
base_tr_resolver_and_hygiene 187752 ns/iter (± 43482) 163960 ns/iter (± 48668) 1.15
codegen_es2015 66009 ns/iter (± 12982) 53927 ns/iter (± 10027) 1.22
codegen_es2016 68235 ns/iter (± 12204) 55877 ns/iter (± 11236) 1.22
codegen_es2017 67760 ns/iter (± 8270) 57733 ns/iter (± 13202) 1.17
codegen_es2018 67049 ns/iter (± 9840) 55435 ns/iter (± 12033) 1.21
codegen_es2019 68169 ns/iter (± 14893) 55905 ns/iter (± 11522) 1.22
codegen_es2020 68411 ns/iter (± 16931) 58027 ns/iter (± 14517) 1.18
codegen_es3 66754 ns/iter (± 7563) 60295 ns/iter (± 8324) 1.11
codegen_es5 68362 ns/iter (± 13452) 64187 ns/iter (± 11986) 1.07
full_es2015 230970007 ns/iter (± 16242911) 207460133 ns/iter (± 22159062) 1.11
full_es2016 181645065 ns/iter (± 16843810) 159561342 ns/iter (± 23410899) 1.14
full_es2017 190537248 ns/iter (± 18563382) 175807875 ns/iter (± 27311563) 1.08
full_es2018 186529610 ns/iter (± 15453541) 161103104 ns/iter (± 20690003) 1.16
full_es2019 192945179 ns/iter (± 18720530) 153679910 ns/iter (± 23427357) 1.26
full_es2020 186786775 ns/iter (± 16053621) 155023486 ns/iter (± 20546458) 1.20
full_es3 276250885 ns/iter (± 39402309) 239546499 ns/iter (± 60045756) 1.15
full_es5 253359532 ns/iter (± 27336779) 211584079 ns/iter (± 22187657) 1.20
parser 859206 ns/iter (± 334925) 668870 ns/iter (± 113396) 1.28
ser_ast_node 185 ns/iter (± 35) 154 ns/iter (± 25) 1.20
ser_serde 202 ns/iter (± 31) 168 ns/iter (± 21) 1.20
emit_colors 15200723 ns/iter (± 22169233) 14589245 ns/iter (± 20829276) 1.04
emit_large 103998718 ns/iter (± 156332540) 67287559 ns/iter (± 89609271) 1.55
base_clone 2946922 ns/iter (± 599609) 2377773 ns/iter (± 358761) 1.24
fold_span 5023559 ns/iter (± 922192) 4136753 ns/iter (± 746698) 1.21
fold_span_panic 5348559 ns/iter (± 870059) 4338306 ns/iter (± 914616) 1.23
visit_mut_span 3620383 ns/iter (± 778275) 2970676 ns/iter (± 677778) 1.22
visit_mut_span_panic 3631950 ns/iter (± 1467782) 3076358 ns/iter (± 536228) 1.18
ast_clone 26031 ns/iter (± 5862) 22122 ns/iter (± 5520) 1.18
ast_clone_to_stable 82572 ns/iter (± 19753) 76558 ns/iter (± 8607) 1.08
ast_clone_to_stable_then_to_unstable 146004 ns/iter (± 28573) 137728 ns/iter (± 29188) 1.06
json_deserialize 2840084 ns/iter (± 452851) 2312178 ns/iter (± 430276) 1.23
json_serialize 120479 ns/iter (± 22433) 106065 ns/iter (± 16177) 1.14
boxing_boxed 207 ns/iter (± 49) 155 ns/iter (± 29) 1.34
boxing_boxed_clone 80 ns/iter (± 17) 77 ns/iter (± 13) 1.04
boxing_unboxed 166 ns/iter (± 50) 138 ns/iter (± 20) 1.20
boxing_unboxed_clone 102 ns/iter (± 21) 75 ns/iter (± 13) 1.36

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.