summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/parser/stencil-eager-delazify.js
blob: d638b16e78275592145de06c92a9a721c2852727 (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
69
70
71
72
73
74
75
// |jit-test| skip-if: helperThreadCount() === 0 || isLcovEnabled()

// Extra GCs can empty the StencilCache to reclaim memory. This lines
// re-configure the gc-zeal setting to prevent this from happening in this test
// case which waits for the cache to contain some entry.
if ('gczeal' in this)
  gczeal(0);

let u = 0;

// At each function, create `width` inner functions.
let width = 2;
// Depth of inner functions.
let depth = 4;
// Number of additional parser & delazification workload running concurrently
// with the one we are attempting to measure, such that we can see differences
// in the report of `isInStencilCache`.
let load = 14;

// Return the number of function generated by a to `depthFirstExec` given the
// same parameters.
function count(w, d) {
  return (Math.pow(w, d + 1) - 1) / (w - 1);
}

// Generate a source code with a large number of inner functions, such that
// eager delazification can be observe while running JS code concurrently.
function depthFirstExec(indent, name, w, d) {
  let fun = `${indent}function ${name} (arg) {\n`;
  let inner = "";
  let val = `arg + isInStencilCache(${name})`;
  if (d > 0) {
    for (let i = 0; i < w; i++) {
      inner += depthFirstExec(`${indent}  `, `${name}_${i}`, w, d - 1);
      val = `${name}_${i}(${val})`;
    }
  }
  fun += inner;
  fun += `${indent}  return ${u} + ${val} - ${u};\n`;
  fun += `${indent}}\n`;
  u += 1;
  return fun;
};

const options = {
  fileName: "depthFirstExec.js",
  lineNumber: 1,
  eagerDelazificationStrategy: "ConcurrentDepthFirst",
};
let script = depthFirstExec("", "raceMe", width, depth);

let jobs = [];
for (let i = 0; i < load; i++) {
  // Spin up extra compilation workload...
  jobs.push(offThreadCompileToStencil(script, options));
}

const stencil = finishOffThreadStencil(jobs[0]);
evalStencil(stencil, options);

waitForStencilCache(raceMe);
let start = raceMe(0);
let mid = raceMe(0);
let end = raceMe(0);

// The garbage collector should clear the cache and suppress all delazification
// tasks.
gc();
let afterGc = raceMe(0);

assertEq(1 <= start, true);
assertEq(start <= mid, true);
assertEq(mid <= end, true);
assertEq(end <= count(width, depth), true);
assertEq(afterGc, 0);