Skip to content

Commit

Permalink
fix(es/minifier): Don't drop an inlined parameter as a duplicate (#6293)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Nov 2, 2022
1 parent d22a400 commit dd797f7
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 47 deletions.
53 changes: 10 additions & 43 deletions crates/swc_ecma_minifier/src/compress/optimize/mod.rs
@@ -1,4 +1,4 @@
use std::{iter::once, mem::take};
use std::iter::once;

use rustc_hash::{FxHashMap, FxHashSet};
use swc_atoms::{js_word, JsWord};
Expand All @@ -19,7 +19,7 @@ use Value::Known;

use self::{
unused::PropertyAccessOpts,
util::{extract_class_side_effect, Finalizer, NormalMultiReplacer},
util::{extract_class_side_effect, Finalizer, NormalMultiReplacer, SynthesizedStmts},
};
use super::util::{drop_invalid_stmts, is_fine_for_if_cons};
#[cfg(feature = "debug")]
Expand Down Expand Up @@ -1383,8 +1383,8 @@ where
let mut old_prepend_stmts = self.prepend_stmts.take();
let old_append_stmts = self.append_stmts.take();
n.visit_mut_with(self);
old_prepend_stmts.append(&mut *self.prepend_stmts);
old_prepend_stmts.append(&mut *self.append_stmts);
old_prepend_stmts.append(&mut self.prepend_stmts);
old_prepend_stmts.append(&mut self.append_stmts);

self.prepend_stmts = old_prepend_stmts;
self.append_stmts = old_append_stmts;
Expand Down Expand Up @@ -2423,11 +2423,15 @@ where
// We use var decl with no declarator to indicate we dropped an decl.
Stmt::Decl(Decl::Var(v)) if v.decls.is_empty() => {
*s = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
self.prepend_stmts = old_prepend;
self.append_stmts = old_append;
return;
}
Stmt::Expr(es) => {
if es.expr.is_invalid() {
*s = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
self.prepend_stmts = old_prepend;
self.append_stmts = old_append;
return;
}
}
Expand Down Expand Up @@ -2459,6 +2463,8 @@ where
Stmt::Decl(Decl::Var(v)) if v.decls.is_empty() => {
s.take();
if self.prepend_stmts.is_empty() && self.append_stmts.is_empty() {
self.prepend_stmts = old_prepend;
self.append_stmts = old_append;
return;
}
}
Expand Down Expand Up @@ -3062,42 +3068,3 @@ fn is_left_access_to_arguments(l: &PatOrExpr) -> bool {
},
}
}

#[derive(Debug, Default, PartialEq, Eq)]
struct SynthesizedStmts(Vec<Stmt>);

impl SynthesizedStmts {
fn take_stmts(&mut self) -> Vec<Stmt> {
take(&mut self.0)
}
}

