Skip to content

Commit

Permalink
Increase node stack size of 8Mb when running js_optimizer
Browse files Browse the repository at this point in the history
On windows the default stack size is still limited to 1MB in older
versions of node.  See nodejs/node#43632 which
made it into v19.0.0.

Fixes: emscripten-core#17897
  • Loading branch information
sbc100 committed Dec 2, 2023
1 parent 38ab7c1 commit 986d9c0
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
8 changes: 4 additions & 4 deletions site/source/docs/getting_started/FAQ.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
2 changes: 1 addition & 1 deletion tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
19 changes: 14 additions & 5 deletions tools/js_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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'):
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 986d9c0

Please sign in to comment.