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

v20.15.0 proposal #53486

Merged
merged 96 commits into from
Jun 20, 2024
Merged
Changes from 1 commit
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
cd1415c
Revert "crypto: make timingSafeEqual faster for Uint8Array"
tniessen Jun 8, 2024
d02907e
src: remove misplaced windows code under posix guard in node.cc
thisalihassan Apr 15, 2024
6ea72a5
doc: add test_runner to subsystem
rluvaton May 1, 2024
56e19e3
test: drop test-crypto-timing-safe-equal-benchmarks
RafaelGSS May 1, 2024
9587ae9
doc: simplify copy-pasting of `branch-diff` commands
aduh95 May 2, 2024
5161d95
zlib: expose zlib.crc32()
joyeecheung May 2, 2024
739adf9
watch: fix arguments parsing
MoLow May 2, 2024
a5f3dd1
string_decoder: throw an error when writing a too long buffer
kylo5aby Mar 26, 2024
cf817e1
test_runner: preserve hook promise when executed twice
MoLow May 4, 2024
918962d
build: make simdjson a public dep in GN build
zcbenz May 5, 2024
d7eba50
util: improve `isInsideNodeModules`
Uzlopak Mar 21, 2024
8fc52b3
src: fix test local edge case
ShogunPanda Apr 26, 2024
978ee0a
src: only apply fix in main thread
ShogunPanda May 5, 2024
a3b2012
doc: add OpenSSL errors to API docs
j3lamp Jan 27, 2021
0addeb2
test: skip v8-updates/test-linux-perf-logger
targos May 5, 2024
b83fbf8
tools: fix V8 update workflow
aduh95 May 5, 2024
8f8fb91
tools: specify a commit-message for V8 update workflow
aduh95 May 5, 2024
91fadac
doc: make docs more welcoming and descriptive for newcomers
srknzl May 5, 2024
97e0fef
doc: add more definitions to GLOSSARY.md
avivkeller May 5, 2024
5215b6f
build, tools: copy release assets to staging R2 bucket once built
flakey5 May 6, 2024
514f01e
tools: use sccache GitHub action
targos May 6, 2024
1dce5de
test: skip some console tests on dumb terminal
AdamMajer May 6, 2024
16ae2b2
buffer: remove lines setting indexes to integer value
kylo5aby May 6, 2024
2246d4f
test: crypto-rsa-dsa testing for dynamic openssl
mhdawson May 1, 2024
121ea13
process: improve event-loop
Uzlopak May 6, 2024
12512c3
doc: add pimterry to collaborators
pimterry May 7, 2024
01eff58
tools: update `gr2m/create-or-update-pull-request-action`
aduh95 May 7, 2024
1be8232
build: drop base64 dep in GN build
zcbenz May 8, 2024
403a4a7
tools: update lint-md-dependencies to rollup@4.17.2
nodejs-github-bot May 8, 2024
794e450
console: colorize console error and warn
MrJithil Feb 1, 2024
986bfa2
test: add common.expectRequiredModule()
joyeecheung May 7, 2024
5700600
tools: prepare custom rules for ESLint v9
targos May 9, 2024
3df3e37
doc: add names next to release key bash commands
avivkeller May 9, 2024
1ff8f31
watch: enable passthrough ipc in watch mode
znewsham May 9, 2024
2dcbf18
src: avoid unused variable 'error' warning
targos May 10, 2024
dce0300
tools: support != in test status files
joyeecheung Apr 29, 2024
e98c305
tools: support max_virtual_memory test configuration
joyeecheung Apr 29, 2024
9d485b4
tools: fix get_asan_state() in tools/test.py
joyeecheung May 2, 2024
0830b31
tools: fix doc update action
marco-ippolito May 10, 2024
1e429d1
doc: exclude commits with baking-for-lts
marco-ippolito May 10, 2024
6001b16
test: reduce memory usage of test-worker-stdio
AdamMajer May 10, 2024
ae5d47d
doc: watermark string behavior
benjamingr May 10, 2024
4bf3d44
doc: update fs read documentation for clarity
mertcanaltin May 10, 2024
48c15d0
build: remove deprecated calls for argument groups
VoltrexKeyva May 11, 2024
311bdc6
test: add http agent to `executionAsyncResource`
psj-tar-gz Aug 29, 2020
b162aea
src: fix typo Unabled -> Unable
SimonSiefke May 11, 2024
8d628c3
buffer: use size_t instead of uint32_t to avoid segmentation fault
Xstoudi May 11, 2024
585f2a2
doc: update `fs.realpath` documentation
sinkhaha May 11, 2024
184cfe5
benchmark: filter non-present deps from `start-cli-version`
AdamMajer May 11, 2024
7d38c2e
fs: keep fs.promises.readFile read until EOF is reached
kylo5aby May 11, 2024
0638274
test: fix DNS cancel tests
szmarczak May 11, 2024
556e9a2
test: move `test-http-server-request-timeouts-mixed` to sequential
sonimadhuri May 11, 2024
3aa3337
doc: fix `dns.lookup` family `0` and `all` descriptions
domdomegg May 11, 2024
086626f
doc: add examples and notes to http server.close et al
mmarchini May 11, 2024
75dd009
events: replace NodeCustomEvent with CustomEvent
F3n67u May 11, 2024
4102244
test: updated for each to for of in test file
lyannel May 11, 2024
8cb1312
inspector: introduce the `--inspect-wait` flag
cola119 May 11, 2024
d5ab1de
meta: move `@anonrig` to TSC regular member
anonrig May 11, 2024
b774544
deps: enable unbundling of simdjson, simdutf, ada
lemire May 11, 2024
f6290bc
tools: add --certify-safe to nci-ci
mcollina May 12, 2024
74753ed
events: add stop propagation flag to `Event.stopImmediatePropagation`
mikemadest May 12, 2024
0be8123
test: improve coverage of lib/readline.js
pd4d10 May 12, 2024
af27225
doc: add example for `execFileSync` method and ref to stdio
evanshortiss May 12, 2024
4ae4f7e
watch: allow listening for grouped changes
matthieusieben May 12, 2024
eceac78
repl: fix disruptive autocomplete without inspector
Linkgoron May 12, 2024
d08c9a6
test: test pipeline `end` on transform streams
aloisklink Jul 30, 2023
e62c6e2
doc: document pipeline with `end` option
aloisklink Jul 30, 2023
9512839
src: allow preventing debug signal handler start
codebytere May 12, 2024
800b6f6
test: replace `forEach()` in `test-stream-pipe-unpipe-stream`
DevPres May 12, 2024
7603a51
util: fix `%s` format behavior with `Symbol.toPrimitive`
Mar 18, 2024
be309bd
doc: mention push.followTags config
RafaelGSS May 12, 2024
af29120
stream: use `ByteLengthQueuingStrategy` when not in `objectMode`
CGQAQ May 12, 2024
cc74bf7
test: fix broken env fuzzer by initializing process
AdamKorcz May 12, 2024
5fb829b
test: add fuzzer for `ClientHelloParser`
AdamKorcz May 12, 2024
7dda156
test: add fuzzer for native/js string conversion
AdamKorcz Dec 11, 2023
954d2ad
cluster: replace `forEach` with `for-of` loop
jerome-benoit May 12, 2024
033f985
src: use `S_ISDIR` to check if the file is a directory
theanarkh May 12, 2024
972eafd
events: update MaxListenersExceededWarning message log
sinkhaha May 12, 2024
3a1d17a
doc: mention quicker way to build docs
crawford May 12, 2024
1d01325
test: verify request payload is uploaded consistently
awwright May 12, 2024
0fb7c18
crypto: fix duplicated switch-case return values
0o001 May 12, 2024
0513e07
test: use `for-of` instead of `forEach`
gibbyfree May 12, 2024
8b3e83b
buffer: even faster atob
lemire May 12, 2024
227093b
assert: add deep equal check for more Error type
kylo5aby May 12, 2024
0c5e589
test, crypto: use correct object on assert
xicilion May 12, 2024
65fa95d
test: add `Debugger.setInstrumentationBreakpoint` known issue
ulitink May 12, 2024
be9d6f2
url,tools,benchmark: replace deprecated `substr()`
May 12, 2024
89a910b
src: fix Worker termination in `inspector.waitForDebugger`
daeyeon May 13, 2024
2f3f2ff
doc: update hljs with the latest styles
avivkeller May 13, 2024
f82d086
path: fix toNamespacedPath on Windows
huseyinacacak-janea May 13, 2024
0289a02
test_runner: fix watch mode race condition
MoLow May 14, 2024
de54123
tools: fix v8-update workflow
targos May 14, 2024
da4dbfc
doc: remove reference to AUTHORS file
marco-ippolito May 14, 2024
d54aa47
test_runner: support test plans
cjihrig May 9, 2024
473fa73
cli: allow running wasm in limited vmem with --disable-wasm-trap-handler
joyeecheung Apr 19, 2024
0bf200b
2024-06-20, Version 20.15.0 'Iron' (LTS)
marco-ippolito Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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: #52766
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
  • Loading branch information
