summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength.js
blob: 51ed63f254f3e681807440d9c5b3e3c34b6d868a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0

function setup() {
  // Shared memory locations:
  //
  // 0: Lock
  // 1: Sleep
  // 2: Data
  // 3: Unused

  function worker(gsab) {
    var ta = new Int32Array(gsab);

    // Notify the main thread that the worker is ready.
    Atomics.store(ta, 0, 1);

    // Sleep to give the main thread time to execute and tier-up the loop.
    Atomics.wait(ta, 1, 0, 500);

    // Modify the memory read in the loop.
    Atomics.store(ta, 2, 1);

    // Sleep again to give the main thread time to execute the loop.
    Atomics.wait(ta, 1, 0, 100);

    // Grow the buffer. This modifies the loop condition.
    gsab.grow(16);
  }

  var gsab = new SharedArrayBuffer(12, {maxByteLength: 16});

  // Pass |gsab| to the mailbox.
  setSharedObject(gsab);

  // Start the worker.
  evalInWorker(`
    (${worker})(getSharedObject());
  `);

  // Wait until worker is ready.
  var ta = new Int32Array(gsab);
  while (Atomics.load(ta, 0) === 0);

  return gsab;
}

function testDataViewByteLength() {
  var gsab = setup();
  var ta = new Int32Array(gsab);
  var dv = new DataView(gsab);
  var r = 0;

  // |dv.byteLength| is a seq-cst load, so it must prevent reordering any other
  // loads, including unordered loads like |ta[2]|.
  while (dv.byteLength <= 12) {
    // |ta[2]| is an unordered load, so it's hoistable by default.
    r += ta[2];
  }

  // The memory location is first modified and then the buffer is grown, so we
  // must observe reads of the modified memory location before exiting the loop.
  assertEq(
    r > 0,
    true,
    "dv.byteLength acts as a memory barrier, so ta[2] can't be hoisted"
  );
}
testDataViewByteLength();