From 986d9c047c5f285e50d90b48ca5ca842adeb93e4 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sat, 2 Dec 2023 07:20:30 -0800 Subject: [PATCH] Increase node stack size of 8Mb when running js_optimizer On windows the default stack size is still limited to 1MB in older versions of node. See https://github.com/nodejs/node/pull/43632 which made it into v19.0.0. Fixes: #17897 --- site/source/docs/getting_started/FAQ.rst | 8 ++++---- tools/building.py | 2 +- tools/js_optimizer.py | 19 ++++++++++++++----- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/site/source/docs/getting_started/FAQ.rst b/site/source/docs/getting_started/FAQ.rst index d1f51dca62ee..5da693c1a4e5 100644 --- a/site/source/docs/getting_started/FAQ.rst +++ b/site/source/docs/getting_started/FAQ.rst @@ -654,10 +654,10 @@ Why do I get a stack size error when optimizing: ``RangeError: Maximum call stac You may need to increase the stack size for :term:`node.js`. -On Linux and Mac macOS, you can just do ``NODE_JS = ['node', -'--stack_size=8192']`` in the :ref:`compiler-configuration-file`. On Windows, -you will also need ``--max-stack-size=8192``, and also run ``editbin -/stack:33554432 node.exe``. +On Linux and Mac macOS, you can just do ``NODE_JS = ['/path/to/node', +'--stack_size=8192']`` in the :ref:`compiler-configuration-file`. On Windows +(for node versions older than v19), you will also need +``--max-stack-size=8192``, and also run ``editbin /stack:33554432 node.exe``. How do I pass int64_t and uint64_t values from js into Wasm functions? diff --git a/tools/building.py b/tools/building.py index 0ae76bddf78e..8f49997522f0 100644 --- a/tools/building.py +++ b/tools/building.py @@ -342,7 +342,7 @@ def opt_level_to_str(opt_level, shrink_level=0): def js_optimizer(filename, passes): from . import js_optimizer try: - return js_optimizer.run_on_js(filename, passes) + return js_optimizer.run_on_file(filename, passes) except subprocess.CalledProcessError as e: exit_with_error("'%s' failed (%d)", ' '.join(e.cmd), e.returncode) diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py index 6b8741059d9a..b532ec70fe2c 100755 --- a/tools/js_optimizer.py +++ b/tools/js_optimizer.py @@ -37,6 +37,15 @@ import_sig = re.compile(r'(var|const) ([_\w$]+ *=[^;]+);') +def get_acorn_cmd(): + node = config.NODE_JS + if not any('--stack-size' in arg for arg in node): + # Use an 8Mb stack (rather than the ~1Mb default) when running the + # js optimizer since larger inputs can cause terser to use a lot of stack. + node.append('--stack-size=8192') + return node + [ACORN_OPTIMIZER] + + def split_funcs(js): # split properly even if there are no newlines, # which is important for deterministic builds (as which functions @@ -88,7 +97,7 @@ def minify_shell(self, shell, minify_whitespace): f.write('\n') f.write('// EXTRA_INFO:' + json.dumps(self.serialize())) - cmd = config.NODE_JS + [ACORN_OPTIMIZER, temp_file, 'minifyGlobals'] + cmd = get_acorn_cmd() + [temp_file, 'minifyGlobals'] if minify_whitespace: cmd.append('minifyWhitespace') output = shared.run_process(cmd, stdout=subprocess.PIPE).stdout @@ -139,8 +148,8 @@ def chunkify(funcs, chunk_size): return [''.join(func[1] for func in chunk) for chunk in chunks] # remove function names -@ToolchainProfiler.profile_block('js_optimizer.run_on_js') -def run_on_js(filename, passes, extra_info=None): +@ToolchainProfiler.profile_block('js_optimizer.run_on_file') +def run_on_file(filename, passes, extra_info=None): with ToolchainProfiler.profile_block('js_optimizer.split_markers'): if not isinstance(passes, list): passes = [passes] @@ -261,7 +270,7 @@ def write_chunk(chunk, i): filenames = [write_chunk(chunk, i) for i, chunk in enumerate(chunks)] with ToolchainProfiler.profile_block('run_optimizer'): - commands = [config.NODE_JS + [ACORN_OPTIMIZER, f] + passes for f in filenames] + commands = [get_acorn_cmd() + [f] + passes for f in filenames] filenames = shared.run_multiple_processes(commands, route_stdout_to_temp_files_suffix='js_opt.jo.js') with ToolchainProfiler.profile_block('split_closure_cleanup'): @@ -348,7 +357,7 @@ def main(): sys.argv = sys.argv[:-1] else: extra_info = None - out = run_on_js(sys.argv[1], sys.argv[2:], extra_info=extra_info) + out = run_on_file(sys.argv[1], sys.argv[2:], extra_info=extra_info) shutil.copyfile(out, sys.argv[1] + '.jsopt.js') return 0