Skip to content

Commit 2be6a64

Browse files
committed
deps: V8: backport bef0d9c1bc90
Original commit message: [api] Add V8::GetWasmMemoryReservationSizeInBytes() When the system does not have enough virtual memory for the wasm cage, installing the trap handler would cause any code allocating wasm memory to throw. Therefore it's useful for the embedder to know when the system doesn't have enough virtual address space to allocate enough wasm cages and in that case, skip the trap handler installation so that wasm code can at least work (even not at the maximal performance). Node.js previously has a command line option --disable-wasm-trap-handler to fully disable trap-based bound checks, this new API would allow it to adapt automatically while keeping the optimization in the happy path, since it's not always possible for end users to opt-into disabling trap-based bound checks (for example, when a VS Code Server is loaded in a remote server for debugging). Refs: #62132 Refs: microsoft/vscode#251777 Change-Id: I345c076af2b2b47700e5716b49c3133fdf8a0981 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7638233 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/main@{#105702} Refs: v8/v8@bef0d9c Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com>
1 parent c96c3da commit 2be6a64

File tree

6 files changed

+94
-21
lines changed

6 files changed

+94
-21
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.13',
41+
'v8_embedder_string': '-node.14',
4242

4343
##### V8 defaults for Node.js #####
4444

deps/v8/include/v8-initialization.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,35 @@ class V8_EXPORT V8 {
253253
static size_t GetSandboxReservationSizeInBytes();
254254
#endif // V8_ENABLE_SANDBOX
255255

256+
enum class WasmMemoryType {
257+
kMemory32,
258+
kMemory64,
259+
};
260+
261+
/**
262+
* Returns the virtual address space reservation size (in bytes) needed
263+
* for one WebAssembly memory instance of the given capacity.
264+
*
265+
* \param type Whether this is a memory32 or memory64 instance.
266+
* \param byte_capacity The maximum size, in bytes, of the WebAssembly
267+
* memory. Values exceeding the engine's maximum allocatable memory
268+
* size for the given type (determined by max_mem32_pages or
269+
* max_mem64_pages) are clamped.
270+
*
271+
* When trap-based bounds checking is enabled by
272+
* EnableWebAssemblyTrapHandler(), the amount of virtual address space
273+
* that V8 needs to reserve for each WebAssembly memory instance can
274+
* be much bigger than the requested size. If the process does
275+
* not have enough virtual memory available, WebAssembly memory allocation
276+
* would fail. During the initialization of V8, embedders can use this method
277+
* to estimate whether the process has enough virtual memory for their
278+
* usage of WebAssembly, and decide whether to enable the trap handler
279+
* via EnableWebAssemblyTrapHandler(), or to skip it and reduce the amount of
280+
* virtual memory required to keep the application running.
281+
*/
282+
static size_t GetWasmMemoryReservationSizeInBytes(WasmMemoryType type,
283+
size_t byte_capacity);
284+
256285
/**
257286
* Activate trap-based bounds checking for WebAssembly.
258287
*

deps/v8/src/api/api.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
#include "src/wasm/value-type.h"
151151
#include "src/wasm/wasm-engine.h"
152152
#include "src/wasm/wasm-js.h"
153+
#include "src/wasm/wasm-limits.h"
153154
#include "src/wasm/wasm-objects-inl.h"
154155
#include "src/wasm/wasm-result.h"
155156
#include "src/wasm/wasm-serialization.h"
@@ -6294,6 +6295,26 @@ bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
62946295
}
62956296
#endif
62966297

6298+
size_t V8::GetWasmMemoryReservationSizeInBytes(WasmMemoryType type,
6299+
size_t byte_capacity) {
6300+
#if V8_ENABLE_WEBASSEMBLY
6301+
bool is_memory64 = type == WasmMemoryType::kMemory64;
6302+
uint64_t max_byte_capacity =
6303+
is_memory64 ? i::wasm::max_mem64_bytes() : i::wasm::max_mem32_bytes();
6304+
if (byte_capacity > max_byte_capacity) {
6305+
byte_capacity = static_cast<size_t>(max_byte_capacity);
6306+
}
6307+
#if V8_TRAP_HANDLER_SUPPORTED
6308+
if (!is_memory64 || i::v8_flags.wasm_memory64_trap_handling) {
6309+
return i::BackingStore::GetWasmReservationSize(
6310+
/* has_guard_regions */ true, byte_capacity,
6311+
/* is_wasm_memory64 */ is_memory64);
6312+
}
6313+
#endif // V8_TRAP_HANDLER_SUPPORTED
6314+
#endif // V8_ENABLE_WEBASSEMBLY
6315+
return byte_capacity;
6316+
}
6317+
62976318
bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
62986319
#if V8_ENABLE_WEBASSEMBLY
62996320
return i::trap_handler::EnableTrapHandler(use_v8_signal_handler);

