Commit 405fa4d6 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm][memory64] Bump memory limit to 16GB

Bump the memory size limit of memory64 memories from 4GB to 16GB. Tests
are added for larger sizes (5GB, 16GB).

Drive-by: Improve two decoder errors to properly include the unit,
  tested by the new tests.

R=jkummerow@chromium.org

Bug: v8:10949
Change-Id: I99dfc216b9213838784214c0b65ba863831d5884
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3789507Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82105}
parent 4a33fd79
......@@ -1998,8 +1998,8 @@ class ModuleDecoderTemplate : public Decoder {
if (initial_64 > max_initial) {
errorf(pos,
"initial %s size (%" PRIu64
" %s) is larger than implementation limit (%u)",
name, initial_64, units, max_initial);
" %s) is larger than implementation limit (%u %s)",
name, initial_64, units, max_initial, units);
}
*initial = static_cast<uint32_t>(initial_64);
tracer_.Description(*initial);
......@@ -2012,8 +2012,8 @@ class ModuleDecoderTemplate : public Decoder {
if (maximum_64 > max_maximum) {
errorf(pos,
"maximum %s size (%" PRIu64
" %s) is larger than implementation limit (%u)",
name, maximum_64, units, max_maximum);
" %s) is larger than implementation limit (%u %s)",
name, maximum_64, units, max_maximum, units);
}
if (maximum_64 < *initial) {
errorf(pos,
......
......@@ -23,8 +23,8 @@ namespace wasm {
// These constants limit the amount of *declared* memory. At runtime, memory can
// only grow up to kV8MaxWasmMemory{32,64}Pages.
constexpr size_t kSpecMaxMemory32Pages = 65536; // 4GB
// TODO(clemensb): Increase the maximum for memory64.
constexpr size_t kSpecMaxMemory64Pages = 65536; // 4GB
// TODO(clemensb): Adapt once the spec defines a limit here. For now, use 16GB.
constexpr size_t kSpecMaxMemory64Pages = 262144; // 16GB
// The following limits are imposed by V8 on WebAssembly modules.
// The limits are agreed upon with other engines for consistency.
......@@ -44,10 +44,9 @@ constexpr size_t kV8MaxWasmDataSegments = 100000;
constexpr size_t kV8MaxWasmMemory32Pages = kSystemPointerSize == 4
? 32767 // = 2 GiB - 64Kib
: 65536; // = 4 GiB
// TODO(clemensb): Increase the maximum for memory64.
constexpr size_t kV8MaxWasmMemory64Pages = kSystemPointerSize == 4
? 32767 // = 2 GiB - 64Kib
: 65536; // = 4 GiB
? 32767 // = 2 GiB - 64Kib
: 262144; // = 16 GiB
constexpr size_t kV8MaxWasmStringSize = 100000;
constexpr size_t kV8MaxWasmModuleSize = 1024 * 1024 * 1024; // = 1 GiB
constexpr size_t kV8MaxWasmFunctionSize = 7654321;
......
......@@ -9,6 +9,10 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
// We use standard JavaScript doubles to represent bytes and offsets. They offer
// enough precision (53 bits) for every allowed memory size.
const GB = 1024 * 1024 * 1024;
// The current limit is 16GB. Adapt this test if this changes.
const max_num_pages = 16 * GB / kPageSize;
function BasicMemory64Tests(num_pages) {
const num_bytes = num_pages * kPageSize;
print(`Testing ${num_bytes} bytes (${num_pages} pages)`);
......@@ -37,8 +41,20 @@ function BasicMemory64Tests(num_pages) {
let load = module.exports.load;
let store = module.exports.store;
let array = new Int8Array(memory.buffer);
assertEquals(num_bytes, array.length);
assertEquals(num_bytes, memory.buffer.byteLength);
// TODO(v8:4153): Enable for all sizes once the TypedArray size limit is
// raised.
const kMaxTypedArraySize = Math.pow(2, 32);
if (num_bytes > kMaxTypedArraySize) {
// TODO(v8:4153): Fix the error message below, if we don't decide to bump
// the limit soon.
assertThrows(
() => new Int8Array(memory.buffer), RangeError,
'Invalid typed array length: undefined');
} else {
let array = new Int8Array(memory.buffer);
assertEquals(num_bytes, array.length);
}
assertEquals(0, load(num_bytes - 4));
assertThrows(() => load(num_bytes - 3));
......@@ -59,7 +75,18 @@ function BasicMemory64Tests(num_pages) {
} else if (num_bytes - position <= 4) {
expected = [0x12, 0x34, 0x56, 0x78][num_bytes - position - 1];
}
assertEquals(expected, array[position]);
let value = new Int8Array(memory.buffer, position, 1)[0];
assertEquals(expected, value);
}
}
function allowOOM(fn) {
try {
fn();
} catch (e) {
const is_oom =
(e instanceof RangeError) && e.message.includes('Out of memory');
if (!is_oom) throw e;
}
}
......@@ -70,22 +97,53 @@ function BasicMemory64Tests(num_pages) {
(function Test3GBMemory() {
print(arguments.callee.name);
let num_pages = 3 * 1024 * 1024 * 1024 / kPageSize;
let num_pages = 3 * GB / kPageSize;
// This test can fail if 3GB of memory cannot be allocated.
try {
BasicMemory64Tests(num_pages);
} catch (e) {
assertInstanceof(e, RangeError);
assertMatches(/Out of memory/, e.message);
}
allowOOM(() => BasicMemory64Tests(num_pages));
})();
(function Test5GBMemory() {
print(arguments.callee.name);
let num_pages = 5 * GB / kPageSize;
// This test can fail if 5GB of memory cannot be allocated.
allowOOM(() => BasicMemory64Tests(num_pages));
})();
(function TestMaxMem64Size() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory64(max_num_pages);
assertTrue(WebAssembly.validate(builder.toBuffer()));
builder.toModule();
// This test can fail if 16GB of memory cannot be allocated.
allowOOM(() => BasicMemory64Tests(max_num_pages));
})();
(function TestTooBigDeclaredInitial() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory64(max_num_pages + 1);
assertFalse(WebAssembly.validate(builder.toBuffer()));
assertThrows(
() => builder.toModule(), WebAssembly.CompileError,
'WebAssembly.Module(): initial memory size (262145 pages) is larger ' +
'than implementation limit (262144 pages) @+12');
})();
// TODO(clemensb): Allow for memories >4GB and enable this test.
//(function Test5GBMemory() {
// print(arguments.callee.name);
// let num_pages = 5 * 1024 * 1024 * 1024 / kPageSize;
// BasicMemory64Tests(num_pages);
//})();
(function TestTooBigDeclaredMaximum() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
builder.addMemory64(1, max_num_pages + 1);
assertFalse(WebAssembly.validate(builder.toBuffer()));
assertThrows(
() => builder.toModule(), WebAssembly.CompileError,
'WebAssembly.Module(): maximum memory size (262145 pages) is larger ' +
'than implementation limit (262144 pages) @+13');
})();
(function TestGrow64() {
print(arguments.callee.name);
......
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