Skip to content

Commit af07938

Browse files
committed
deps: V8: backport 2733a0848301
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 emebdder to know when the system doesn't have enough virtual address space to allocate any wasm cage 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 for this, this new API would allow it to adapt automatically without requiring the use of a command line flag, which is not always under end-user's control (for example, when a VS Code Server is loaded in a remote server for debugging). As a drive by this also makes the trap handlers a bit more robust by making them a no-op of trap handling is not enabled at all. Refs: #52766 Refs: microsoft/vscode#251777 Bug: 40644005 Change-Id: Ie0608970daabe370db4616b875a8f098711c80e2 Refs: v8/v8@2733a08 Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com>
1 parent d0e75fd commit af07938

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.12',
41+
'v8_embedder_string': '-node.13',
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
@@ -263,4 +263,20 @@ TEST_F(ApiWasmTest, WasmEnableDisableCustomDescriptors) {
263263
}
264264
}
265265

266+
TEST_F(ApiWasmTest, GetWasmMemoryReservationSizeInBytes) {
267+
constexpr size_t kCapacity = 64 * 1024; // 64 KiB
268+
size_t reservation = V8::GetWasmMemoryReservationSizeInBytes(
269+
V8::WasmMemoryType::kMemory32, kCapacity);
270+
size_t reservation64 = V8::GetWasmMemoryReservationSizeInBytes(
271+
V8::WasmMemoryType::kMemory64, kCapacity);
272+
273+
#if V8_TRAP_HANDLER_SUPPORTED
274+
EXPECT_GE(reservation, kCapacity);
275+
EXPECT_GE(reservation64, kCapacity);
276+
#else
277+
EXPECT_EQ(reservation, kCapacity);
278+
EXPECT_EQ(reservation64, kCapacity);
279+
#endif // V8_TRAP_HANDLER_SUPPORTED
280+
}
281+
266282
} // namespace v8

0 commit comments

Comments
 (0)