Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: allow running wasm in limited vmemory with --disable-wasm-trap-handler #52766

Closed
wants to merge 5 commits into from

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Apr 30, 2024

tools: support != in test status files

tools: support max_virtual_memory test configuration

tools: fix get_asan_state() in tools/test.py

The output of node -p process.config.variables.asan includes
a newline character so it's never exactly "1", which means
asan is always "off" for the status files. This fixes the
detection by stripping whitespaces from the output.

cli: allow running wasm in limited vmemory 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.

$ 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.

Background: https://docs.google.com/document/u/3/d/1PM4Zqmlt8ac5O8UNQfY7fOsem-6MhbsB-vjFI-9XK6w/edit#heading=h.diogznvalour

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/startup

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Apr 30, 2024
@joyeecheung
Copy link
Member Author

A more real world example of what this PR fixes:

$ ulimit -v 5000000
$ mkdir test-webpack
$ npm install --save webpack
$ node ./node_modules/.bin/webpack

[webpack-cli] RangeError: WebAssembly.Instance(): Out of memory: Cannot allocate Wasm memory for new instance
    at create (/home/ubuntu/test-webpack/node_modules/webpack/lib/util/hash/wasm-hash.js:155:4)
    at module.exports (/home/ubuntu/test-webpack/node_modules/webpack/lib/util/createHash.js:176:6)
    at /home/ubuntu/test-webpack/node_modules/webpack/lib/DefinePlugin.js:351:22
    at _next31 (eval at create (/home/ubuntu/test-webpack/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:42:1)
    at _next9 (eval at create (/home/ubuntu/test-webpack/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:97:1)
    at Hook.eval [as call] (eval at create (/home/ubuntu/test-webpack/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:119:1)
    at Hook.CALL_DELEGATE [as _call] (/home/ubuntu/test-webpack/node_modules/tapable/lib/Hook.js:14:14)
    at Compiler.newCompilation (/home/ubuntu/test-webpack/node_modules/webpack/lib/Compiler.js:1255:26)
    at /home/ubuntu/test-webpack/node_modules/webpack/lib/Compiler.js:1299:29
    at Hook.eval [as callAsync] (eval at create (/home/ubuntu/test-webpack/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)

(This happens because Webpack uses a wasm implementation of md4)

@nodejs-github-bot
Copy link
Collaborator

doc/api/cli.md Outdated Show resolved Hide resolved
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

The output of `node -p process.config.variables.asan` includes
a newline character so it's never exactly "1", which means
asan is always "off" for the status files. This fixes the
detection by stripping whitespaces from the output.
…andler

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.
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@joyeecheung
Copy link
Member Author

cc @nodejs/cpp-reviewers @nodejs/build

@joyeecheung
Copy link
Member Author

joyeecheung commented May 7, 2024

Added YAML and manpage entries, thanks for the reminder.

As for stability index, it seems unnecessary for a flag that serves as an escape hatch in a special environment - we don't usually add stability index to this kind of flags, either, and there is no clear criteria when this should be considered stable or how it could change over time - I expect the flag to just keep working as it is. If we must assign an index, I think it's fine to just mark it stable. But I'd prefer to just leave it out like most other optional CLI flags.

Copy link
Member

@RafaelGSS RafaelGSS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label May 9, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label May 9, 2024
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

joyeecheung added a commit that referenced this pull request May 10, 2024
joyeecheung added a commit that referenced this pull request May 10, 2024
joyeecheung added a commit that referenced this pull request May 10, 2024
The output of `node -p process.config.variables.asan` includes
a newline character so it's never exactly "1", which means
asan is always "off" for the status files. This fixes the
detection by stripping whitespaces from the output.

PR-URL: #52766
Reviewed-By: Rafael Gonzaga <[email protected]>
joyeecheung added a commit that referenced this pull request May 10, 2024
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: #52766
Reviewed-By: Rafael Gonzaga <[email protected]>
@joyeecheung
Copy link
Member Author

Landed in e03529e...77fabfb

targos pushed a commit that referenced this pull request May 11, 2024
targos pushed a commit that referenced this pull request May 11, 2024
targos pushed a commit that referenced this pull request May 11, 2024
The output of `node -p process.config.variables.asan` includes
a newline character so it's never exactly "1", which means
asan is always "off" for the status files. This fixes the
detection by stripping whitespaces from the output.

PR-URL: #52766
Reviewed-By: Rafael Gonzaga <[email protected]>
targos pushed a commit that referenced this pull request May 11, 2024
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: #52766
Reviewed-By: Rafael Gonzaga <[email protected]>
@targos targos added the semver-minor PRs that contain new features and should be released in the next minor version. label May 13, 2024
@targos
Copy link
Member

targos commented May 13, 2024

This PR adds a feature so it should be labeled semver-minor PRs that contain new features and should be released in the next minor version. (this is not supposed to be done by releasers).

targos added a commit that referenced this pull request May 13, 2024
Notable changes:

cli:
  * (SEMVER-MINOR) allow running wasm in limited vmem with
    --disable-wasm-trap-handler (Joyee Cheung)
    #52766
doc:
  * add pimterry to collaborators (Tim Perry)
    #52874
fs:
  * (SEMVER-MINOR) allow 'withFileTypes' to be used with globs
    (Aviv Keller) #52837
inspector:
  * (SEMVER-MINOR) introduce the `--inspect-wait` flag (Kohei Ueno)
    #52734
lib,src:
  * remove --experimental-policy (Rafael Gonzaga)
    #52583
perf_hooks:
  * (SEMVER-MINOR) add `deliveryType` and `responseStatus` fields
    (Matthew Aitken) #51589
test_runner:
  * (SEMVER-MINOR) support test plans (Colin Ihrig)
    #52860
zlib:
  * (SEMVER-MINOR) expose zlib.crc32() (Joyee Cheung)
    #52692

PR-URL: #52971
targos added a commit that referenced this pull request May 15, 2024
Notable changes:

cli:
  * (SEMVER-MINOR) allow running wasm in limited vmem with
    --disable-wasm-trap-handler (Joyee Cheung)
    #52766
doc:
  * add pimterry to collaborators (Tim Perry)
    #52874
fs:
  * (SEMVER-MINOR) allow 'withFileTypes' to be used with globs
    (Aviv Keller) #52837
inspector:
  * (SEMVER-MINOR) introduce the `--inspect-wait` flag (Kohei Ueno)
    #52734
lib,src:
  * remove --experimental-policy (Rafael Gonzaga)
    #52583
perf_hooks:
  * (SEMVER-MINOR) add `deliveryType` and `responseStatus` fields
    (Matthew Aitken) #51589
test_runner:
  * (SEMVER-MINOR) support test plans (Colin Ihrig)
    #52860
zlib:
  * (SEMVER-MINOR) expose zlib.crc32() (Joyee Cheung)
    #52692

PR-URL: #52971
targos added a commit that referenced this pull request May 15, 2024
Notable changes:

cli:
  * (SEMVER-MINOR) allow running wasm in limited vmem with
    --disable-wasm-trap-handler (Joyee Cheung)
    #52766
doc:
  * add pimterry to collaborators (Tim Perry)
    #52874
fs:
  * (SEMVER-MINOR) allow 'withFileTypes' to be used with globs
    (Aviv Keller) #52837
inspector:
  * (SEMVER-MINOR) introduce the `--inspect-wait` flag (Kohei Ueno)
    #52734
lib,src:
  * remove --experimental-policy (Rafael Gonzaga)
    #52583
perf_hooks:
  * (SEMVER-MINOR) add `deliveryType` and `responseStatus` fields
    (Matthew Aitken) #51589
test_runner:
  * (SEMVER-MINOR) support test plans (Colin Ihrig)
    #52860
zlib:
  * (SEMVER-MINOR) expose zlib.crc32() (Joyee Cheung)
    #52692

PR-URL: #52971
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants