Skip to content

Commit

Permalink
fix(es/minifier): Fix analysis of parameters (#5954)
Browse files Browse the repository at this point in the history
**Description:**

Although the author of the issue talked about `@react-pdf/renderer`, it's a bug related to `brotli`, not react pdf renderer.

After investigation, I found that the bug is caused by not marking parameters as initialized. So I fixed the analyzer.

**Related issue:**

 - vercel/next.js#40803.
  • Loading branch information
kdy1 committed Sep 27, 2022
1 parent 132a938 commit 33a15c8
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 12 deletions.
6 changes: 5 additions & 1 deletion crates/swc_ecma_minifier/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ impl VarUsageInfo {
pub fn reassigned(&self) -> bool {
self.reassigned_with_assignment
|| self.reassigned_with_var_decl
|| (u32::from(self.var_initialized) + self.assign_count) > 1
|| (u32::from(self.var_initialized)
+ u32::from(self.declared_as_catch_param)
+ u32::from(self.declared_as_fn_param)
+ self.assign_count)
> 1
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2121,7 +2121,7 @@
domBuilder.startDocument(), _copy(defaultNSMap, defaultNSMap = {}), function(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
function entityReplacer(a) {
var code, k = a.slice(1, -1);
return k in entityMap ? entityMap[k] : "#" !== k.charAt(0) ? (errorHandler.error("entity not found:" + a), a) : (code = parseInt(k.substr(1).replace("x", "0x"))) > 0xffff ? String.fromCharCode(0xd800 + ((code -= 0x10000) >> 10), 0xdc00 + (0x3ff & code)) : String.fromCharCode(code);
return k in entityMap ? entityMap[k] : "#" === k.charAt(0) ? (code = parseInt(k.substr(1).replace("x", "0x"))) > 0xffff ? String.fromCharCode(0xd800 + ((code -= 0x10000) >> 10), 0xdc00 + (0x3ff & code)) : String.fromCharCode(code) : (errorHandler.error("entity not found:" + a), a);
}
function appendText(end) {
if (end > start) {
Expand Down Expand Up @@ -5587,12 +5587,18 @@
}, Buffer.prototype.readDoubleBE = function(offset, noAssert) {
return offset >>>= 0, noAssert || checkOffset(offset, 8, this.length), ieee754.read(this, offset, !1, 52, 8);
}, Buffer.prototype.writeUIntLE = function(value, offset, byteLength, noAssert) {
value = +value, offset >>>= 0, byteLength >>>= 0, noAssert || checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength) - 1, 0);
if (value = +value, offset >>>= 0, byteLength >>>= 0, !noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
var mul = 1, i = 0;
for(this[offset] = 0xff & value; ++i < byteLength && (mul *= 0x100);)this[offset + i] = value / mul & 0xff;
return offset + byteLength;
}, Buffer.prototype.writeUIntBE = function(value, offset, byteLength, noAssert) {
value = +value, offset >>>= 0, byteLength >>>= 0, noAssert || checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength) - 1, 0);
if (value = +value, offset >>>= 0, byteLength >>>= 0, !noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1;
checkInt(this, value, offset, byteLength, maxBytes, 0);
}
var i = byteLength - 1, mul = 1;
for(this[offset + i] = 0xff & value; --i >= 0 && (mul *= 0x100);)this[offset + i] = value / mul & 0xff;
return offset + byteLength;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"defaults": false,
"toplevel": true,
"inline": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[545], {


/***/ 966:
/***/ (function (__unused_webpack_module, exports) {

function HuffmanCode(bits, value) {
this.bits = bits; /* number of bits used for this symbol */
this.value = value; /* symbol value or table offset */
}

exports.h = HuffmanCode;

var MAX_LENGTH = 15;

/* Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the
bit-wise reversal of the len least significant bits of key. */
function GetNextKey(key, len) {
var step = 1 << (len - 1);
while (key & step) {
step >>= 1;
}
return (key & (step - 1)) + step;
}

/* Stores code in table[0], table[step], table[2*step], ..., table[end] */
/* Assumes that end is an integer multiple of step */
function ReplicateValue(table, i, step, end, code) {
do {
end -= step;
table[i + end] = new HuffmanCode(code.bits, code.value);
} while (end > 0);
}

/* Returns the table width of the next 2nd level table. count is the histogram
of bit lengths for the remaining symbols, len is the code length of the next
processed symbol */
function NextTableBitSize(count, len, root_bits) {
var left = 1 << (len - root_bits);
while (len < MAX_LENGTH) {
left -= count[len];
if (left <= 0) break;
++len;
left <<= 1;
}
return len - root_bits;
}

exports.g = function (root_table, table, root_bits, code_lengths, code_lengths_size) {
var start_table = table;
var code; /* current table entry */
var len; /* current code length */
var symbol; /* symbol index in original or sorted table */
var key; /* reversed prefix code */
var step; /* step size to replicate values in current table */
var low; /* low bits for current root entry */
var mask; /* mask for low bits */
var table_bits; /* key length of current table */
var table_size; /* size of current table */
var total_size; /* sum of root table size and 2nd level table sizes */
var sorted; /* symbols sorted by code length */
var count = new Int32Array(MAX_LENGTH + 1); /* number of codes of each length */
var offset = new Int32Array(MAX_LENGTH + 1); /* offsets in sorted table for each length */

sorted = new Int32Array(code_lengths_size);

/* build histogram of code lengths */
for (symbol = 0; symbol < code_lengths_size; symbol++) {
count[code_lengths[symbol]]++;
}

/* generate offsets into sorted symbol table by code length */
offset[1] = 0;
for (len = 1; len < MAX_LENGTH; len++) {
offset[len + 1] = offset[len] + count[len];
}

/* sort symbols by length, by symbol order within each length */
for (symbol = 0; symbol < code_lengths_size; symbol++) {
if (code_lengths[symbol] !== 0) {
sorted[offset[code_lengths[symbol]]++] = symbol;
}
}

table_bits = root_bits;
table_size = 1 << table_bits;
total_size = table_size;

/* special case code with only one value */
if (offset[MAX_LENGTH] === 1) {
for (key = 0; key < total_size; ++key) {
root_table[table + key] = new HuffmanCode(0, sorted[0] & 0xffff);
}

return total_size;
}

/* fill in root table */
key = 0;
symbol = 0;
for (len = 1, step = 2; len <= root_bits; ++len, step <<= 1) {
for (; count[len] > 0; --count[len]) {
code = new HuffmanCode(len & 0xff, sorted[symbol++] & 0xffff);
ReplicateValue(root_table, table + key, step, table_size, code);
key = GetNextKey(key, len);
}
}

/* fill in 2nd level tables and add pointers to root table */
mask = total_size - 1;
low = -1;
for (len = root_bits + 1, step = 2; len <= MAX_LENGTH; ++len, step <<= 1) {
for (; count[len] > 0; --count[len]) {
if ((key & mask) !== low) {
table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
low = key & mask;
root_table[start_table + low] = new HuffmanCode((table_bits + root_bits) & 0xff, ((table - start_table) - low) & 0xffff);
}
code = new HuffmanCode((len - root_bits) & 0xff, sorted[symbol++] & 0xffff);
ReplicateValue(root_table, table + (key >> root_bits), step, table_size, code);
key = GetNextKey(key, len);
}
}

return total_size;
}


/***/
}),

}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[
545
],
{
966: function(__unused_webpack_module, exports) {
function HuffmanCode(bits, value) {
this.bits = bits;
this.value = value;
}
exports.h = HuffmanCode;
function GetNextKey(key, len) {
var step = 1 << len - 1;
while(key & step){
step >>= 1;
}
return (key & step - 1) + step;
}
function ReplicateValue(table, i, step, end, code) {
do {
end -= step;
table[i + end] = new HuffmanCode(code.bits, code.value);
}while (end > 0)
}
function NextTableBitSize(count, len, root_bits) {
var left = 1 << len - root_bits;
while(len < 15){
left -= count[len];
if (left <= 0) break;
++len;
left <<= 1;
}
return len - root_bits;
}
exports.g = function(root_table, table, root_bits, code_lengths, code_lengths_size) {
var start_table = table;
var code;
var len;
var symbol;
var key;
var step;
var low;
var mask;
var table_bits;
var table_size;
var total_size;
var sorted;
var count = new Int32Array(16);
var offset = new Int32Array(16);
sorted = new Int32Array(code_lengths_size);
for(symbol = 0; symbol < code_lengths_size; symbol++)count[code_lengths[symbol]]++;
offset[1] = 0;
for(len = 1; len < 15; len++)offset[len + 1] = offset[len] + count[len];
for(symbol = 0; symbol < code_lengths_size; symbol++)if (0 !== code_lengths[symbol]) sorted[offset[code_lengths[symbol]]++] = symbol;
table_bits = root_bits;
table_size = 1 << table_bits;
total_size = table_size;
if (1 === offset[15]) {
for(key = 0; key < total_size; ++key)root_table[table + key] = new HuffmanCode(0, 0xffff & sorted[0]);
return total_size;
}
key = 0;
symbol = 0;
for(len = 1, step = 2; len <= root_bits; ++len, step <<= 1){
for(; count[len] > 0; --count[len]){
code = new HuffmanCode(0xff & len, 0xffff & sorted[symbol++]);
ReplicateValue(root_table, table + key, step, table_size, code);
key = GetNextKey(key, len);
}
}
mask = total_size - 1;
low = -1;
for(len = root_bits + 1, step = 2; len <= 15; ++len, step <<= 1){
for(; count[len] > 0; --count[len]){
if ((key & mask) !== low) {
table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
low = key & mask;
root_table[start_table + low] = new HuffmanCode(table_bits + root_bits & 0xff, table - start_table - low & 0xffff);
}
code = new HuffmanCode(len - root_bits & 0xff, 0xffff & sorted[symbol++]);
ReplicateValue(root_table, table + (key >> root_bits), step, table_size, code);
key = GetNextKey(key, len);
}
}
return total_size;
};
}
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
[
545
],
{
966: (function(r, n) {
function a(r, n) {
this.bits = r;
this.value = n;
}
n.h = a;
var e = 15;
function f(r, n) {
var a = 1 << (n - 1);
while(r & a){
a >>= 1;
}
return (r & (a - 1)) + a;
}
function v(r, n, e, f, v) {
do {
f -= e;
r[n + f] = new a(v.bits, v.value);
}while (f > 0)
}
function i(r, n, a) {
var f = 1 << (n - a);
while(n < e){
f -= r[n];
if (f <= 0) break;
++n;
f <<= 1;
}
return n - a;
}
n.g = function(r, n, t, o, u) {
var w = n;
var h;
var c;
var l;
var s;
var b;
var k;
var _;
var p;
var y;
var A;
var I;
var C = new Int32Array(e + 1);
var E = new Int32Array(e + 1);
I = new Int32Array(u);
for(l = 0; l < u; l++){
C[o[l]]++;
}
E[1] = 0;
for(c = 1; c < e; c++){
E[c + 1] = E[c] + C[c];
}
for(l = 0; l < u; l++){
if (o[l] !== 0) {
I[E[o[l]]++] = l;
}
}
p = t;
y = 1 << p;
A = y;
if (E[e] === 1) {
for(s = 0; s < A; ++s){
r[n + s] = new a(0, I[0] & 0xffff);
}
return A;
}
s = 0;
l = 0;
for(c = 1, b = 2; c <= t; ++c, b <<= 1){
for(; C[c] > 0; --C[c]){
h = new a(c & 0xff, I[l++] & 0xffff);
v(r, n + s, b, y, h);
s = f(s, c);
}
}
_ = A - 1;
k = -1;
for(c = t + 1, b = 2; c <= e; ++c, b <<= 1){
for(; C[c] > 0; --C[c]){
if ((s & _) !== k) {
n += y;
p = i(C, c, t);
y = 1 << p;
A += y;
k = s & _;
r[w + k] = new a((p + t) & 0xff, ((n - w) - k) & 0xffff);
}
h = new a((c - t) & 0xff, I[l++] & 0xffff);
v(r, n + (s >> t), b, y, h);
s = f(s, c);
}
}
return A;
};
})
}
]);

1 comment on commit 33a15c8

@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: 33a15c8 Previous: 9d19742 Ratio
es/full/minify/libraries/antd 1873475603 ns/iter (± 63374002) 1822957067 ns/iter (± 55954973) 1.03
es/full/minify/libraries/d3 346927685 ns/iter (± 15305366) 359471705 ns/iter (± 13109250) 0.97
es/full/minify/libraries/echarts 1371406597 ns/iter (± 37750436) 1413394065 ns/iter (± 27024113) 0.97
es/full/minify/libraries/jquery 89409228 ns/iter (± 5485880) 93764982 ns/iter (± 8680940) 0.95
es/full/minify/libraries/lodash 111037904 ns/iter (± 3023239) 120652734 ns/iter (± 11238976) 0.92
es/full/minify/libraries/moment 51782376 ns/iter (± 2958331) 57035687 ns/iter (± 3681542) 0.91
es/full/minify/libraries/react 19831452 ns/iter (± 732467) 20058168 ns/iter (± 602391) 0.99
es/full/minify/libraries/terser 264651108 ns/iter (± 20518848) 265392685 ns/iter (± 6508260) 1.00
es/full/minify/libraries/three 484084598 ns/iter (± 19153531) 474000184 ns/iter (± 10849552) 1.02
es/full/minify/libraries/typescript 3082734561 ns/iter (± 87308767) 3140781219 ns/iter (± 87035491) 0.98
es/full/minify/libraries/victory 718666641 ns/iter (± 7968513) 726256118 ns/iter (± 36310583) 0.99
es/full/minify/libraries/vue 120149194 ns/iter (± 3428212) 123687168 ns/iter (± 9836699) 0.97
es/full/codegen/es3 33573 ns/iter (± 1254) 33148 ns/iter (± 970) 1.01
es/full/codegen/es5 33093 ns/iter (± 870) 33228 ns/iter (± 450) 1.00
es/full/codegen/es2015 33580 ns/iter (± 760) 33430 ns/iter (± 840) 1.00
es/full/codegen/es2016 33608 ns/iter (± 272) 33603 ns/iter (± 697) 1.00
es/full/codegen/es2017 33579 ns/iter (± 928) 33608 ns/iter (± 857) 1.00
es/full/codegen/es2018 33626 ns/iter (± 753) 33581 ns/iter (± 357) 1.00
es/full/codegen/es2019 33628 ns/iter (± 526) 33553 ns/iter (± 643) 1.00
es/full/codegen/es2020 33614 ns/iter (± 573) 33563 ns/iter (± 540) 1.00
es/full/all/es3 191361207 ns/iter (± 14237446) 193523392 ns/iter (± 52510626) 0.99
es/full/all/es5 179943784 ns/iter (± 5810705) 180405722 ns/iter (± 8540344) 1.00
es/full/all/es2015 145672742 ns/iter (± 5780576) 146401042 ns/iter (± 6509400) 1.00
es/full/all/es2016 145107295 ns/iter (± 7358182) 147112450 ns/iter (± 4513437) 0.99
es/full/all/es2017 143930326 ns/iter (± 15852448) 144932375 ns/iter (± 5446718) 0.99
es/full/all/es2018 141322246 ns/iter (± 6905301) 143384371 ns/iter (± 5308220) 0.99
es/full/all/es2019 141800690 ns/iter (± 9775953) 154663004 ns/iter (± 228962874) 0.92
es/full/all/es2020 139294282 ns/iter (± 7770783) 143215345 ns/iter (± 13494817) 0.97
es/full/parser 719997 ns/iter (± 32347) 736023 ns/iter (± 25938) 0.98
es/full/base/fixer 25613 ns/iter (± 507) 25640 ns/iter (± 789) 1.00
es/full/base/resolver_and_hygiene 93124 ns/iter (± 2312) 93186 ns/iter (± 4646) 1.00
serialization of ast node 213 ns/iter (± 3) 214 ns/iter (± 7) 1.00
serialization of serde 217 ns/iter (± 7) 226 ns/iter (± 2) 0.96

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

Please sign in to comment.