joyeecheung authored and marco-ippolito committed Jun 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 473fa73857848b1ab822d74a13766b79144352c1
40 changes: 40 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
@@ -559,6 +559,45 @@ const vm = require('node:vm');
vm.measureMemory();
```

### `--disable-wasm-trap-handler`

<!-- YAML
added: REPLACEME
-->

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`

<!-- YAML
@@ -2499,6 +2538,7 @@ one is included in the list below.
* `--diagnostic-dir`
* `--disable-proto`
* `--disable-warning`
* `--disable-wasm-trap-handler`
* `--dns-result-order`
* `--enable-fips`
* `--enable-network-family-autoselection`
5 changes: 5 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
@@ -142,6 +142,11 @@ is `delete`, the property will be removed entirely. If
is `throw`, accesses to the property will throw an exception with the code
`ERR_PROTO_ACCESS`.
.
.It Fl -disable-wasm-trap-handler Ns = Ns Ar mode
Disable trap-handler-based WebAssembly bound checks and fall back to
inline bound checks so that WebAssembly can be run with limited virtual
memory.
.
.It Fl -disallow-code-generation-from-strings
Make built-in language features like `eval` and `new Function` that generate
code from strings throw an exception instead. This does not affect the Node.js
69 changes: 38 additions & 31 deletions src/node.cc
Original file line number Diff line number Diff line change
@@ -420,6 +420,7 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
typedef void (*sigaction_cb)(int signo, siginfo_t* info, void* ucontext);
#endif
#if NODE_USE_V8_WASM_TRAP_HANDLER
static std::atomic<bool> is_wasm_trap_handler_configured{false};
#if defined(_WIN32)
static LONG WINAPI TrapWebAssemblyOrContinue(EXCEPTION_POINTERS* exception) {
if (v8::TryHandleWebAssemblyTrapWindows(exception)) {
@@ -465,15 +466,17 @@ void RegisterSignalHandler(int signal,
bool reset_handler) {
CHECK_NOT_NULL(handler);
#if NODE_USE_V8_WASM_TRAP_HANDLER
if (signal == SIGSEGV) {
// Stash the user-registered handlers for TrapWebAssemblyOrContinue
// to call out to when the signal is not coming from a WASM OOM.
if (signal == SIGSEGV && is_wasm_trap_handler_configured.load()) {
CHECK(previous_sigsegv_action.is_lock_free());
CHECK(!reset_handler);
previous_sigsegv_action.store(handler);
return;
}
// TODO(align behavior between macos and other in next major version)
// TODO(align behavior between macos and other in next major version)
#if defined(__APPLE__)
if (signal == SIGBUS) {
if (signal == SIGBUS && is_wasm_trap_handler_configured.load()) {
CHECK(previous_sigbus_action.is_lock_free());
CHECK(!reset_handler);
previous_sigbus_action.store(handler);
@@ -625,25 +628,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling)) {
RegisterSignalHandler(SIGINT, SignalExit, true);
RegisterSignalHandler(SIGTERM, SignalExit, true);

#if NODE_USE_V8_WASM_TRAP_HANDLER
// Tell V8 to disable emitting WebAssembly
// memory bounds checks. This means that we have
// to catch the SIGSEGV/SIGBUS in TrapWebAssemblyOrContinue
// and pass the signal context to V8.
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = TrapWebAssemblyOrContinue;
sa.sa_flags = SA_SIGINFO;
CHECK_EQ(sigaction(SIGSEGV, &sa, nullptr), 0);
// TODO(align behavior between macos and other in next major version)
#if defined(__APPLE__)
CHECK_EQ(sigaction(SIGBUS, &sa, nullptr), 0);
#endif
}
V8::EnableWebAssemblyTrapHandler(false);
#endif // NODE_USE_V8_WASM_TRAP_HANDLER
}

if (!(flags & ProcessInitializationFlags::kNoAdjustResourceLimits)) {
@@ -670,14 +654,6 @@ static void PlatformInit(ProcessInitializationFlags::Flags flags) {
}
#endif // __POSIX__
#ifdef _WIN32
#ifdef NODE_USE_V8_WASM_TRAP_HANDLER
{
constexpr ULONG first = TRUE;
per_process::old_vectored_exception_handler =
AddVectoredExceptionHandler(first, TrapWebAssemblyOrContinue);
}
V8::EnableWebAssemblyTrapHandler(false);
#endif // NODE_USE_V8_WASM_TRAP_HANDLER
if (!(flags & ProcessInitializationFlags::kNoStdioInitialization)) {
for (int fd = 0; fd <= 2; ++fd) {
auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
@@ -1207,6 +1183,37 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
cppgc::InitializeProcess(allocator);
}

#if NODE_USE_V8_WASM_TRAP_HANDLER
bool use_wasm_trap_handler =
!per_process::cli_options->disable_wasm_trap_handler;
if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling) &&
use_wasm_trap_handler) {
#if defined(_WIN32)
constexpr ULONG first = TRUE;
per_process::old_vectored_exception_handler =
AddVectoredExceptionHandler(first, TrapWebAssemblyOrContinue);
#else
// Tell V8 to disable emitting WebAssembly
// memory bounds checks. This means that we have
// to catch the SIGSEGV/SIGBUS in TrapWebAssemblyOrContinue
// and pass the signal context to V8.
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = TrapWebAssemblyOrContinue;
sa.sa_flags = SA_SIGINFO;
CHECK_EQ(sigaction(SIGSEGV, &sa, nullptr), 0);
// TODO(align behavior between macos and other in next major version)
#if defined(__APPLE__)
CHECK_EQ(sigaction(SIGBUS, &sa, nullptr), 0);
#endif
}
#endif // defined(_WIN32)
is_wasm_trap_handler_configured.store(true);
V8::EnableWebAssemblyTrapHandler(false);
}
#endif // NODE_USE_V8_WASM_TRAP_HANDLER

performance::performance_v8_start = PERFORMANCE_NOW();
per_process::v8_initialized = true;

@@ -1236,7 +1243,7 @@ void TearDownOncePerProcess() {
}

#if NODE_USE_V8_WASM_TRAP_HANDLER && defined(_WIN32)
if (!(flags & ProcessInitializationFlags::kNoDefaultSignalHandling)) {
if (is_wasm_trap_handler_configured.load()) {
RemoveVectoredExceptionHandler(per_process::old_vectored_exception_handler);
}
#endif
8 changes: 8 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
@@ -1071,6 +1071,14 @@ PerProcessOptionsParser::PerProcessOptionsParser(
"Generate a blob that can be embedded into the single executable "
"application",
&PerProcessOptions::experimental_sea_config);

AddOption(
"--disable-wasm-trap-handler",
"Disable trap-handler-based WebAssembly bound checks. V8 will insert "
"inline bound checks when compiling WebAssembly which may slow down "
"performance.",
&PerProcessOptions::disable_wasm_trap_handler,
kAllowedInEnvvar);
}

inline std::string RemoveBrackets(const std::string& host) {
2 changes: 2 additions & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
@@ -310,6 +310,8 @@ class PerProcessOptions : public Options {
bool openssl_shared_config = false;
#endif

bool disable_wasm_trap_handler = false;

// Per-process because reports can be triggered outside a known V8 context.
bool report_on_fatalerror = false;
bool report_compact = false;
12 changes: 12 additions & 0 deletions test/testpy/__init__.py
Original file line number Diff line number Diff line change
@@ -167,3 +167,15 @@ def ListTests(self, current_path, path, arch, mode):
for tst in result:
tst.disable_core_files = True
return result

class WasmAllocationTestConfiguration(SimpleTestConfiguration):
def __init__(self, context, root, section, additional=None):
super(WasmAllocationTestConfiguration, self).__init__(context, root, section,
additional)

def ListTests(self, current_path, path, arch, mode):
result = super(WasmAllocationTestConfiguration, self).ListTests(
current_path, path, arch, mode)
for tst in result:
tst.max_virtual_memory = 5 * 1024 * 1024 * 1024 # 5GB
return result
7 changes: 7 additions & 0 deletions test/wasm-allocation/test-wasm-allocation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Flags: --disable-wasm-trap-handler
// Test that with limited virtual memory space, --disable-wasm-trap-handler
// allows WASM to at least run with inline bound checks.
'use strict';

require('../common');
new WebAssembly.Memory({ initial: 10, maximum: 100 });
6 changes: 6 additions & 0 deletions test/wasm-allocation/testcfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import testpy

def GetConfiguration(context, root):
return testpy.WasmAllocationTestConfiguration(context, root, 'wasm-allocation')
10 changes: 10 additions & 0 deletions test/wasm-allocation/wasm-allocation.status
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix wasm-allocation

# To mark a test as flaky, list the test name in the appropriate section
# below, without ".js", followed by ": PASS,FLAKY". Example:
# sample-test : PASS,FLAKY

[true] # This section applies to all platforms

[$system!=linux || $asan==on]
test-wasm-allocation: SKIP