Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(es/ast): Shrink size of Expr #7041

Merged
merged 23 commits into from
Mar 9, 2023
12 changes: 9 additions & 3 deletions crates/swc_ecma_ast/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ pub enum Expr {
Invalid(Invalid),
}

#[cfg(target_pointer_width = "64")]
assert_eq_size!(Expr, [u8; 80]);

impl Expr {
/// Normalize parenthesized expressions.
///
Expand Down Expand Up @@ -862,7 +865,8 @@ pub struct ArrowExpr {

pub params: Vec<Pat>,

pub body: BlockStmtOrExpr,
/// This is boxed to reduce the type size of [Expr].
pub body: Box<BlockStmtOrExpr>,

#[serde(default, rename = "async")]
pub is_async: bool,
Expand Down Expand Up @@ -978,8 +982,9 @@ pub struct TaggedTpl {
#[serde(default, rename = "typeParameters")]
pub type_params: Option<Box<TsTypeParamInstantiation>>,

/// This is boxed to reduce the type size of [Expr].
#[serde(rename = "template")]
pub tpl: Tpl,
pub tpl: Box<Tpl>,
}

impl Take for TaggedTpl {
Expand Down Expand Up @@ -1366,7 +1371,8 @@ impl Take for PatOrExpr {
pub struct OptChainExpr {
pub span: Span,
pub question_dot_token: Span,
pub base: OptChainBase,
/// This is boxed to reduce the type size of [Expr].
pub base: Box<OptChainBase>,
}

#[ast_node]
Expand Down
9 changes: 9 additions & 0 deletions crates/swc_ecma_ast/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,12 @@ macro_rules! bridge_decl_from {
bridge_from!(crate::ModuleItem, crate::Stmt, $src);
};
}

/// Copied from static_assertions
macro_rules! assert_eq_size {
($x:ty, $($xs:ty),+ $(,)?) => {
const _: fn() = || {
$(let _ = std::mem::transmute::<$x, $xs>;)+
};
};
}
3 changes: 3 additions & 0 deletions crates/swc_ecma_ast/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ pub enum Stmt {
Expr(ExprStmt),
}

#[cfg(target_pointer_width = "64")]
assert_eq_size!(Stmt, [u8; 64]);

// Implement Clone without inline to avoid multiple copies of the
// implementation.
impl Clone for Stmt {
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ where
fn emit_opt_chain(&mut self, n: &OptChainExpr) -> Result {
self.emit_leading_comments_of_span(n.span(), false)?;

match n.base {
match &*n.base {
OptChainBase::Member(ref e) => {
if let Expr::New(new) = &*e.obj {
self.emit_new(new, false)?;
Expand Down
13 changes: 4 additions & 9 deletions crates/swc_ecma_codegen/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,10 @@ impl StartsWithAlphaNum for Expr {
| Expr::TsInstantiation(TsInstantiation { ref expr, .. })
| Expr::TsSatisfies(TsSatisfiesExpr { ref expr, .. }) => expr.starts_with_alpha_num(),

Expr::OptChain(OptChainExpr {
base: OptChainBase::Member(MemberExpr { obj: expr, .. }),
..
}) => expr.starts_with_alpha_num(),

Expr::OptChain(OptChainExpr {
base: OptChainBase::Call(OptCall { callee, .. }),
..
}) => callee.starts_with_alpha_num(),
Expr::OptChain(OptChainExpr { base, .. }) => match &**base {
OptChainBase::Member(base) => base.obj.starts_with_alpha_num(),
OptChainBase::Call(base) => base.callee.starts_with_alpha_num(),
},

Expr::Invalid(..) => true,
}
Expand Down
1 change: 1 addition & 0 deletions crates/swc_ecma_lints/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg_attr(feature = "non_critical_lints", deny(unused))]
#![cfg_attr(feature = "non_critical_lints", deny(clippy::all))]
#![feature(box_patterns)]

pub mod config;
pub mod rule;
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_lints/src/rules/duplicate_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl Visit for DuplicateBindings {
return_type: _,
} = a;
params.visit_with(self);
if let BlockStmtOrExpr::BlockStmt(b) = body {
if let BlockStmtOrExpr::BlockStmt(b) = &**body {
self.visit_with_stmts(&b.stmts, false)
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_lints/src/rules/no_alert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl NoAlert {
}
Expr::Member(member_expr)
| Expr::OptChain(OptChainExpr {
base: OptChainBase::Member(member_expr),
base: box OptChainBase::Member(member_expr),
..
}) => {
let MemberExpr { obj, prop, .. } = member_expr;
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_lints/src/rules/no_empty_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl Visit for NoEmptyFunction {
}

fn visit_arrow_expr(&mut self, function: &ArrowExpr) {
if let BlockStmtOrExpr::BlockStmt(BlockStmt { stmts, span }) = &function.body {
if let BlockStmtOrExpr::BlockStmt(BlockStmt { stmts, span }) = &*function.body {
if self.consider_comments && self.has_comment_in_body(span) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_lints/src/rules/radix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ impl Radix {
return self.extract_obj_and_prop_member_case(member_expr);
}
Expr::OptChain(OptChainExpr {
base: OptChainBase::Member(member_expr),
base: box OptChainBase::Member(member_expr),
..
}) => {
return self.extract_obj_and_prop_member_case(member_expr);
Expand Down
10 changes: 3 additions & 7 deletions crates/swc_ecma_lints/src/rules/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,8 @@ pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue
ArgValue::Other
}
}
Expr::TaggedTpl(TaggedTpl {
tag,
tpl: Tpl { exprs, quasis, .. },
..
}) => {
if exprs.is_empty() {
Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => {
if tpl.exprs.is_empty() {
if let Expr::Member(MemberExpr { obj, prop, .. }) = tag.as_ref() {
if let (Expr::Ident(obj), MemberProp::Ident(prop)) = (obj.as_ref(), prop) {
if &*obj.sym != "String" {
Expand All @@ -87,7 +83,7 @@ pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue
return ArgValue::Other;
}

return ArgValue::Str(quasis.first().unwrap().raw.clone());
return ArgValue::Str(tpl.quasis.first().unwrap().raw.clone());
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/swc_ecma_minifier/src/compress/optimize/iife.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ where
}

if self.ctx.in_top_level() && !self.ctx.in_call_arg && self.options.negate_iife {
match &f.body {
match &*f.body {
BlockStmtOrExpr::BlockStmt(body) => {
let has_decl =
body.stmts.iter().any(|stmt| matches!(stmt, Stmt::Decl(..)));
Expand All @@ -494,7 +494,7 @@ where
.map(|p| p.clone().ident().unwrap().id)
.collect::<Vec<_>>();

match &mut f.body {
match &mut *f.body {
BlockStmtOrExpr::BlockStmt(body) => {
let new = self.inline_fn_like(&param_ids, body, &mut call.args);
if let Some(new) = new {
Expand Down Expand Up @@ -1080,7 +1080,7 @@ where

Expr::Arrow(ArrowExpr {
params,
body: BlockStmtOrExpr::Expr(body),
body: box BlockStmtOrExpr::Expr(body),
is_async: false,
is_generator: false,
..
Expand All @@ -1107,7 +1107,7 @@ fn find_params(callee: &mut Expr) -> Option<Vec<&mut Pat>> {
}
fn find_body(callee: &mut Expr) -> Option<Either<&mut BlockStmt, &mut Expr>> {
match callee {
Expr::Arrow(e) => match &mut e.body {
Expr::Arrow(e) => match &mut *e.body {
BlockStmtOrExpr::BlockStmt(b) => Some(Either::Left(b)),
BlockStmtOrExpr::Expr(b) => Some(Either::Right(&mut **b)),
},
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/src/compress/optimize/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ fn is_arrow_simple_enough_for_copy(e: &ArrowExpr) -> bool {
return false;
}

match &e.body {
match &*e.body {
BlockStmtOrExpr::BlockStmt(s) => is_block_stmt_of_fn_simple_enough_for_copy(s),
BlockStmtOrExpr::Expr(e) => is_arrow_body_simple_enough_for_copy(e),
}
Expand Down
10 changes: 5 additions & 5 deletions crates/swc_ecma_minifier/src/compress/optimize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ where
.as_ref()
.map(|body| body.stmts.is_empty())
.unwrap_or(false),
Expr::Arrow(f) => match &f.body {
Expr::Arrow(f) => match &*f.body {
BlockStmtOrExpr::BlockStmt(body) => body.stmts.is_empty(),
BlockStmtOrExpr::Expr(_) => false,
},
Expand Down Expand Up @@ -1407,7 +1407,7 @@ where

if !self.prepend_stmts.is_empty() {
let mut stmts = self.prepend_stmts.take().take_stmts();
match &mut n.body {
match &mut *n.body {
BlockStmtOrExpr::BlockStmt(v) => {
prepend_stmts(&mut v.stmts, stmts.into_iter());
}
Expand All @@ -1419,17 +1419,17 @@ where
span: DUMMY_SP,
arg: Some(v.take()),
}));
n.body = BlockStmtOrExpr::BlockStmt(BlockStmt {
n.body = Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt {
span: DUMMY_SP,
stmts,
});
}));
}
}
}

self.prepend_stmts = prepend;

if let BlockStmtOrExpr::BlockStmt(body) = &mut n.body {
if let BlockStmtOrExpr::BlockStmt(body) = &mut *n.body {
drop_invalid_stmts(&mut body.stmts);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,7 @@ where
Expr::Paren(e) => self.is_skippable_for_seq(a, &e.expr),
Expr::Unary(e) => self.is_skippable_for_seq(a, &e.arg),

Expr::OptChain(OptChainExpr { base, .. }) => match base {
Expr::OptChain(OptChainExpr { base, .. }) => match &**base {
OptChainBase::Member(e) => {
if !self.should_preserve_property_access(
&e.obj,
Expand Down
6 changes: 3 additions & 3 deletions crates/swc_ecma_minifier/src/compress/pure/arrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Pure<'_> {
*e = Expr::Arrow(ArrowExpr {
span: function.span,
params: function.params.take().into_iter().map(|p| p.pat).collect(),
body: BlockStmtOrExpr::BlockStmt(function.body.take().unwrap()),
body: Box::new(BlockStmtOrExpr::BlockStmt(function.body.take().unwrap())),
is_async: function.is_async,
is_generator: function.is_generator,
type_params: Default::default(),
Expand Down Expand Up @@ -104,7 +104,7 @@ impl Pure<'_> {
.into_iter()
.map(|v| v.pat)
.collect(),
body: BlockStmtOrExpr::Expr(arg),
body: Box::new(BlockStmtOrExpr::Expr(arg)),
is_async: m.function.is_async,
is_generator: m.function.is_generator,
type_params: Default::default(),
Expand Down Expand Up @@ -133,7 +133,7 @@ impl Pure<'_> {

if let Expr::Arrow(
m @ ArrowExpr {
body: BlockStmtOrExpr::BlockStmt(..),
body: box BlockStmtOrExpr::BlockStmt(..),
..
},
) = &mut *kv.value
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/src/compress/pure/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ impl Pure<'_> {
_ => return,
};

match &mut opt.base {
match &mut *opt.base {
OptChainBase::Member(MemberExpr { span, obj, .. }) => {
//
if is_pure_undefined_or_null(&self.expr_ctx, obj) {
Expand Down
12 changes: 4 additions & 8 deletions crates/swc_ecma_minifier/src/compress/pure/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ impl Pure<'_> {
_ => return,
};

if let OptChainBase::Member(base) = &mut opt.base {
if let OptChainBase::Member(base) = &mut *opt.base {
if match &*base.obj {
Expr::Lit(Lit::Null(..)) => false,
Expr::Lit(..) | Expr::Object(..) | Expr::Array(..) => true,
Expand Down Expand Up @@ -866,15 +866,11 @@ impl Pure<'_> {
return;
}

Expr::TaggedTpl(TaggedTpl {
span,
tpl: Tpl { exprs, .. },
..
}) if span.has_mark(self.marks.pure) => {
Expr::TaggedTpl(TaggedTpl { span, tpl, .. }) if span.has_mark(self.marks.pure) => {
report_change!("ignore_return_value: Dropping a pure call");
self.changed = true;

let new = self.make_ignored_expr(exprs.take().into_iter());
let new = self.make_ignored_expr(tpl.exprs.take().into_iter());

*e = new.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
return;
Expand Down Expand Up @@ -1228,7 +1224,7 @@ impl Pure<'_> {
}
}
}
Expr::Arrow(callee) => match &mut callee.body {
Expr::Arrow(callee) => match &mut *callee.body {
BlockStmtOrExpr::BlockStmt(body) => {
for stmt in &mut body.stmts {
self.ignore_return_value_of_return_stmt(stmt, opts);
Expand Down
1 change: 1 addition & 0 deletions crates/swc_ecma_minifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#![allow(clippy::only_used_in_recursion)]
#![allow(unstable_name_collisions)]
#![allow(clippy::match_like_matches_macro)]
#![feature(box_patterns)]

use once_cell::sync::Lazy;
use swc_common::{comments::Comments, pass::Repeated, sync::Lrc, SourceMap, SyntaxContext};
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/src/pass/global_defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ fn should_replace(pred: &Expr, node: &Expr) -> bool {
})
| Expr::OptChain(OptChainExpr {
base:
OptChainBase::Member(MemberExpr {
box OptChainBase::Member(MemberExpr {
obj: node_obj,
prop: nodes,
..
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/src/util/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl SizeWithCtxt for Expr {
body,
is_async,
..
}) => match body {
}) => match &**body {
BlockStmtOrExpr::BlockStmt(_) => TODO,
BlockStmtOrExpr::Expr(e) => {
let p = match &params[..] {
Expand All @@ -178,7 +178,7 @@ impl SizeWithCtxt for Expr {
MetaPropKind::ImportMeta => 11,
},
Expr::PrivateName(p) => p.size(),
Expr::OptChain(p) => match &p.base {
Expr::OptChain(p) => match &*p.base {
OptChainBase::Member(m) => 1 + m.obj.size(unresolved) + m.prop.size(unresolved),
OptChainBase::Call(c) => {
1 + c.callee.size(unresolved) + c.args.size(unresolved) + 2
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/tests/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ impl VisitMut for PartialInliner {
raw: Atom::new(&*s.value),
cooked: Some(Atom::new(&*s.value)),
};
tt.tpl = Tpl {
tt.tpl = Box::new(Tpl {
span: el.span,
exprs: Default::default(),
quasis: vec![el],
};
});
}
_ => {
unreachable!()
Expand Down
Loading