[wasm] Fix possible hang in compare-exchange tests

Make sure that the workers do not start running before the main thread
told them so by setting the memory to the first element in the sequence.
Otherwise it can happen that the main thread resets the memory after the
workers already started doing their updates, which results in a hang
(see linked bug).

R=marja@chromium.org

Bug: v8:10625
Change-Id: I959018279e0049900d44457b72146bc37a12bcb4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2252191
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68429}
This commit is contained in:
Clemens Backes 2020-06-19 11:29:00 +02:00 committed by Commit Bot
parent 36532d1beb
commit a2ef686f86
2 changed files with 34 additions and 14 deletions

View File

@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const kSequenceLength = 8192; const kSequenceLength = 8192;
const kNumberOfWorkers = 4; const kNumberOfWorkers = 4;
const kBitMask = kNumberOfWorkers - 1; const kBitMask = kNumberOfWorkers - 1;
const kMemoryAddress = 0;
const kSequenceStartAddress = 32; const kSequenceStartAddress = 32;
function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
@ -135,7 +136,8 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
function generateSequence(typedarray, start, count) { function generateSequence(typedarray, start, count) {
let end = count + start; let end = count + start;
for (let i = start; i < end; i++) { for (let i = start; i < end; i++) {
typedarray[i] = Math.floor(Math.random() * 256); // Avoid the value 255, which is used as initial value in memory.
typedarray[i] = Math.floor(Math.random() * 255);
} }
} }
@ -186,15 +188,23 @@ function testOpcode(opcode, opcodeSize) {
shared: true shared: true
}); });
let memoryView = new Uint8Array(memory.buffer); let memoryView = new Uint8Array(memory.buffer);
generateSequence(memoryView, kSequenceStartAddress, kSequenceLength * (opcodeSize / 8)); let numBytes = opcodeSize / 8;
generateSequence(
memoryView, kSequenceStartAddress, kSequenceLength * numBytes);
// Initialize the memory to a value which does not appear in the sequence.
memoryView.fill(255, kMemoryAddress, numBytes);
let module = new WebAssembly.Module(builder.toBuffer()); let module = new WebAssembly.Module(builder.toBuffer());
let workers = spawnWorker(module, memory, 0, kSequenceStartAddress); let workers =
spawnWorker(module, memory, kMemoryAddress, kSequenceStartAddress);
// Fire the workers off // Fire off the workers by writing the first element of the sequence to
for (let i = opcodeSize / 8 - 1; i >= 0; i--) { // memory. The byte order does not matter here, since all bytes need to be
memoryView[i] = memoryView[kSequenceStartAddress + i]; // updated before the first worker can do an update.
} memoryView.copyWithin(
kMemoryAddress, kSequenceStartAddress,
kSequenceStartAddress + numBytes);
waitForWorkers(workers); waitForWorkers(workers);

View File

@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
const kSequenceLength = 8192; const kSequenceLength = 8192;
const kNumberOfWorkers = 4; const kNumberOfWorkers = 4;
const kBitMask = kNumberOfWorkers - 1; const kBitMask = kNumberOfWorkers - 1;
const kMemoryAddress = 0;
const kSequenceStartAddress = 32; const kSequenceStartAddress = 32;
function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
@ -140,7 +141,8 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName,
function generateSequence(typedarray, start, count) { function generateSequence(typedarray, start, count) {
let end = count + start; let end = count + start;
for (let i = start; i < end; i++) { for (let i = start; i < end; i++) {
typedarray[i] = Math.floor(Math.random() * 256); // Avoid the value 255, which is used as initial value in memory.
typedarray[i] = Math.floor(Math.random() * 255);
} }
} }
@ -191,15 +193,23 @@ function testOpcode(opcode, opcodeSize) {
shared: true shared: true
}); });
let memoryView = new Uint8Array(memory.buffer); let memoryView = new Uint8Array(memory.buffer);
generateSequence(memoryView, kSequenceStartAddress, kSequenceLength * (opcodeSize / 8)); let numBytes = opcodeSize / 8;
generateSequence(
memoryView, kSequenceStartAddress, kSequenceLength * numBytes);
// Initialize the memory to a value which does not appear in the sequence.
memoryView.fill(255, kMemoryAddress, numBytes);
let module = new WebAssembly.Module(builder.toBuffer()); let module = new WebAssembly.Module(builder.toBuffer());
let workers = spawnWorker(module, memory, 0, kSequenceStartAddress); let workers =
spawnWorker(module, memory, kMemoryAddress, kSequenceStartAddress);
// Fire the workers off // Fire off the workers by writing the first element of the sequence to
for (let i = opcodeSize / 8 - 1; i >= 0; i--) { // memory. The byte order does not matter here, since all bytes need to be
memoryView[i] = memoryView[kSequenceStartAddress + i]; // updated before the first worker can do an update.
} memoryView.copyWithin(
kMemoryAddress, kSequenceStartAddress,
kSequenceStartAddress + numBytes);
waitForWorkers(workers); waitForWorkers(workers);