deps/v8/src/objects/backing-store.cc

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,25 @@ enum class AllocationStatus {
5151
kOtherFailure // Failed for an unknown reason
5252
};
5353

54-
size_t GetReservationSize(bool has_guard_regions, size_t byte_capacity,
55-
bool is_wasm_memory64) {
54+
base::AddressRegion GetReservedRegion(bool has_guard_regions,
55+
bool is_wasm_memory64, void* buffer_start,
56+
size_t byte_capacity) {
57+
return base::AddressRegion(
58+
reinterpret_cast<Address>(buffer_start),
59+
BackingStore::GetWasmReservationSize(has_guard_regions, byte_capacity,
60+
is_wasm_memory64));
61+
}
62+
63+
void RecordStatus(Isolate* isolate, AllocationStatus status) {
64+
isolate->counters()->wasm_memory_allocation_result()->AddSample(
65+
static_cast<int>(status));
66+
}
67+
68+
} // namespace
69+
70+
size_t BackingStore::GetWasmReservationSize(bool has_guard_regions,
71+
size_t byte_capacity,
72+
bool is_wasm_memory64) {
5673
#if V8_TARGET_ARCH_64_BIT && V8_ENABLE_WEBASSEMBLY
5774
DCHECK_IMPLIES(is_wasm_memory64 && has_guard_regions,
5875
v8_flags.wasm_memory64_trap_handling);
@@ -73,21 +90,6 @@ size_t GetReservationSize(bool has_guard_regions, size_t byte_capacity,
7390
return byte_capacity;
7491
}
7592

76-
base::AddressRegion GetReservedRegion(bool has_guard_regions,
77-
bool is_wasm_memory64, void* buffer_start,
78-
size_t byte_capacity) {
79-
return base::AddressRegion(
80-
reinterpret_cast<Address>(buffer_start),
81-
GetReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64));
82-
}
83-
84-
void RecordStatus(Isolate* isolate, AllocationStatus status) {
85-
isolate->counters()->wasm_memory_allocation_result()->AddSample(
86-
static_cast<int>(status));
87-
}
88-
89-
} // namespace
90-
9193
// The backing store for a Wasm shared memory remembers all the isolates
9294
// with which it has been shared.
9395
struct SharedWasmMemoryData {
@@ -168,7 +170,7 @@ BackingStore::~BackingStore() {
168170

169171
#if V8_ENABLE_WEBASSEMBLY
170172
if (is_wasm_memory()) {
171-
size_t reservation_size = GetReservationSize(
173+
size_t reservation_size = GetWasmReservationSize(
172174
has_guard_regions(), byte_capacity_, is_wasm_memory64());
173175
TRACE_BS(
174176
"BSw:free bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
@@ -324,8 +326,8 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
324326
};
325327

326328
size_t byte_capacity = maximum_pages * page_size;
327-
size_t reservation_size =
328-
GetReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64);
329+
size_t reservation_size = GetWasmReservationSize(
330+
has_guard_regions, byte_capacity, is_wasm_memory64);
329331

330332
//--------------------------------------------------------------------------
331333
// Allocate pages (inaccessible by default).

deps/v8/src/objects/backing-store.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
183183

184184
uint32_t id() const { return id_; }
185185

186+
// Return the size of the reservation needed for a wasm backing store.
187+
static size_t GetWasmReservationSize(bool has_guard_regions,
188+
size_t byte_capacity,
189+
bool is_wasm_memory64);
190+
186191
private:
187192
friend class GlobalBackingStoreRegistry;
188193

deps/v8/test/unittests/api/api-wasm-unittest.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,22 @@ void WasmStreamingMoreFunctionsCanBeSerializedCallback(
122122
streaming->SetMoreFunctionsCanBeSerializedCallback([](CompiledWasmModule) {});
123123
}
124124

125+
TEST_F(ApiWasmTest, GetWasmMemoryReservationSizeInBytes) {
126+
constexpr size_t kCapacity = 64 * 1024; // 64 KiB
127+
size_t reservation = V8::GetWasmMemoryReservationSizeInBytes(
128+
V8::WasmMemoryType::kMemory32, kCapacity);
129+
size_t reservation64 = V8::GetWasmMemoryReservationSizeInBytes(
130+
V8::WasmMemoryType::kMemory64, kCapacity);
131+
132+
#if V8_TRAP_HANDLER_SUPPORTED
133+
EXPECT_GE(reservation, kCapacity);
134+
EXPECT_GE(reservation64, kCapacity);
135+
#else
136+
EXPECT_EQ(reservation, kCapacity);
137+
EXPECT_EQ(reservation64, kCapacity);
138+
#endif // V8_TRAP_HANDLER_SUPPORTED
139+
}
140+
125141
TEST_F(ApiWasmTest, WasmStreamingCallback) {
126142
TestWasmStreaming(WasmStreamingCallbackTestCallbackIsCalled,
127143
Promise::kPending);

0 commit comments

Comments
 (0)