Skip to content

Commit

Permalink
garbage collect the AST while outputting code (#1189)
Browse files Browse the repository at this point in the history
* garbage collect the AST while outputting code

* go through all the scopes before including source map sources in the source map
  • Loading branch information
fabiosantoscode committed May 1, 2022
1 parent 423b304 commit 878a631
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 16 deletions.
12 changes: 1 addition & 11 deletions lib/ast.js
Expand Up @@ -552,11 +552,10 @@ var AST_With = DEFNODE("With", "expression", function AST_With(props) {

var AST_Scope = DEFNODE(
"Scope",
"variables functions uses_with uses_eval parent_scope enclosed cname",
"variables uses_with uses_eval parent_scope enclosed cname",
function AST_Scope(props) {
if (props) {
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down Expand Up @@ -612,7 +611,6 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) {
if (props) {
this.globals = props.globals;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down Expand Up @@ -694,7 +692,6 @@ var AST_Lambda = DEFNODE(
this.is_generator = props.is_generator;
this.async = props.async;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down Expand Up @@ -774,7 +771,6 @@ var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) {
this.is_generator = props.is_generator;
this.async = props.async;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand All @@ -799,7 +795,6 @@ var AST_Function = DEFNODE("Function", null, function AST_Function(props) {
this.is_generator = props.is_generator;
this.async = props.async;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand All @@ -824,7 +819,6 @@ var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) {
this.is_generator = props.is_generator;
this.async = props.async;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand All @@ -849,7 +843,6 @@ var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) {
this.is_generator = props.is_generator;
this.async = props.async;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down Expand Up @@ -2161,7 +2154,6 @@ var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(p
this.extends = props.extends;
this.properties = props.properties;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down Expand Up @@ -2255,7 +2247,6 @@ var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
this.extends = props.extends;
this.properties = props.properties;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand All @@ -2278,7 +2269,6 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExp
this.extends = props.extends;
this.properties = props.properties;
this.variables = props.variables;
this.functions = props.functions;
this.uses_with = props.uses_with;
this.uses_eval = props.uses_eval;
this.parent_scope = props.parent_scope;
Expand Down
28 changes: 27 additions & 1 deletion lib/minify.js
Expand Up @@ -7,7 +7,7 @@ import {
map_to_object,
HOP,
} from "./utils/index.js";
import { AST_Toplevel, AST_Node } from "./ast.js";
import { AST_Toplevel, AST_Node, walk, AST_Scope } from "./ast.js";
import { parse } from "./parse.js";
import { OutputStream } from "./output.js";
import { Compressor } from "./compress/index.js";
Expand Down Expand Up @@ -194,6 +194,8 @@ async function minify(files, options, _fs_module) {
url: null,
}, true);
}

// -- Parse phase --
if (timings) timings.parse = Date.now();
var toplevel;
if (files instanceof AST_Toplevel) {
Expand Down Expand Up @@ -243,12 +245,16 @@ async function minify(files, options, _fs_module) {
toplevel.figure_out_scope(options.mangle);
toplevel.expand_names(options.mangle);
}

// -- Compress phase --
if (timings) timings.compress = Date.now();
if (options.compress) {
toplevel = new Compressor(options.compress, {
mangle_options: options.mangle
}).compress(toplevel);
}

// -- Mangle phase --
if (timings) timings.scope = Date.now();
if (options.mangle) toplevel.figure_out_scope(options.mangle);
if (timings) timings.mangle = Date.now();
Expand All @@ -261,6 +267,8 @@ async function minify(files, options, _fs_module) {
if (options.mangle && options.mangle.properties) {
toplevel = mangle_properties(toplevel, options.mangle.properties);
}

// Format phase
if (timings) timings.format = Date.now();
var result = {};
if (options.format.ast) {
Expand All @@ -270,6 +278,24 @@ async function minify(files, options, _fs_module) {
result.ast = toplevel.to_mozilla_ast();
}
if (!HOP(options.format, "code") || options.format.code) {
if (!options.format.ast) {
// Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
options.format._destroy_ast = true;

walk(toplevel, node => {
if (node instanceof AST_Scope) {
node.variables = undefined;
node.enclosed = undefined;
node.parent_scope = undefined;
}
if (node.block_scope) {
node.block_scope.variables = undefined;
node.block_scope.enclosed = undefined;
node.parent_scope = undefined;
}
});
}

if (options.sourceMap) {
options.format.source_map = await SourceMap({
file: options.sourceMap.filename,
Expand Down
17 changes: 17 additions & 0 deletions lib/output.js
Expand Up @@ -247,6 +247,8 @@ function OutputStream(options) {
width : 80,
wrap_iife : false,
wrap_func_args : true,

_destroy_ast : false
}, true);

if (options.shorthand === undefined)
Expand Down Expand Up @@ -796,6 +798,18 @@ function OutputStream(options) {
if (OUTPUT.length() > insert) newline_insert = insert;
}

/**
* When output.option("_destroy_ast") is enabled, destroy the function.
* Call this after printing it.
*/
const gc_scope =
options["_destroy_ast"]
? function gc_scope(scope) {
scope.body.length = 0;
scope.argnames.length = 0;
}
: noop;

var stack = [];
return {
get : get,
Expand Down Expand Up @@ -842,6 +856,7 @@ function OutputStream(options) {
with_square : with_square,
add_mapping : add_mapping,
option : function(opt) { return options[opt]; },
gc_scope,
printed_comments: printed_comments,
prepend_comments: readonly ? noop : prepend_comments,
append_comments : readonly || comment_filter === return_false ? noop : append_comments,
Expand Down Expand Up @@ -1358,6 +1373,7 @@ function OutputStream(options) {
});
DEFPRINT(AST_Lambda, function(self, output) {
self._do_print(output);
output.gc_scope(self);
});

DEFPRINT(AST_PrefixedTemplateString, function(self, output) {
Expand Down Expand Up @@ -1437,6 +1453,7 @@ function OutputStream(options) {
print_braced(self, output);
}
if (needs_parens) { output.print(")"); }
output.gc_scope(self);
});

/* -----[ exits ]----- */
Expand Down
8 changes: 4 additions & 4 deletions test/benchmark.js
Expand Up @@ -3,10 +3,10 @@

"use strict";

var createHash = require("crypto").createHash;
var fetch = require("./fetch");
var fork = require("child_process").fork;
var zlib = require("zlib");
import { createHash } from "crypto";
import fetch from "./fetch.cjs";
import { fork } from "child_process";
import zlib from "zlib";
var args = process.argv.slice(2);
if (!args.length) {
args.push("-mc");
Expand Down

0 comments on commit 878a631

Please sign in to comment.