v8/test/mjsunit/wasm/grow-shared-memory.js
Clemens Backes 421fd3929d [wasm] Rename {Get,Set,Tee}Local to Local{Get,Set,Tee}
This brings our constants back in line with the changed spec text. We
already use kExprTableGet and kExprTableSet, but for locals and globals
we still use the old wording.

This renaming is mostly mechanical.

PS1 was created using:
ag -l 'kExpr(Get|Set|Tee)Local' src test | \
  xargs -L1 sed -E 's/kExpr(Get|Set|Tee)Local\b/kExprLocal\1/g' -i

PS2 contains manual fixes.

R=mstarzinger@chromium.org

Bug: v8:9810
Change-Id: I1617f1b2a100685a3bf56218e76845a9481959c5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1847354
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64161}
2019-10-08 14:14:40 +00:00

347 lines
14 KiB
JavaScript

// Copyright 2019 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: --wasm-grow-shared-memory --experimental-wasm-threads
load("test/mjsunit/wasm/wasm-module-builder.js");
(function TestGrowSharedMemoryWithoutPostMessage() {
print(arguments.callee.name);
let memory = new WebAssembly.Memory({initial: 1, maximum: 5, shared: true});
assertEquals(memory.buffer.byteLength, kPageSize);
assertEquals(1, memory.grow(1));
assertEquals(memory.buffer.byteLength, 2 * kPageSize);
})();
function assertIsWasmSharedMemory(memory) {
assertTrue(memory instanceof Object,
"Memory is not an object");
assertTrue(memory instanceof WebAssembly.Memory,
"Object is not WebAssembly.Memory" );
assertTrue(memory.buffer instanceof SharedArrayBuffer,
"Memory.buffer is not a SharedArrayBuffer");
assertTrue(Object.isFrozen(memory.buffer),
"Memory.buffer not frozen");
}
function assertTrue(value, msg) {
if (!value) {
postMessage("Error: " + msg);
throw new Error("Exit"); // To stop testing.
}
}
let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString();
(function TestPostMessageWithGrow() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
assertIsWasmSharedMemory(obj.memory);
assertTrue(1 === obj.memory.grow(1));
assertTrue(obj.memory.buffer.byteLength === obj.expected_size);
assertIsWasmSharedMemory(obj.memory);
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 1, maximum: 5, shared: true});
let obj = {memory: memory, expected_size: 2 * kPageSize};
assertEquals(obj.memory.buffer.byteLength, kPageSize);
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(obj.memory.buffer.byteLength, 2 * kPageSize);
worker.terminate();
})();
// PostMessage from two different workers, and assert that the grow
// operations are performed on the same memory object.
(function TestWorkersWithGrowEarlyWorkerTerminate() {
print(arguments.callee.name);
let workerScript = workerHelpers +
`onmessage = function(obj) {
assertIsWasmSharedMemory(obj.memory);
obj.memory.grow(1);
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === obj.expected_size);
postMessage("OK");
};`;
let workers = [new Worker(workerScript, {type: 'string'}),
new Worker(workerScript, {type: 'string'})];
let memory = new WebAssembly.Memory({initial: 1, maximum: 5, shared: true});
let expected_pages = 1;
for (let worker of workers) {
assertEquals(memory.buffer.byteLength, expected_pages++ * kPageSize);
let obj = {memory: memory, expected_size: expected_pages * kPageSize};
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(memory.buffer.byteLength, expected_pages * kPageSize);
worker.terminate();
}
assertEquals(memory.buffer.byteLength, expected_pages * kPageSize);
})();
// PostMessage of Multiple memories and grow
(function TestGrowSharedWithMultipleMemories() {
print(arguments.callee.name);
let workerScript = workerHelpers +
`onmessage = function(obj) {
let expected_size = 0;
let kPageSize = 0x10000;
for (let memory of obj.memories) {
assertIsWasmSharedMemory(memory);
assertTrue(expected_size === memory.grow(2));
expected_size+=2;
assertIsWasmSharedMemory(memory);
assertTrue(memory.buffer.byteLength === expected_size * kPageSize);
}
postMessage("OK");
};`;
let worker = new Worker(workerScript, {type: 'string'});
let memories = [new WebAssembly.Memory({initial: 0, maximum: 2, shared: true}),
new WebAssembly.Memory({initial: 2, maximum: 10, shared: true}),
new WebAssembly.Memory({initial: 4, maximum: 12, shared: true})];
let obj = {memories: memories};
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(2 * kPageSize, memories[0].buffer.byteLength);
assertEquals(4 * kPageSize, memories[1].buffer.byteLength);
assertEquals(6 * kPageSize, memories[2].buffer.byteLength);
worker.terminate();
})();
// SharedMemory Object shared between different instances
(function TestPostMessageJSAndWasmInterop() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
let kPageSize = 0x10000;
assertIsWasmSharedMemory(obj.memory);
let instance = new WebAssembly.Instance(
obj.module, {m: {memory: obj.memory}});
assertTrue(5 === obj.memory.grow(10));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 15 * kPageSize);
assertTrue(15 === instance.exports.grow(5));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 20 * kPageSize);
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 5, maximum: 50, shared: true});
var builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "memory", 5, 100, "shared");
builder.addFunction("grow", kSig_i_i)
.addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
let obj = {memory: memory, module: module};
assertEquals(obj.memory.buffer.byteLength, 5 * kPageSize);
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
worker.terminate();
assertEquals(obj.memory.buffer.byteLength, 20 * kPageSize);
})();
(function TestConsecutiveJSAndWasmSharedGrow() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
let kPageSize = 0x10000;
assertIsWasmSharedMemory(obj.memory);
let instance = new WebAssembly.Instance(
obj.module, {m: {memory: obj.memory}});
assertTrue(5 === obj.memory.grow(10));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 15 * kPageSize);
assertTrue(15 === instance.exports.grow(5));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 20 * kPageSize);
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 5, maximum: 50, shared: true});
var builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "memory", 5, 100, "shared");
builder.addFunction("grow", kSig_i_i)
.addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
let obj = {memory: memory, module: module};
assertEquals(obj.memory.buffer.byteLength, 5 * kPageSize);
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(obj.memory.buffer.byteLength, 20 * kPageSize);
})();
(function TestConsecutiveWasmSharedGrow() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
let kPageSize = 0x10000;
assertIsWasmSharedMemory(obj.memory);
let instance = new WebAssembly.Instance(
obj.module, {m: {memory: obj.memory}});
assertTrue(5 === obj.memory.grow(10));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 15 * kPageSize);
assertTrue(17 === instance.exports.grow_twice(2));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 19 * kPageSize);
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 5, maximum: 50, shared: true});
var builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "memory", 5, 100, "shared");
builder.addFunction("grow_twice", kSig_i_i)
.addBody([kExprLocalGet, 0,
kExprMemoryGrow, kMemoryZero,
kExprDrop,
kExprLocalGet, 0,
kExprMemoryGrow, kMemoryZero])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
let obj = {memory: memory, module: module};
assertEquals(obj.memory.buffer.byteLength, 5 * kPageSize);
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(obj.memory.buffer.byteLength, 19 * kPageSize);
let instance = new WebAssembly.Instance(module, {m: {memory: memory}});
assertEquals(21, instance.exports.grow_twice(2));
assertEquals(obj.memory.buffer.byteLength, 23 * kPageSize);
})();
(function TestConsecutiveSharedGrowAndMemorySize() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
let kPageSize = 0x10000;
assertIsWasmSharedMemory(obj.memory);
let instance = new WebAssembly.Instance(
obj.module, {m: {memory: obj.memory}});
assertTrue(5 === obj.memory.grow(10));
assertTrue(15 === instance.exports.memory_size());
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 15 * kPageSize);
assertTrue(19 === instance.exports.grow_and_size(2));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 19 * kPageSize);
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 5, maximum: 50, shared: true});
var builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "memory", 5, 100, "shared");
builder.addFunction("grow_and_size", kSig_i_i)
.addBody([kExprLocalGet, 0,
kExprMemoryGrow, kMemoryZero,
kExprDrop,
kExprLocalGet, 0,
kExprMemoryGrow, kMemoryZero,
kExprDrop,
kExprMemorySize, kMemoryZero])
.exportFunc();
builder.addFunction("memory_size", kSig_i_v)
.addBody([kExprMemorySize, kMemoryZero])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
let obj = {memory: memory, module: module};
assertEquals(obj.memory.buffer.byteLength, 5 * kPageSize);
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(memory.buffer.byteLength, 19 * kPageSize);
let instance = new WebAssembly.Instance(module, {m: {memory: memory}});
assertEquals(23, instance.exports.grow_and_size(2));
assertEquals(obj.memory.buffer.byteLength, 23 * kPageSize);
assertEquals(23, memory.grow(2));
assertEquals(25, instance.exports.memory_size());
})();
// Only spot checking here because currently the underlying buffer doesn't move.
// In the case that the underlying buffer does move, more comprehensive memory
// integrity checking and bounds checks testing are needed.
(function TestSpotCheckMemoryWithSharedGrow() {
print(arguments.callee.name);
let worker = new Worker(workerHelpers +
`onmessage = function(obj) {
let kPageSize = 0x10000;
assertIsWasmSharedMemory(obj.memory);
let instance = new WebAssembly.Instance(
obj.module, {m: {memory: obj.memory}});
assertTrue(5 === obj.memory.grow(10));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 15 * kPageSize);
// Store again, and verify that the previous stores are still reflected.
instance.exports.atomic_store(15 * kPageSize - 4, 0xACED);
assertTrue(0xACED === instance.exports.atomic_load(0));
assertTrue(0xACED === instance.exports.atomic_load(5 * kPageSize - 4));
assertTrue(0xACED === instance.exports.atomic_load(15 * kPageSize - 4));
assertTrue(15 === instance.exports.grow(2));
assertIsWasmSharedMemory(obj.memory);
assertTrue(obj.memory.buffer.byteLength === 17 * kPageSize);
// Validate previous writes.
instance.exports.atomic_store(17 * kPageSize - 4, 0xACED);
assertTrue(0xACED === instance.exports.atomic_load(0));
assertTrue(0xACED === instance.exports.atomic_load(5 * kPageSize - 4));
assertTrue(0xACED === instance.exports.atomic_load(15 * kPageSize - 4));
assertTrue(0xACED === instance.exports.atomic_load(17 * kPageSize - 4));
postMessage("OK");
}`, {type: 'string'});
let memory = new WebAssembly.Memory({initial: 5, maximum: 50, shared: true});
var builder = new WasmModuleBuilder();
builder.addImportedMemory("m", "memory", 5, 100, "shared");
builder.addFunction("grow", kSig_i_i)
.addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero])
.exportFunc();
builder.addFunction("atomic_load", kSig_i_i)
.addBody([kExprLocalGet, 0, kAtomicPrefix, kExprI32AtomicLoad, 2, 0])
.exportFunc();
builder.addFunction("atomic_store", kSig_v_ii)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1,
kAtomicPrefix, kExprI32AtomicStore, 2, 0])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
let instance = new WebAssembly.Instance(module, {m: {memory: memory}});
// Store at first and last accessible 32 bit offset.
instance.exports.atomic_store(0, 0xACED);
instance.exports.atomic_store(5 * kPageSize - 4, 0xACED);
// Verify that these were stored.
assertEquals(0xACED, instance.exports.atomic_load(0));
assertEquals(0xACED, instance.exports.atomic_load(5 * kPageSize - 4));
// Verify bounds.
assertTraps(kTrapMemOutOfBounds,
() => instance.exports.atomic_load(5 * kPageSize - 3));
let obj = {memory: memory, module: module};
assertEquals(obj.memory.buffer.byteLength, 5 * kPageSize);
// PostMessage
worker.postMessage(obj);
assertEquals("OK", worker.getMessage());
assertEquals(memory.buffer.byteLength, 17 * kPageSize);
assertEquals(17, instance.exports.grow(2));
assertEquals(obj.memory.buffer.byteLength, 19 * kPageSize);
// Validate previous writes, and check bounds.
assertTrue(0xACED === instance.exports.atomic_load(0));
assertTrue(0xACED === instance.exports.atomic_load(5 * kPageSize - 4));
assertTrue(0xACED === instance.exports.atomic_load(15 * kPageSize - 4));
assertTrue(0xACED === instance.exports.atomic_load(17 * kPageSize - 4));
assertTraps(kTrapMemOutOfBounds,
() => instance.exports.atomic_load(19 * kPageSize - 3));
assertEquals(19, memory.grow(6));
assertEquals(obj.memory.buffer.byteLength, 25 * kPageSize);
assertTraps(kTrapMemOutOfBounds,
() => instance.exports.atomic_load(25 * kPageSize - 3));
})();
(function TestMemoryBufferTypeAfterGrow() {
const memory = new WebAssembly.Memory({
"initial": 1, "maximum": 2, "shared": true });
assertInstanceof(memory.buffer, SharedArrayBuffer);
assertEquals(memory.grow(1), 1);
assertInstanceof(memory.buffer, SharedArrayBuffer);
})();