mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
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: https://github.com/nodejs/node/pull/62132
Refs: https://github.com/microsoft/vscode/issues/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: https://github.com/v8/v8/commit/bef0d9c1bc90357ef5e654b25fcb4ef9f74b591c
Co-authored-by: Joyee Cheung <joyeec9h3@gmail.com>
Refs: https://github.com/microsoft/vscode/issues/251777
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7638233
PR-URL: https://github.com/nodejs/node/pull/61898
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
1 parent
cc5a331715
commit
13fb819110
6 files changed
+94
-21
No files matched your search
+1
-1
@@ -40,7 +40,7 @@
|
||||
|
||||
# Reset this number to 0 on major V8 upgrades.
|
||||
# Increment by one for each non-official patch applied to deps/v8.
|
||||
'v8_embedder_string': '-node.12',
|
||||
'v8_embedder_string': '-node.13',
|
||||
|
||||
##### V8 defaults for Node.js #####
|
||||
|
||||
|
||||
Vendored
+29
@@ -253,6 +253,35 @@ class V8_EXPORT V8 {
|
||||
static size_t GetSandboxReservationSizeInBytes();
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
|
||||
enum class WasmMemoryType {
|
||||
kMemory32,
|
||||
kMemory64,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the virtual address space reservation size (in bytes) needed
|
||||
* for one WebAssembly memory instance of the given capacity.
|
||||
*
|
||||
* \param type Whether this is a memory32 or memory64 instance.
|
||||
* \param byte_capacity The maximum size, in bytes, of the WebAssembly
|
||||
* memory. Values exceeding the engine's maximum allocatable memory
|
||||
* size for the given type (determined by max_mem32_pages or
|
||||
* max_mem64_pages) are clamped.
|
||||
*
|
||||
* When trap-based bounds checking is enabled by
|
||||
* EnableWebAssemblyTrapHandler(), the amount of virtual address space
|
||||
* that V8 needs to reserve for each WebAssembly memory instance can
|
||||
* be much bigger than the requested size. If the process does
|
||||
* not have enough virtual memory available, WebAssembly memory allocation
|
||||
* would fail. During the initialization of V8, embedders can use this method
|
||||
* to estimate whether the process has enough virtual memory for their
|
||||
* usage of WebAssembly, and decide whether to enable the trap handler
|
||||
* via EnableWebAssemblyTrapHandler(), or to skip it and reduce the amount of
|
||||
* virtual memory required to keep the application running.
|
||||
*/
|
||||
static size_t GetWasmMemoryReservationSizeInBytes(WasmMemoryType type,
|
||||
size_t byte_capacity);
|
||||
|
||||
/**
|
||||
* Activate trap-based bounds checking for WebAssembly.
|
||||
*
|
||||
|
||||
Vendored
+21
@@ -152,6 +152,7 @@
|
||||
#include "src/wasm/value-type.h"
|
||||
#include "src/wasm/wasm-engine.h"
|
||||
#include "src/wasm/wasm-js.h"
|
||||
#include "src/wasm/wasm-limits.h"
|
||||
#include "src/wasm/wasm-objects-inl.h"
|
||||
#include "src/wasm/wasm-result.h"
|
||||
#include "src/wasm/wasm-serialization.h"
|
||||
@@ -6358,6 +6359,26 @@ bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t V8::GetWasmMemoryReservationSizeInBytes(WasmMemoryType type,
|
||||
size_t byte_capacity) {
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
bool is_memory64 = type == WasmMemoryType::kMemory64;
|
||||
uint64_t max_byte_capacity =
|
||||
is_memory64 ? i::wasm::max_mem64_bytes() : i::wasm::max_mem32_bytes();
|
||||
if (byte_capacity > max_byte_capacity) {
|
||||
byte_capacity = static_cast<size_t>(max_byte_capacity);
|
||||
}
|
||||
#if V8_TRAP_HANDLER_SUPPORTED
|
||||
if (!is_memory64 || i::v8_flags.wasm_memory64_trap_handling) {
|
||||
return i::BackingStore::GetWasmReservationSize(
|
||||
/* has_guard_regions */ true, byte_capacity,
|
||||
/* is_wasm_memory64 */ is_memory64);
|
||||
}
|
||||
#endif // V8_TRAP_HANDLER_SUPPORTED
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
return byte_capacity;
|
||||
}
|
||||
|
||||
bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
return i::trap_handler::EnableTrapHandler(use_v8_signal_handler);
|
||||
|
||||
Vendored
+22
-20
@@ -51,8 +51,25 @@ enum class AllocationStatus {
|
||||
kOtherFailure // Failed for an unknown reason
|
||||
};
|
||||
|
||||
size_t GetReservationSize(bool has_guard_regions, size_t byte_capacity,
|
||||
bool is_wasm_memory64) {
|
||||
base::AddressRegion GetReservedRegion(bool has_guard_regions,
|
||||
bool is_wasm_memory64, void* buffer_start,
|
||||
size_t byte_capacity) {
|
||||
return base::AddressRegion(
|
||||
reinterpret_cast<Address>(buffer_start),
|
||||
BackingStore::GetWasmReservationSize(has_guard_regions, byte_capacity,
|
||||
is_wasm_memory64));
|
||||
}
|
||||
|
||||
void RecordStatus(Isolate* isolate, AllocationStatus status) {
|
||||
isolate->counters()->wasm_memory_allocation_result()->AddSample(
|
||||
static_cast<int>(status));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
size_t BackingStore::GetWasmReservationSize(bool has_guard_regions,
|
||||
size_t byte_capacity,
|
||||
bool is_wasm_memory64) {
|
||||
#if V8_TARGET_ARCH_64_BIT && V8_ENABLE_WEBASSEMBLY
|
||||
DCHECK_IMPLIES(is_wasm_memory64 && has_guard_regions,
|
||||
v8_flags.wasm_memory64_trap_handling);
|
||||
@@ -73,21 +90,6 @@ size_t GetReservationSize(bool has_guard_regions, size_t byte_capacity,
|
||||
return byte_capacity;
|
||||
}
|
||||
|
||||
base::AddressRegion GetReservedRegion(bool has_guard_regions,
|
||||
bool is_wasm_memory64, void* buffer_start,
|
||||
size_t byte_capacity) {
|
||||
return base::AddressRegion(
|
||||
reinterpret_cast<Address>(buffer_start),
|
||||
GetReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64));
|
||||
}
|
||||
|
||||
void RecordStatus(Isolate* isolate, AllocationStatus status) {
|
||||
isolate->counters()->wasm_memory_allocation_result()->AddSample(
|
||||
static_cast<int>(status));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// The backing store for a Wasm shared memory remembers all the isolates
|
||||
// with which it has been shared.
|
||||
struct SharedWasmMemoryData {
|
||||
@@ -169,7 +171,7 @@ BackingStore::~BackingStore() {
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
if (is_wasm_memory()) {
|
||||
size_t reservation_size = GetReservationSize(
|
||||
size_t reservation_size = GetWasmReservationSize(
|
||||
has_guard_regions(), byte_capacity_, is_wasm_memory64());
|
||||
TRACE_BS(
|
||||
"BSw:free bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
|
||||
@@ -319,8 +321,8 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateAndPartiallyCommitMemory(
|
||||
};
|
||||
|
||||
size_t byte_capacity = maximum_pages * page_size;
|
||||
size_t reservation_size =
|
||||
GetReservationSize(has_guard_regions, byte_capacity, is_wasm_memory64);
|
||||
size_t reservation_size = GetWasmReservationSize(
|
||||
has_guard_regions, byte_capacity, is_wasm_memory64);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Allocate pages (inaccessible by default).
|
||||
|
||||
Vendored
+5
@@ -202,6 +202,11 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
|
||||
|
||||
uint32_t id() const { return id_; }
|
||||
|
||||
// Return the size of the reservation needed for a wasm backing store.
|
||||
static size_t GetWasmReservationSize(bool has_guard_regions,
|
||||
size_t byte_capacity,
|
||||
bool is_wasm_memory64);
|
||||
|
||||
private:
|
||||
friend class GlobalBackingStoreRegistry;
|
||||
|
||||
|
||||
+16
@@ -124,6 +124,22 @@ void WasmStreamingMoreFunctionsCanBeSerializedCallback(
|
||||
streaming->SetMoreFunctionsCanBeSerializedCallback([](CompiledWasmModule) {});
|
||||
}
|
||||
|
||||
TEST_F(ApiWasmTest, GetWasmMemoryReservationSizeInBytes) {
|
||||
constexpr size_t kCapacity = 64 * 1024; // 64 KiB
|
||||
size_t reservation = V8::GetWasmMemoryReservationSizeInBytes(
|
||||
V8::WasmMemoryType::kMemory32, kCapacity);
|
||||
size_t reservation64 = V8::GetWasmMemoryReservationSizeInBytes(
|
||||
V8::WasmMemoryType::kMemory64, kCapacity);
|
||||
|
||||
#if V8_TRAP_HANDLER_SUPPORTED
|
||||
EXPECT_GE(reservation, kCapacity);
|
||||
EXPECT_GE(reservation64, kCapacity);
|
||||
#else
|
||||
EXPECT_EQ(reservation, kCapacity);
|
||||
EXPECT_EQ(reservation64, kCapacity);
|
||||
#endif // V8_TRAP_HANDLER_SUPPORTED
|
||||
}
|
||||
|
||||
TEST_F(ApiWasmTest, WasmStreamingCallback) {
|
||||
TestWasmStreaming(WasmStreamingCallbackTestCallbackIsCalled,
|
||||
Promise::kPending);
|
||||
|
||||
Reference in new issue
Block a user