From 473fa73857848b1ab822d74a13766b79144352c1 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 19 Apr 2024 21:35:20 +0200 Subject: [PATCH] cli: allow running wasm in limited vmem with --disable-wasm-trap-handler By default, Node.js enables trap-handler-based WebAssembly bound checks. As a result, V8 does not need to insert inline bound checks int the code compiled from WebAssembly which may speedup WebAssembly execution significantly, but this optimization requires allocating a big virtual memory cage (currently 10GB). If the Node.js process does not have access to a large enough virtual memory address space due to system configurations or hardware limitations, users won't be able to run any WebAssembly that involves allocation in this virtual memory cage and will see an out-of-memory error. ```console $ ulimit -v 5000000 $ node -p "new WebAssembly.Memory({ initial: 10, maximum: 100 });" [eval]:1 new WebAssembly.Memory({ initial: 10, maximum: 100 }); ^ RangeError: WebAssembly.Memory(): could not allocate memory at [eval]:1:1 at runScriptInThisContext (node:internal/vm:209:10) at node:internal/process/execution:118:14 at [eval]-wrapper:6:24 at runScript (node:internal/process/execution:101:62) at evalScript (node:internal/process/execution:136:3) at node:internal/main/eval_string:49:3 ``` `--disable-wasm-trap-handler` disables this optimization so that users can at least run WebAssembly (with a less optimial performance) when the virtual memory address space available to their Node.js process is lower than what the V8 WebAssembly memory cage needs. PR-URL: https://github.com/nodejs/node/pull/52766 Reviewed-By: Rafael Gonzaga --- doc/api/cli.md | 40 ++++++++++++ doc/node.1 | 5 ++ src/node.cc | 69 +++++++++++--------- src/node_options.cc | 8 +++ src/node_options.h | 2 + test/testpy/__init__.py | 12 ++++ test/wasm-allocation/test-wasm-allocation.js | 7 ++ test/wasm-allocation/testcfg.py | 6 ++ test/wasm-allocation/wasm-allocation.status | 10 +++ 9 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 test/wasm-allocation/test-wasm-allocation.js create mode 100644 test/wasm-allocation/testcfg.py create mode 100644 test/wasm-allocation/wasm-allocation.status diff --git a/doc/api/cli.md b/doc/api/cli.md index 2d8dbfdd805f7f..6619d0a322cb3f 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -559,6 +559,45 @@ const vm = require('node:vm'); vm.measureMemory(); ``` +### `--disable-wasm-trap-handler` + + + +By default, Node.js enables trap-handler-based WebAssembly bound +checks. As a result, V8 does not need to insert inline bound checks +int the code compiled from WebAssembly which may speedup WebAssembly +execution significantly, but this optimization requires allocating +a big virtual memory cage (currently 10GB). If the Node.js process +does not have access to a large enough virtual memory address space +due to system configurations or hardware limitations, users won't +be able to run any WebAssembly that involves allocation in this +virtual memory cage and will see an out-of-memory error. + +```console +$ ulimit -v 5000000 +$ node -p "new WebAssembly.Memory({ initial: 10, maximum: 100 });" +[eval]:1 +new WebAssembly.Memory({ initial: 10, maximum: 100 }); +^ + +RangeError: WebAssembly.Memory(): could not allocate memory + at [eval]:1:1 + at runScriptInThisContext (node:internal/vm:209:10) + at node:internal/process/execution:118:14 + at [eval]-wrapper:6:24 + at runScript (node:internal/process/execution:101:62) + at evalScript (node:internal/process/execution:136:3) + at node:internal/main/eval_string:49:3 + +``` + +`--disable-wasm-trap-handler` disables this optimization so that +users can at least run WebAssembly (with less optimal performance) +when the virtual memory address space available to their Node.js +process is lower than what the V8 WebAssembly memory cage needs. + ### `--disable-proto=mode`