Commit d5720c74 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[wasm] Reduce memory reservation without trap handlers

If trap handlers are disabled, we don't need guard regions around wasm
memories. Hence use the dynamic {trap_handler::IsTrapHandlerEnabled()}
check, instead of always reserving guard regions on all 64-bit
platforms.
This will allow to reserve pretty much arbitrarily many wasm memories if
trap handlers are disabled.

Two tests are added to test the number of memories that can be
allocated: With trap handlers, at least 50 memories should always be
possible. Without trap handlers, 10000 small memories should not be a
problem (each one is taking 64kB, so it's 640MB overall).

Drive-by: Improve tracing.

R=ahaas@chromium.org

Bug: v8:11017
Change-Id: Ic4c620f63dfbef571e64df0b3372b83a1db566ab
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2491034Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70732}
parent 0b355643
......@@ -9,6 +9,7 @@
#include "src/execution/isolate.h"
#include "src/handles/global-handles.h"
#include "src/logging/counters.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/wasm-constants.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"
......@@ -23,12 +24,6 @@ namespace v8 {
namespace internal {
namespace {
#if V8_TARGET_ARCH_64_BIT
constexpr bool kUseGuardRegions = true;
#else
constexpr bool kUseGuardRegions = false;
#endif
#if V8_TARGET_ARCH_MIPS64
// MIPS64 has a user space of 2^40 bytes on most processors,
// address space limits needs to be smaller.
......@@ -173,8 +168,11 @@ BackingStore::~BackingStore() {
if (is_wasm_memory_) {
DCHECK(free_on_destruct_);
DCHECK(!custom_deleter_);
TRACE_BS("BSw:free bs=%p mem=%p (length=%zu, capacity=%zu)\n", this,
buffer_start_, byte_length(), byte_capacity_);
size_t reservation_size =
GetReservationSize(has_guard_regions_, byte_capacity_);
TRACE_BS(
"BSw:free bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
this, buffer_start_, byte_length(), byte_capacity_, reservation_size);
if (is_shared_) {
// Deallocate the list of attached memory objects.
SharedWasmMemoryData* shared_data = get_shared_wasm_memory_data();
......@@ -191,8 +189,7 @@ BackingStore::~BackingStore() {
FreePages(GetPlatformPageAllocator(),
reinterpret_cast<void*>(region.begin()), region.size());
CHECK(pages_were_freed);
BackingStore::ReleaseReservation(
GetReservationSize(has_guard_regions_, byte_capacity_));
BackingStore::ReleaseReservation(reservation_size);
Clear();
return;
}
......@@ -304,7 +301,7 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory(
TRACE_BS("BSw:try %zu pages, %zu max\n", initial_pages, maximum_pages);
bool guards = kUseGuardRegions;
bool guards = trap_handler::IsTrapHandlerEnabled();
// For accounting purposes, whether a GC was necessary.
bool did_retry = false;
......@@ -348,7 +345,8 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory(
FATAL("could not allocate wasm memory backing store");
}
RecordStatus(isolate, AllocationStatus::kAddressSpaceLimitReachedFailure);
TRACE_BS("BSw:try failed to reserve address space\n");
TRACE_BS("BSw:try failed to reserve address space (size %zu)\n",
reservation_size);
return {};
}
......@@ -405,8 +403,10 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory(
false, // custom_deleter
false); // empty_deleter
TRACE_BS("BSw:alloc bs=%p mem=%p (length=%zu, capacity=%zu)\n", result,
result->buffer_start(), byte_length, byte_capacity);
TRACE_BS(
"BSw:alloc bs=%p mem=%p (length=%zu, capacity=%zu, reservation=%zu)\n",
result, result->buffer_start(), byte_length, byte_capacity,
reservation_size);
// Shared Wasm memories need an anchor for the memory object list.
if (shared == SharedFlag::kShared) {
......
......@@ -69,7 +69,7 @@ extern bool g_is_trap_handler_enabled;
//
// use_v8_handler indicates that V8 should install its own handler
// rather than relying on the embedder to do it.
bool EnableTrapHandler(bool use_v8_handler);
V8_EXPORT_PRIVATE bool EnableTrapHandler(bool use_v8_handler);
inline bool IsTrapHandlerEnabled() {
DCHECK_IMPLIES(g_is_trap_handler_enabled, V8_TRAP_HANDLER_SUPPORTED);
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --no-wasm-trap-handler
// No reason to stress-opt this; save some time.
// Flags: --no-stress-opt
load('test/mjsunit/wasm/wasm-module-builder.js');
// Without trap handlers, we are able to allocate basically arbitrarily many
// memories, because we don't need to reserve a huge amount of virtual address
// space.
const num_memories = 10000;
const memories = [];
while (memories.length < num_memories) {
print('Allocating memory #' + memories.length);
memories.push(new WebAssembly.Memory({initial: 1, maximum: 1}));
}
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// No reason to stress-opt this; save some time.
// Flags: --no-stress-opt
load('test/mjsunit/wasm/wasm-module-builder.js');
// Test that we can generate at least 50 memories of small size.
// More memories are currently not possible if the trap handler is enabled,
// because we reserve 10GB then, and we have a virtual memory space limit of
// 512GB on MIPS64 and 1TB+4GB on other 64-bit systems.
// The number of memories should be increased in this test once we raise that
// limit or fix the allocation strategy to allow for more memories generally.
const num_memories = 50;
const memories = [];
while (memories.length < num_memories) {
print('Allocating memory #' + memories.length);
memories.push(new WebAssembly.Memory({initial: 1, maximum: 1}));
}
......@@ -80,6 +80,7 @@ class TrapHandlerTest : public TestWithIsolate,
public ::testing::WithParamInterface<TrapHandlerStyle> {
protected:
void SetUp() override {
CHECK(trap_handler::EnableTrapHandler(false));
backing_store_ = BackingStore::AllocateWasmMemory(i_isolate(), 1, 1,
SharedFlag::kNotShared);
CHECK(backing_store_);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment