test,v8: skip less and stabilize test-linux-perf.js
Co-authored-by: Matheus Marchini <mat@mmarchini.me> PR-URL: https://github.com/nodejs/node/pull/27364 Refs: https://github.com/nodejs/build/issues/1774 Reviewed-By: Matheus Marchini <mat@mmarchini.me> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
parent
a8277ddb55
commit
546d6cdd9e
27
test/fixtures/linux-perf.js
vendored
27
test/fixtures/linux-perf.js
vendored
@ -1,26 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const crypto = require('crypto');
|
const { spawnSync } = require("child_process");
|
||||||
|
const sleepTime = new Number(process.argv[2] || "0.1");
|
||||||
|
const repeat = new Number(process.argv[3]) || 5;
|
||||||
|
|
||||||
// Functions should be complex enough for V8 to run them a few times before
|
function functionOne() {
|
||||||
// compiling, but not complex enough to always stay in interpreted mode. They
|
functionTwo();
|
||||||
// should also take some time to run, otherwise Linux perf might miss them
|
|
||||||
// entirely even when sampling at a high frequency.
|
|
||||||
function functionOne(i) {
|
|
||||||
for (let j=i; j > 0; j--) {
|
|
||||||
crypto.createHash('md5').update(functionTwo(i, j)).digest("hex");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function functionTwo(x, y) {
|
function functionTwo() {
|
||||||
let data = ((((x * y) + (x / y)) * y) ** (x + 1)).toString();
|
spawnSync('sleep', [`${sleepTime}`]);
|
||||||
if (x % 2 == 0) {
|
|
||||||
return crypto.createHash('md5').update(data.repeat((x % 100) + 1)).digest("hex");
|
|
||||||
} else {
|
|
||||||
return crypto.createHash('md5').update(data.repeat((y % 100) + 1)).digest("hex");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < 1000; i++) {
|
for (let i = 0; i < repeat; i++) {
|
||||||
functionOne(i);
|
functionOne();
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,53 @@ tmpdir.refresh();
|
|||||||
if (process.config.variables.node_shared)
|
if (process.config.variables.node_shared)
|
||||||
common.skip("can't test Linux perf with shared libraries yet");
|
common.skip("can't test Linux perf with shared libraries yet");
|
||||||
|
|
||||||
const perfArgs = [
|
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',
|
'record',
|
||||||
'-F999',
|
`-F${frequency}`,
|
||||||
'-g',
|
'-g',
|
||||||
'--',
|
];
|
||||||
process.execPath,
|
|
||||||
|
const nodeCommonFlags = [
|
||||||
'--perf-basic-prof',
|
'--perf-basic-prof',
|
||||||
'--interpreted-frames-native-stack',
|
'--interpreted-frames-native-stack',
|
||||||
'--no-turbo-inlining', // Otherwise simple functions might get inlined.
|
'--no-turbo-inlining', // Otherwise simple functions might get inlined.
|
||||||
|
];
|
||||||
|
|
||||||
|
const perfInterpretedFramesArgs = [
|
||||||
|
...perfFlags,
|
||||||
|
'--',
|
||||||
|
process.execPath,
|
||||||
|
...nodeCommonFlags,
|
||||||
|
'--no-opt',
|
||||||
fixtures.path('linux-perf.js'),
|
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 = [
|
const perfScriptArgs = [
|
||||||
@ -43,25 +80,20 @@ const options = {
|
|||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!common.isLinux)
|
let output = '';
|
||||||
common.skip('only testing Linux for now');
|
|
||||||
|
|
||||||
const perf = spawnSync('perf', perfArgs, options);
|
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}`);
|
||||||
|
|
||||||
if (perf.error && perf.error.errno === 'ENOENT')
|
const perfScript = spawnSync('perf', perfScriptArgs, options);
|
||||||
common.skip('perf not found on system');
|
assert.ifError(perfScript.error);
|
||||||
|
if (perfScript.status !== 0)
|
||||||
|
throw new Error(`Failed to execute perf script: ${perfScript.stderr}`);
|
||||||
|
|
||||||
if (perf.status !== 0) {
|
output += perfScript.stdout;
|
||||||
common.skip(`Failed to execute perf: ${perf.stderr}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const perfScript = spawnSync('perf', perfScriptArgs, options);
|
|
||||||
|
|
||||||
if (perf.error)
|
|
||||||
common.skip(`perf script aborted: ${perf.error.errno}`);
|
|
||||||
|
|
||||||
if (perfScript.status !== 0) {
|
|
||||||
common.skip(`Failed to execute perf script: ${perfScript.stderr}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;
|
const interpretedFunctionOneRe = /InterpretedFunction:functionOne/;
|
||||||
@ -69,7 +101,6 @@ const compiledFunctionOneRe = /LazyCompile:\*functionOne/;
|
|||||||
const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;
|
const interpretedFunctionTwoRe = /InterpretedFunction:functionTwo/;
|
||||||
const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;
|
const compiledFunctionTwoRe = /LazyCompile:\*functionTwo/;
|
||||||
|
|
||||||
const output = perfScript.stdout;
|
|
||||||
|
|
||||||
assert.ok(output.match(interpretedFunctionOneRe),
|
assert.ok(output.match(interpretedFunctionOneRe),
|
||||||
"Couldn't find interpreted functionOne()");
|
"Couldn't find interpreted functionOne()");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user