summaryrefslogtreecommitdiff
path: root/test/v8-updates/test-linux-perf.js
blob: 01ebce0ae5af9a084c43560e574844a80cb77906 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
'use strict';

// This test verifies that JavaScript functions are being correctly sampled by
// Linux perf. The test runs a JavaScript script, sampling the execution with
// Linux perf. It then uses `perf script` to generate a human-readable output,
// and uses regular expressions to find samples of the functions defined in
// `fixtures/linux-perf.js`.

// NOTE (mmarchini): this test is meant to run only on Linux machines with Linux
// perf installed. It will skip if those criteria are not met.

const common = require('../common');
if (!common.hasCrypto)
  common.skip('missing crypto');

const assert = require('assert');
const { spawnSync } = require('child_process');
const fixtures = require('../common/fixtures');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();

if (process.config.variables.node_shared)
  common.skip("can't test Linux perf with shared libraries yet");

if (!common.isLinux)
  common.skip('only testing Linux for now');

const frequency = 99;

const repeat = 5;

// Expected number of samples we'll capture per repeat
const sampleCount = 10;
const sleepTime = sampleCount * (1.0 / frequency);

const perfFlags = [
  'record',
  `-F${frequency}`,
  '-g',
];

const nodeCommonFlags = [
  '--perf-basic-prof',
  '--interpreted-frames-native-stack',
  '--no-turbo-inlining',  // Otherwise simple functions might get inlined.
];

const perfInterpretedFramesArgs = [
  ...perfFlags,
  '--',
  process.execPath,
  ...nodeCommonFlags,
  '--no-opt',
  fixtures.path('linux-perf.js'),
  `${sleepTime}`,
  `${repeat}`,
];

const perfCompiledFramesArgs = [
  ...perfFlags,
  '--',
  process.execPath,
  ...nodeCommonFlags,
  '--always-opt',
  fixtures.path('linux-perf.js'),
  `${sleepTime}`,
  `${repeat}`,
];

const perfArgsList = [
  perfInterpretedFramesArgs, perfCompiledFramesArgs
];

const perfScriptArgs = [
  'script',
];

const options = {
  cwd: tmpdir.path,
  encoding: 'utf-8',
};

let output = '';

for (const perfArgs of perfArgsList) {
  const perf = spawnSync('perf', perfArgs, options);
  assert.ifError(perf.error);
  if (perf.status !== 0)
    throw new Error(`Failed to execute 'perf': ${perf.stderr}`);

  const perfScript = spawnSync('perf', perfScriptArgs, options);
  assert.ifError(perfScript.error);
  if (perfScript.status !== 0)
    throw new Error(`Failed to execute perf script: ${perfScript.stderr}`);

  output += perfScript.stdout;
}

const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;
const compiledFunctionOneRe = /LazyCompile:\*functionOne/;
const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;
const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;


assert.ok(output.match(interpretedFunctionOneRe),
          "Couldn't find interpreted functionOne()");
assert.ok(output.match(compiledFunctionOneRe),
          "Couldn't find compiled functionOne()");
assert.ok(output.match(interpretedFunctionTwoRe),
          "Couldn't find interpreted functionTwo()");
assert.ok(output.match(compiledFunctionTwoRe),
          "Couldn't find compiled functionTwo");