impl std::ops::Deref for SynthesizedStmts {
type Target = Vec<Stmt>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl std::ops::DerefMut for SynthesizedStmts {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl Take for SynthesizedStmts {
fn dummy() -> Self {
Self(Take::dummy())
}
}

impl Drop for SynthesizedStmts {
fn drop(&mut self) {
if !self.0.is_empty() {
if !std::thread::panicking() {
panic!("We should not drop synthesized stmts");
}
}
}
}
Expand Up @@ -492,7 +492,7 @@ where
prepend_stmts(stmts, self.prepend_stmts.drain(..).map(T::from_stmt));
}

if self.append_stmts.is_empty() {
if !self.append_stmts.is_empty() {
stmts.extend(self.append_stmts.drain(..).map(T::from_stmt));
}

Expand Down
9 changes: 7 additions & 2 deletions crates/swc_ecma_minifier/src/compress/optimize/unused.rs
Expand Up @@ -759,9 +759,14 @@ where
for d in var.decls.iter_mut() {
if d.init.is_none() {
if let Pat::Ident(name) = &d.name {
if let Some(usage) = self.data.vars.get(&name.to_id()) {
if usage.is_fn_local && usage.declared_as_fn_param {
if let Some(usage) = self.data.vars.get_mut(&name.to_id()) {
if usage.is_fn_local
&& usage.declared_as_fn_param
&& usage.declared_count >= 2
{
d.name.take();
usage.declared_count -= 1;

report_change!(
"Removing a variable statement because it's a function parameter"
);
Expand Down
58 changes: 57 additions & 1 deletion crates/swc_ecma_minifier/src/compress/optimize/util.rs
@@ -1,4 +1,7 @@
use std::ops::{Deref, DerefMut};
use std::{
mem::take,
ops::{Deref, DerefMut},
};

use rustc_hash::{FxHashMap, FxHashSet};
use swc_atoms::js_word;
Expand Down Expand Up @@ -532,3 +535,56 @@ impl VisitMut for ExprReplacer {
}
}
}

#[derive(Debug, Default, PartialEq, Eq)]
pub(super) struct SynthesizedStmts(Vec<Stmt>);

impl SynthesizedStmts {
pub fn take_stmts(&mut self) -> Vec<Stmt> {
take(&mut self.0)
}
}

impl std::ops::Deref for SynthesizedStmts {
type Target = Vec<Stmt>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl SynthesizedStmts {
pub fn push(&mut self, stmt: Stmt) {
self.0.push(stmt);
}

pub fn extend(&mut self, stmts: impl IntoIterator<Item = Stmt>) {
self.0.extend(stmts);
}

pub fn append(&mut self, other: &mut SynthesizedStmts) {
self.0.append(&mut other.0);
}
}

impl std::ops::DerefMut for SynthesizedStmts {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl Take for SynthesizedStmts {
fn dummy() -> Self {
Self(Take::dummy())
}
}

impl Drop for SynthesizedStmts {
fn drop(&mut self) {
if !self.0.is_empty() {
if !std::thread::panicking() {
panic!("We should not drop synthesized stmts");
}
}
}
}
14 changes: 14 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/next/tinymce/1/input.js
@@ -0,0 +1,14 @@
Yp.revoke, (a => Yp.config((b => ({
aria: {
mode: "checked"
},
...ge(b, ((e, t) => "exclusive" !== t)),
onToggled: (c, d) => {
p(b.onToggled) && b.onToggled(c, d), ((e, f) => {
Or(e, th, {
item: e,
state: f
})
})(c, d)
}
}))(a)))
12 changes: 12 additions & 0 deletions crates/swc_ecma_minifier/tests/fixture/next/tinymce/1/output.js
@@ -0,0 +1,12 @@
Yp.revoke, (a)=>Yp.config({
aria: {
mode: "checked"
},
...ge(a, (e, t)=>"exclusive" !== t),
onToggled (c, d) {
p(a.onToggled) && a.onToggled(c, d), Or(c, th, {
item: c,
state: d
});
}
});

1 comment on commit dd797f7

@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: dd797f7 Previous: 5d52ae9 Ratio
es/full/bugs-1 340738 ns/iter (± 30990) 333499 ns/iter (± 19664) 1.02
es/full/minify/libraries/antd 1855953349 ns/iter (± 55052703) 1821367285 ns/iter (± 21294944) 1.02
es/full/minify/libraries/d3 393567280 ns/iter (± 10591097) 395646308 ns/iter (± 15568813) 0.99
es/full/minify/libraries/echarts 1531522597 ns/iter (± 71969395) 1529611573 ns/iter (± 17266138) 1.00
es/full/minify/libraries/jquery 103538818 ns/iter (± 8282540) 97840769 ns/iter (± 1514192) 1.06
es/full/minify/libraries/lodash 128417537 ns/iter (± 5157873) 115607946 ns/iter (± 1698643) 1.11
es/full/minify/libraries/moment 65275093 ns/iter (± 6192070) 57688801 ns/iter (± 884911) 1.13
es/full/minify/libraries/react 22914326 ns/iter (± 2051115) 20075903 ns/iter (± 419054) 1.14
es/full/minify/libraries/terser 338876282 ns/iter (± 26168229) 317650668 ns/iter (± 12046523) 1.07
es/full/minify/libraries/three 560720392 ns/iter (± 20046470) 545790497 ns/iter (± 14480442) 1.03
es/full/minify/libraries/typescript 3334931660 ns/iter (± 163276236) 3278454545 ns/iter (± 71952773) 1.02
es/full/minify/libraries/victory 789340773 ns/iter (± 17877986) 829572867 ns/iter (± 12864134) 0.95
es/full/minify/libraries/vue 152667188 ns/iter (± 11238987) 150604834 ns/iter (± 6633383) 1.01
es/full/codegen/es3 34213 ns/iter (± 674) 33425 ns/iter (± 622) 1.02
es/full/codegen/es5 34140 ns/iter (± 485) 33446 ns/iter (± 431) 1.02
es/full/codegen/es2015 34143 ns/iter (± 395) 33111 ns/iter (± 727) 1.03
es/full/codegen/es2016 34253 ns/iter (± 1055) 33354 ns/iter (± 869) 1.03
es/full/codegen/es2017 34219 ns/iter (± 962) 33367 ns/iter (± 1849) 1.03
es/full/codegen/es2018 34166 ns/iter (± 635) 33350 ns/iter (± 1547) 1.02
es/full/codegen/es2019 34200 ns/iter (± 532) 33220 ns/iter (± 911) 1.03
es/full/codegen/es2020 36642 ns/iter (± 2847) 33246 ns/iter (± 735) 1.10
es/full/all/es3 252675992 ns/iter (± 105369439) 186887264 ns/iter (± 10693052) 1.35
es/full/all/es5 217022798 ns/iter (± 46944450) 176958837 ns/iter (± 6813676) 1.23
es/full/all/es2015 158795045 ns/iter (± 39687933) 142058528 ns/iter (± 5555615) 1.12
es/full/all/es2016 167980304 ns/iter (± 70551796) 142416710 ns/iter (± 6560502) 1.18
es/full/all/es2017 182830789 ns/iter (± 64900575) 140753085 ns/iter (± 6150161) 1.30
es/full/all/es2018 172030182 ns/iter (± 70326348) 140376638 ns/iter (± 8008789) 1.23
es/full/all/es2019 157737181 ns/iter (± 42420573) 145081774 ns/iter (± 5920782) 1.09
es/full/all/es2020 150371363 ns/iter (± 45892026) 139443199 ns/iter (± 7624274) 1.08
es/full/parser 778984 ns/iter (± 42277) 731386 ns/iter (± 27637) 1.07
es/full/base/fixer 28169 ns/iter (± 6191) 26935 ns/iter (± 1774) 1.05
es/full/base/resolver_and_hygiene 103426 ns/iter (± 8372) 91564 ns/iter (± 3220) 1.13
serialization of ast node 224 ns/iter (± 38) 213 ns/iter (± 2) 1.05
serialization of serde 225 ns/iter (± 11) 213 ns/iter (± 3) 1.06

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

Please sign in to comment.