Commit cfc4bba0 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[test][wasm] Allow testing of huge memories

This patch maintains the previous default value of the flag controlling
the max size of Wasm memories, but allows the limit to be raised on the
command line.
Bonus content: improve the multi-mapped mock allocator by falling back
to regular allocation for small requests.
More bonus content: make debug-mode Wasm tests faster.

Bug: v8:6306
Change-Id: Idabae5734794b06e65d45b3a6165dbd488847f3f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1981157
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65681}
parent bb4425c0
......@@ -219,11 +219,17 @@ class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
class MultiMappedAllocator : public ArrayBufferAllocatorBase {
protected:
void* Allocate(size_t length) override {
if (length < kChunkSize) {
return ArrayBufferAllocatorBase::Allocate(length);
}
// We use mmap, which initializes pages to zero anyway.
return AllocateUninitialized(length);
}
void* AllocateUninitialized(size_t length) override {
if (length < kChunkSize) {
return ArrayBufferAllocatorBase::AllocateUninitialized(length);
}
size_t rounded_length = RoundUp(length, kChunkSize);
int prot = PROT_READ | PROT_WRITE;
// We have to specify MAP_SHARED to make {mremap} below do what we want.
......@@ -250,6 +256,9 @@ class MultiMappedAllocator : public ArrayBufferAllocatorBase {
}
void Free(void* data, size_t length) override {
if (length < kChunkSize) {
return ArrayBufferAllocatorBase::Free(data, length);
}
void* real_alloc = regions_[data];
munmap(real_alloc, kChunkSize);
size_t rounded_length = RoundUp(length, kChunkSize);
......
......@@ -670,7 +670,8 @@ DEFINE_BOOL(wasm_async_compilation, true,
"enable actual asynchronous compilation for WebAssembly.compile")
DEFINE_BOOL(wasm_test_streaming, false,
"use streaming compilation instead of async compilation for tests")
DEFINE_UINT(wasm_max_mem_pages, v8::internal::wasm::kV8MaxWasmMemoryPages,
// TODO(4153): Set this back to v8::internal::wasm::kV8MaxWasmMemoryPages
DEFINE_UINT(wasm_max_mem_pages, 32767,
"maximum number of 64KiB memory pages of a wasm instance")
DEFINE_UINT(wasm_max_table_size, v8::internal::wasm::kV8MaxWasmTableSize,
"maximum table size of a wasm instance")
......
......@@ -3,6 +3,9 @@
// found in the LICENSE file.
#include "src/objects/backing-store.h"
#include <cstring>
#include "src/execution/isolate.h"
#include "src/handles/global-handles.h"
#include "src/logging/counters.h"
......@@ -103,11 +106,20 @@ void RecordStatus(Isolate* isolate, AllocationStatus status) {
inline void DebugCheckZero(void* start, size_t byte_length) {
#if DEBUG
// Double check memory is zero-initialized.
// Double check memory is zero-initialized. Despite being DEBUG-only,
// this function is somewhat optimized for the benefit of test suite
// execution times (some tests allocate several gigabytes).
const byte* bytes = reinterpret_cast<const byte*>(start);
for (size_t i = 0; i < byte_length; i++) {
const size_t kBaseCase = 32;
for (size_t i = 0; i < kBaseCase && i < byte_length; i++) {
DCHECK_EQ(0, bytes[i]);
}
// Having checked the first kBaseCase bytes to be zero, we can now use
// {memcmp} to compare the range against itself shifted by that amount,
// thereby inductively checking the remaining bytes.
if (byte_length > kBaseCase) {
DCHECK_EQ(0, memcmp(bytes, bytes + kBaseCase, byte_length - kBaseCase));
}
#endif
}
} // namespace
......
......@@ -72,7 +72,7 @@ struct CompilationEnv {
: 0),
max_memory_size((module && module->has_maximum_pages
? module->maximum_pages
: kV8MaxWasmMemoryPages) *
: max_mem_pages()) *
uint64_t{kWasmPageSize}),
enabled_features(enabled_features),
lower_simd(lower_simd) {}
......
......@@ -28,7 +28,7 @@ constexpr size_t kV8MaxWasmExceptions = 1000000;
constexpr size_t kV8MaxWasmExceptionTypes = 1000000;
constexpr size_t kV8MaxWasmDataSegments = 100000;
// Don't use this limit directly, but use the value of {max_mem_pages()}.
constexpr size_t kV8MaxWasmMemoryPages = 32767; // = ~ 2 GiB
constexpr size_t kV8MaxWasmMemoryPages = 65536; // = 4 GiB
constexpr size_t kV8MaxWasmStringSize = 100000;
constexpr size_t kV8MaxWasmModuleSize = 1024 * 1024 * 1024; // = 1 GiB
constexpr size_t kV8MaxWasmFunctionSize = 7654321;
......@@ -58,7 +58,7 @@ constexpr uint64_t kWasmMaxHeapOffset =
// Defined in wasm-engine.cc.
// TODO(wasm): Make this size_t for wasm64. Currently the --wasm-max-mem-pages
// flag is only uint32_t.
uint32_t max_mem_pages();
V8_EXPORT_PRIVATE uint32_t max_mem_pages();
uint32_t max_table_init_entries();
inline uint64_t max_mem_bytes() {
......
......@@ -231,9 +231,6 @@
# Runs out of stack space in debug builds.
'big-array-literal': [PASS, ['mode == debug', SKIP]],
# BUG(v8:6306).
'wasm/huge-memory': [SKIP],
# Allocates a huge string and then flattens it, very slow in debug mode.
'regress/regress-752764': [PASS, ['mode == debug', SLOW]],
......@@ -254,6 +251,8 @@
# Test doesn't work on 32-bit architectures (it would require a
# regexp pattern with too many captures).
# TODO(jkummerow/jgruber): Silently fails with pointer compression too.
# Fix it or delete it.
'regress/regress-976627': [FAIL, ['arch == x64 or arch == arm64 or arch == mips64el or arch == ppc64 or arch == s390x', PASS]],
# OOM with too many isolates/memory objects (https://crbug.com/1010272)
......@@ -446,6 +445,13 @@
'wasm/*': [SKIP],
}], # 'byteorder == big'
##############################################################################
# 32-bit platforms
['arch in (ia32, arm, mips, mipsel)', {
# Needs >2GB of available contiguous memory.
'wasm/huge-memory': [SKIP],
}], # 'arch in (ia32, arm, mips, mipsel)'
##############################################################################
['arch == arm64', {
......
......@@ -4,7 +4,7 @@
load('test/mjsunit/wasm/wasm-module-builder.js');
// Flags: --wasm-max-mem-pages=49152
// Flags: --wasm-max-mem-pages=49151
let builder = new WasmModuleBuilder();
const num_pages = 49152;
......
......@@ -6,10 +6,10 @@
load('test/mjsunit/wasm/wasm-module-builder.js');
let k1MiB = 1 * 1024 * 1024;
let k1GiB = 1 * 1024 * 1024 * 1024;
let k4GiB = 4 * k1GiB;
let kMaxMemory = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB
// TODO(4153): Raise this to 4GiB, but only on 64-bit platforms.
let kMaxMemory = 2 * k1GiB - kPageSize;
(function Test() {
var memory;
......@@ -36,20 +36,19 @@ let kMaxMemory = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB
function probe(a, f) {
print("------------------------");
let stride = kPageSize;
let stride = kPageSize * 32; // Don't check every page to save time.
let max = kMaxMemory;
for (let i = 0; i < max; i += stride) {
a.store(i, f(i));
}
for (let i = 0; i < max; i += stride) {
// print(`${i} = ${f(i)}`);
assertEquals(f(i), a.load(i));
}
}
try {
let kPages = kMaxMemory / kPageSize;
memory = new WebAssembly.Memory({initial: kPages, maximum: kPages});
memory = new WebAssembly.Memory({ initial: kPages, maximum: kPages });
} catch (e) {
print("OOM: sorry, best effort max memory size test.");
return;
......
......@@ -3,6 +3,8 @@
// found in the LICENSE file.
// Flags: --wasm-max-mem-pages=49152
// Save some memory on Linux; other platforms ignore this flag.
// Flags: --multi-mapped-mock-allocator
// This test makes sure things don't break once we support >2GB wasm memories.
load("test/mjsunit/wasm/wasm-module-builder.js");
......
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