// 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. // // This test is a reproduction of a crash that happens when a TypedArray // backed by a SharedArrayBuffer is concurrently modified while sorting. // Segfaults would need a long time to trigger in normal builds, so this // reproduction is tailored to trigger on ASAN builds. On ASAN builds, // out-of-bounds accesses while sorting would result in an immediate failure. const lock = new Int32Array(new SharedArrayBuffer(4)); const kIterations = 5000; const kLength = 2000; const kStageIndex = 0; const kStageInit = 0; const kStageRunning = 1; const kStageDone = 2; Atomics.store(lock, kStageIndex, kStageInit); function WaitUntil(funcOfValue) { while (true) { const value = Atomics.load(lock, kStageIndex); if (funcOfValue(value)) break; } } const workerScript = ` onmessage = function([sab, lock]) { const i32a = new Int32Array(sab); Atomics.store(lock, ${kStageIndex}, ${kStageRunning}); for (let j = 1; j < ${kIterations}; ++j) { for (let i = 0; i < i32a.length; ++i) { i32a[i] = j; } } postMessage("done"); Atomics.store(lock, ${kStageIndex}, ${kStageDone}); };`; const worker = new Worker(workerScript, {type: 'string'}); const i32a = new Int32Array( new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * kLength) ); worker.postMessage([i32a.buffer, lock]); WaitUntil(value => value !== kStageInit); for (let i = 0; i < kIterations; ++i) { i32a.sort(); } WaitUntil(value => value === kStageDone); assertEquals(worker.getMessage(), "done");