From a2ef686f86ce1a5c20f991c609a68ea442fcb988 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Fri, 19 Jun 2020 11:29:00 +0200 Subject: [PATCH] [wasm] Fix possible hang in compare-exchange tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Marja Hölttä Cr-Commit-Position: refs/heads/master@{#68429} --- test/mjsunit/wasm/compare-exchange-stress.js | 24 +++++++++++++------ .../mjsunit/wasm/compare-exchange64-stress.js | 24 +++++++++++++------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/test/mjsunit/wasm/compare-exchange-stress.js b/test/mjsunit/wasm/compare-exchange-stress.js index 050a15e380..0c894b19fb 100644 --- a/test/mjsunit/wasm/compare-exchange-stress.js +++ b/test/mjsunit/wasm/compare-exchange-stress.js @@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const kSequenceLength = 8192; const kNumberOfWorkers = 4; const kBitMask = kNumberOfWorkers - 1; +const kMemoryAddress = 0; const kSequenceStartAddress = 32; function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, @@ -135,7 +136,8 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, function generateSequence(typedarray, start, count) { let end = count + start; 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 }); 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 workers = spawnWorker(module, memory, 0, kSequenceStartAddress); + let workers = + spawnWorker(module, memory, kMemoryAddress, kSequenceStartAddress); - // Fire the workers off - for (let i = opcodeSize / 8 - 1; i >= 0; i--) { - memoryView[i] = memoryView[kSequenceStartAddress + i]; - } + // Fire off the workers by writing the first element of the sequence to + // memory. The byte order does not matter here, since all bytes need to be + // updated before the first worker can do an update. + memoryView.copyWithin( + kMemoryAddress, kSequenceStartAddress, + kSequenceStartAddress + numBytes); waitForWorkers(workers); diff --git a/test/mjsunit/wasm/compare-exchange64-stress.js b/test/mjsunit/wasm/compare-exchange64-stress.js index b2ffcf1475..75f186a54a 100644 --- a/test/mjsunit/wasm/compare-exchange64-stress.js +++ b/test/mjsunit/wasm/compare-exchange64-stress.js @@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const kSequenceLength = 8192; const kNumberOfWorkers = 4; const kBitMask = kNumberOfWorkers - 1; +const kMemoryAddress = 0; const kSequenceStartAddress = 32; function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, @@ -140,7 +141,8 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, function generateSequence(typedarray, start, count) { let end = count + start; 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 }); 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 workers = spawnWorker(module, memory, 0, kSequenceStartAddress); + let workers = + spawnWorker(module, memory, kMemoryAddress, kSequenceStartAddress); - // Fire the workers off - for (let i = opcodeSize / 8 - 1; i >= 0; i--) { - memoryView[i] = memoryView[kSequenceStartAddress + i]; - } + // Fire off the workers by writing the first element of the sequence to + // memory. The byte order does not matter here, since all bytes need to be + // updated before the first worker can do an update. + memoryView.copyWithin( + kMemoryAddress, kSequenceStartAddress, + kSequenceStartAddress + numBytes); waitForWorkers(workers);