mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
b5f1564880
Refs: https://chromium-review.googlesource.com/c/v8/v8/+/3610431 PR-URL: https://github.com/nodejs/node/pull/44741 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
116 lines
3.1 KiB
JavaScript
116 lines
3.1 KiB
JavaScript
'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-turbofan',
|
|
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 = /~functionOne/;
|
|
const compiledFunctionOneRe = /\*functionOne/;
|
|
const interpretedFunctionTwoRe = /~functionTwo/;
|
|
const compiledFunctionTwoRe = /\*functionTwo/;
|
|
|
|
function makeAssertMessage(message) {
|
|
return message + '\nPerf output:\n\n' + output;
|
|
}
|
|
|
|
assert.ok(output.match(interpretedFunctionOneRe),
|
|
makeAssertMessage("Couldn't find interpreted functionOne()"));
|
|
assert.ok(output.match(compiledFunctionOneRe),
|
|
makeAssertMessage("Couldn't find compiled functionOne()"));
|
|
assert.ok(output.match(interpretedFunctionTwoRe),
|
|
makeAssertMessage("Couldn't find interpreted functionTwo()"));
|
|
assert.ok(output.match(compiledFunctionTwoRe),
|
|
makeAssertMessage("Couldn't find compiled functionTwo"));
|