workaround v8 performance quirks (#5207)

This commit is contained in:
Alex Lam S.L
2021-12-08 05:40:47 +00:00
committed by GitHub
parent 8f39491e96
commit bc27966a19
4 changed files with 38 additions and 31 deletions

View File

@@ -10,7 +10,7 @@ var info = require("../package.json");
var path = require("path");
var UglifyJS = require("../tools/node");
var skip_keys = [ "cname", "fixed", "inlined", "length_read", "parent_scope", "scope" ];
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
var files = {};

View File

@@ -301,7 +301,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
},
}, AST_Statement);
var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_scope variables", {
var AST_BlockScope = DEFNODE("BlockScope", "_var_names enclosed functions make_def parent_scope variables", {
$documentation: "Base class for all statements introducing a lexical scope",
$propdoc: {
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
@@ -532,7 +532,7 @@ var AST_With = DEFNODE("With", "expression", {
/* -----[ scope and functions ]----- */
var AST_Scope = DEFNODE("Scope", "uses_eval uses_with", {
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
$documentation: "Base class for all statements introducing a lexical scope",
$propdoc: {
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
@@ -591,7 +591,7 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
}
}, AST_Scope);
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
$documentation: "Base class for functions",
$propdoc: {
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
@@ -1795,7 +1795,7 @@ var AST_SymbolVar = DEFNODE("SymbolVar", null, {
$documentation: "Symbol defining a variable",
}, AST_SymbolDeclaration);
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", "unused", {
$documentation: "Symbol naming a function argument",
}, AST_SymbolVar);

View File

@@ -531,6 +531,11 @@ Compressor.prototype.compress = function(node) {
});
}
function safe_to_visit(tw, fn) {
var marker = fn.safe_ids;
return marker === undefined || marker === tw.safe_ids;
}
function walk_fn_def(tw, fn) {
var was_scanning = tw.fn_scanning;
tw.fn_scanning = fn;
@@ -545,14 +550,14 @@ Compressor.prototype.compress = function(node) {
d.single_use = false;
var fixed = d.fixed;
if (typeof fixed == "function") fixed = fixed();
if (fixed instanceof AST_Lambda && HOP(fixed, "safe_ids")) return;
if (fixed instanceof AST_Lambda && fixed.safe_ids !== undefined) return;
d.fixed = false;
});
}
function mark_fn_def(tw, def, fn) {
if (!HOP(fn, "safe_ids")) return;
var marker = fn.safe_ids;
if (marker === undefined) return;
if (marker === false) return;
if (fn.parent_scope.resolve().may_call_this === return_true) {
if (member(fn, tw.fn_visited)) revisit_fn_def(tw, fn);
@@ -587,10 +592,10 @@ Compressor.prototype.compress = function(node) {
walk_fn_def(tw, fn);
});
fn_defs.forEach(function(fn) {
delete fn.safe_ids;
fn.safe_ids = undefined;
});
delete scope.fn_defs;
delete scope.may_call_this;
scope.fn_defs = undefined;
scope.may_call_this = undefined;
}
function push(tw) {
@@ -621,7 +626,7 @@ Compressor.prototype.compress = function(node) {
if (def.global && def.name == "arguments") return false;
tw.loop_ids[def.id] = null;
def.fixed = make_node(AST_Undefined, def.orig[0]);
if (in_order) delete def.safe_ids;
if (in_order) def.safe_ids = undefined;
return true;
}
return !safe.assign || safe.assign === tw.safe_ids;
@@ -643,7 +648,7 @@ Compressor.prototype.compress = function(node) {
var safe = tw.safe_ids[def.id];
if (def.safe_ids) {
def.safe_ids[def.id] = false;
delete def.safe_ids;
def.safe_ids = undefined;
return def.fixed === null || HOP(tw.safe_ids, def.id) && !safe.read;
}
if (!HOP(tw.safe_ids, def.id)) {
@@ -1206,7 +1211,7 @@ Compressor.prototype.compress = function(node) {
});
def(AST_Lambda, function(tw, descend, compressor) {
var fn = this;
if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
if (!safe_to_visit(tw, fn)) return true;
if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
@@ -1221,7 +1226,7 @@ Compressor.prototype.compress = function(node) {
var def = fn.name.definition();
var parent = tw.parent();
if (parent instanceof AST_ExportDeclaration || parent instanceof AST_ExportDefault) def.single_use = false;
if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
if (!safe_to_visit(tw, fn)) return true;
if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
@@ -1469,8 +1474,8 @@ Compressor.prototype.compress = function(node) {
function reset_flags(node) {
node._squeezed = false;
node._optimized = false;
delete node.fixed;
if (node instanceof AST_Scope) delete node._var_names;
if (node instanceof AST_BlockScope) node._var_names = undefined;
if (node instanceof AST_SymbolRef) node.fixed = undefined;
}
AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
@@ -6592,7 +6597,7 @@ Compressor.prototype.compress = function(node) {
argnames.pop();
} else if (i > default_length) {
log(sym.name, "Dropping unused default argument assignment {name}");
sym.name.__unused = true;
sym.name.unused = true;
argnames[i] = sym.name;
} else {
log(sym.name, "Dropping unused default argument value {name}");
@@ -6603,12 +6608,12 @@ Compressor.prototype.compress = function(node) {
var def = sym.definition();
if (def.id in in_use_ids) {
trim = false;
if (indexOf_assign(def, sym) < 0) sym.__unused = null;
if (indexOf_assign(def, sym) < 0) sym.unused = null;
} else if (trim) {
log(sym, "Dropping unused function argument {name}");
argnames.pop();
} else {
sym.__unused = true;
sym.unused = true;
}
}
fns_with_marked_args.push(node);
@@ -7162,7 +7167,7 @@ Compressor.prototype.compress = function(node) {
var value = node.value.drop_side_effect_free(compressor);
if (!value) return null;
log(node.name, "Side effects in default value of unused variable {name}");
node.name.__unused = null;
node.name.unused = null;
node.value = value;
}
return node;
@@ -7419,7 +7424,7 @@ Compressor.prototype.compress = function(node) {
}
return make_node(AST_DestructuredObject, node, { properties: [] });
}
node.__unused = null;
node.unused = null;
return node;
}
}
@@ -9247,7 +9252,7 @@ Compressor.prototype.compress = function(node) {
if (argname instanceof AST_DestructuredObject) {
return argname.properties.length == 0 && !argname.rest && arg && !arg.may_throw_on_access(compressor);
}
return argname.__unused;
return argname.unused;
} : return_false;
var side_effects = [];
for (var i = 0; i < args.length; i++) {
@@ -9255,7 +9260,7 @@ Compressor.prototype.compress = function(node) {
if (drop_defaults && argname instanceof AST_DefaultValue && args[i].is_defined(compressor)) {
argnames[i] = argname = argname.name;
}
if (!argname || "__unused" in argname) {
if (!argname || argname.unused !== undefined) {
var node = args[i].drop_side_effect_free(compressor);
if (drop_fargs(argname)) {
if (argname) argnames.splice(i, 1);
@@ -9969,7 +9974,7 @@ Compressor.prototype.compress = function(node) {
var abort = false;
fn.each_argname(function(arg) {
if (abort) return;
if (arg.__unused) return;
if (arg.unused) return;
if (!safe_to_inject || var_exists(defined, arg.name)) return abort = true;
arg_used.set(arg.name, true);
if (in_loop) in_loop.push(arg.definition());
@@ -10080,12 +10085,12 @@ Compressor.prototype.compress = function(node) {
name = argname;
}
var value = self.args[i];
if (name.__unused || scope.var_names().has(name.name)) {
if (name.unused || scope.var_names().has(name.name)) {
if (value) expressions.push(value);
} else {
var symbol = make_node(AST_SymbolVar, name, name);
name.definition().orig.push(symbol);
if ("__unused" in name) {
if (name.unused !== undefined) {
append_var(decls, expressions, symbol);
if (value) expressions.push(value);
} else {
@@ -10098,7 +10103,7 @@ Compressor.prototype.compress = function(node) {
expressions.reverse();
for (i = default_args.length; --i >= 0;) {
var node = default_args[i];
if ("__unused" in node.name) {
if (node.name.unused !== undefined) {
expressions.push(node.value);
} else {
var sym = make_node(AST_SymbolRef, node.name, node.name);
@@ -10117,7 +10122,7 @@ Compressor.prototype.compress = function(node) {
operator: "=",
left: make_node(AST_DestructuredArray, self, {
elements: fn.argnames.map(function(argname) {
if (argname.__unused) return make_node(AST_Hole, argname);
if (argname.unused) return make_node(AST_Hole, argname);
return argname.convert_symbol(AST_SymbolRef, process);
}),
rest: fn.rest && fn.rest.convert_symbol(AST_SymbolRef, process),
@@ -12307,7 +12312,7 @@ Compressor.prototype.compress = function(node) {
if (assigned) def.reassigned--;
var sym = make_node(AST_SymbolRef, self, argname);
sym.reference();
delete argname.__unused;
argname.unused = undefined;
return sym;
}
}

View File

@@ -45,6 +45,7 @@
function SymbolDef(id, scope, orig, init) {
this._bits = 0;
this.defun = undefined;
this.eliminated = 0;
this.id = id;
this.init = init;
@@ -53,6 +54,7 @@ function SymbolDef(id, scope, orig, init) {
this.orig = [ orig ];
this.references = [];
this.replaced = 0;
this.safe_ids = undefined;
this.scope = scope;
}
@@ -370,7 +372,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
if (node instanceof AST_SymbolLambda) {
var def = node.thedef;
if (!redefine(node, node.scope.parent_scope.resolve())) {
delete def.defun;
def.defun = undefined;
} else if (typeof node.thedef.init !== "undefined") {
node.thedef.init = false;
} else if (def.init) {
@@ -472,7 +474,7 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
for (var s = this.scope; s; s = s.parent_scope) {
push_uniq(s.enclosed, def);
if (!options) {
delete s._var_names;
s._var_names = undefined;
} else if (options.keep_fnames) {
s.functions.each(function(d) {
push_uniq(def.scope.enclosed, d);