Commit 41024b43 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[wasm][32-bit] Always grow memory by a factor

On 32-bit platforms, we generally don't over-allocate backing stores
for Wasm memories. That leads to quadratic overall complexity of
repeated growth operations by a few pages each though. To fix that,
this patch introduces a small over-allocation factor: when we have
to reallocate to grow a memory, we now grow by at least 1/8th of the
memory's previous size.

Bug: chromium:1294262
Change-Id: I89b5e974c75aac78bece8fcd72fb7a2184345153
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3472496
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79193}
parent 0780be44
......@@ -544,13 +544,13 @@ std::unique_ptr<BackingStore> BackingStore::AllocateWasmMemory(
}
std::unique_ptr<BackingStore> BackingStore::CopyWasmMemory(Isolate* isolate,
size_t new_pages) {
size_t new_pages,
size_t max_pages) {
// Note that we could allocate uninitialized to save initialization cost here,
// but since Wasm memories are allocated by the page allocator, the zeroing
// cost is already built-in.
// TODO(titzer): should we use a suitable maximum here?
auto new_backing_store = BackingStore::AllocateWasmMemory(
isolate, new_pages, new_pages,
isolate, new_pages, max_pages,
is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared);
if (!new_backing_store ||
......
......@@ -122,7 +122,8 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
// Allocate a new, larger, backing store for this Wasm memory and copy the
// contents of this backing store into it.
std::unique_ptr<BackingStore> CopyWasmMemory(Isolate* isolate,
size_t new_pages);
size_t new_pages,
size_t max_pages);
// Attach the given memory object to this backing store. The memory object
// will be updated if this backing store is grown.
......
......@@ -997,8 +997,14 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
size_t new_pages = old_pages + pages;
DCHECK_LT(old_pages, new_pages);
// Try allocating a new backing store and copying.
// To avoid overall quadratic complexity of many small grow operations, we
// grow by at least 0.5 MB + 12.5% of the existing memory size.
// These numbers are kept small because we must be careful about address
// space consumption on 32-bit platforms.
size_t min_growth = old_pages + 8 + (old_pages >> 3);
size_t new_capacity = std::max(new_pages, min_growth);
std::unique_ptr<BackingStore> new_backing_store =
backing_store->CopyWasmMemory(isolate, new_pages);
backing_store->CopyWasmMemory(isolate, new_pages, new_capacity);
if (!new_backing_store) {
// Crash on out-of-memory if the correctness fuzzer is running.
if (FLAG_correctness_fuzzer_suppressions) {
......
......@@ -64,7 +64,7 @@ TEST_F(BackingStoreTest, CopyWasmMemory) {
EXPECT_EQ(1 * wasm::kWasmPageSize, bs1->byte_length());
EXPECT_EQ(2 * wasm::kWasmPageSize, bs1->byte_capacity());
auto bs2 = bs1->CopyWasmMemory(isolate(), 3);
auto bs2 = bs1->CopyWasmMemory(isolate(), 3, 3);
EXPECT_TRUE(bs2->is_wasm_memory());
EXPECT_EQ(3 * wasm::kWasmPageSize, bs2->byte_length());
EXPECT_EQ(3 * wasm::kWasmPageSize, bs2->byte_capacity());
......
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