Skip to content

Commit b3de1cb

Browse files
committed
deps: don't enable wasm trap handler if there's not enough vmem
1 parent b5c9469 commit b3de1cb

File tree

4 files changed

+89
-19
lines changed

4 files changed

+89
-19
lines changed

deps/v8/include/v8-initialization.h

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

256+
/**
257+
* Enabling the WebAssembly trap handler requires the process to be able to
258+
* access enough virtual address space. Returns true if the
259+
* system requirements are met at the time of the call.
260+
*/
261+
static bool CanEnableWebAssemblyTrapHandler();
262+
256263
/**
257264
* Activate trap-based bounds checking for WebAssembly.
258265
*

deps/v8/src/api/api.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,14 @@
183183
#include "src/diagnostics/etw-jit-win.h"
184184
#endif // V8_ENABLE_ETW_STACK_WALKING
185185

186+
#if V8_OS_WIN
187+
#define WIN32_LEAN_AND_MEAN
188+
#include <windows.h>
189+
#include <psapi.h>
190+
#else
191+
#include <sys/resource.h>
192+
#include <unistd.h>
193+
#endif
186194
namespace v8 {
187195

188196
i::ExternalPointerTag ToExternalPointerTag(v8::EmbedderDataTypeTag api_tag) {
@@ -6277,6 +6285,9 @@ bool v8::V8::Initialize(const int build_config) {
62776285
bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
62786286
void* context) {
62796287
#if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6288+
if (!i::trap_handler::IsTrapHandlerEnabled()) {
6289+
return false;
6290+
}
62806291
return i::trap_handler::TryHandleSignal(sig_code, info, context);
62816292
#else
62826293
return false;
@@ -6287,14 +6298,63 @@ bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
62876298
#if V8_OS_WIN
62886299
bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
62896300
#if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6301+
if (!i::trap_handler::IsTrapHandlerEnabled()) {
6302+
return false;
6303+
}
62906304
return i::trap_handler::TryHandleWasmTrap(exception);
62916305
#else
62926306
return false;
62936307
#endif
62946308
}
62956309
#endif
62966310

6311+
static uint64_t GetAddressSpaceSize() {
6312+
#if V8_OS_WIN
6313+
SYSTEM_INFO si{};
6314+
GetSystemInfo(&si);
6315+
6316+
auto lo = reinterpret_cast<uintptr_t>(si.lpMinimumApplicationAddress);
6317+
auto hi = reinterpret_cast<uintptr_t>(si.lpMaximumApplicationAddress);
6318+
6319+
// The range is inclusive, so add 1.
6320+
return static_cast<uint64_t>(hi - lo) + 1ULL;
6321+
#else
6322+
struct rlimit lim;
6323+
if (getrlimit(RLIMIT_AS, &lim) == 0 && lim.rlim_cur != RLIM_INFINITY) {
6324+
return static_cast<uint64_t>(lim.rlim_cur);
6325+
}
6326+
// Either RLIM_INFINITY or getrlimit failed — treat as "unlimited".
6327+
return std::numeric_limits<uintptr_t>::max();
6328+
#endif
6329+
}
6330+
6331+
bool V8::CanEnableWebAssemblyTrapHandler() {
6332+
#if V8_ENABLE_WEBASSEMBLY
6333+
uint64_t virtual_memory_available = GetAddressSpaceSize();
6334+
if (virtual_memory_available == 0) {
6335+
// There's no limit, assume trap handler can be enabled.
6336+
return true;
6337+
}
6338+
bool has_guard_regions = true; // Assume guard regions are enabled.
6339+
size_t byte_capacity = 1; // Check if it can reserve memory for an allocation as low as 1 byte.
6340+
size_t memory32_size = i::BackingStore::GetWasmReservationSize(has_guard_regions, byte_capacity, false);
6341+
uint64_t required_size = static_cast<uint64_t>(memory32_size);
6342+
if (i::v8_flags.wasm_memory64_trap_handling) {
6343+
uint64_t memory64_size = static_cast<uint64_t>(i::BackingStore::GetWasmReservationSize(has_guard_regions, byte_capacity, true));
6344+
required_size = std::max(memory64_size, required_size);
6345+
}
6346+
6347+
return virtual_memory_available >= required_size;
6348+
#else
6349+
return false;
6350+
#endif
6351+
}
6352+
62976353
bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6354+
if (!CanEnableWebAssemblyTrapHandler()) {
6355+
return false;
6356+
}
6357+
62986358
#if V8_ENABLE_WEBASSEMBLY
62996359
return i::trap_handler::EnableTrapHandler(use_v8_signal_handler);
63006360
#else

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

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,23 @@ 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, is_wasm_memory64));
60+
}
61+
62+
void RecordStatus(Isolate* isolate, AllocationStatus status) {
63+
isolate->counters()->wasm_memory_allocation_result()->AddSample(
64+
static_cast<int>(status));
65+
}
66+
67+
} // namespace
68+
69+
size_t BackingStore::GetWasmReservationSize(bool has_guard_regions, size_t byte_capacity,
70+
bool is_wasm_memory64) {
5671
#if V8_TARGET_ARCH_64_BIT && V8_ENABLE_WEBASSEMBLY
5772
DCHECK_IMPLIES(is_wasm_memory64 && has_guard_regions,
5873
v8_flags.wasm_memory64_trap_handling);
@@ -73,21 +88,6 @@ size_t GetReservationSize(bool has_guard_regions, size_t byte_capacity,
7388
return byte_capacity;
7489
}
7590

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-
9191
// The backing store for a Wasm shared memory remembers all the isolates
9292
// with which it has been shared.
9393
struct SharedWasmMemoryData {
@@ -168,7 +168,7 @@ BackingStore::~BackingStore() {
168168

169169
#if V8_ENABLE_WEBASSEMBLY
170170
if (is_wasm_memory()) {
171-
size_t reservation_size = GetReservationSize(
171+
size_t reservation_size = GetWasmReservationSize(
172172
has_guard_regions(), byte_capacity_, is_wasm_memory64());
173173
TRACE_BS(
174174
"BSw:free bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
@@ -325,7 +325,7 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
325325

326326
size_t byte_capacity = maximum_pages * page_size;
327327
size_t reservation_size =
328-
GetReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64);
328+
GetWasmReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64);
329329

330330
//--------------------------------------------------------------------------
331331
// Allocate pages (inaccessible by default).

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ 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, size_t byte_capacity,
188+
bool is_wasm_memory64);
186189
private:
187190
friend class GlobalBackingStoreRegistry;
188191

0 commit comments

Comments
 (0)