[tools][profile] Add support for maglev optimisation markers
Drive-by-fix: - Rename baseline to sparkplug for consistency - Add request timeouts for the local symbol server - Add script to start a local symbol server - Fix -h/--help support for linux-perf-chrome-renderer-cmd.sh Change-Id: I4c2fc3595d672871f20fc5c4065ba45e801a1111 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3769699 Auto-Submit: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/main@{#81992}
This commit is contained in:
parent
4b5ac613f8
commit
64aeabbc95
@ -39,7 +39,7 @@
|
|||||||
// Resources: test/mjsunit/tools/tickprocessor-test.log
|
// Resources: test/mjsunit/tools/tickprocessor-test.log
|
||||||
// Resources: test/mjsunit/tools/tickprocessor-test.log.symbols.json
|
// Resources: test/mjsunit/tools/tickprocessor-test.log.symbols.json
|
||||||
// Resources: test/mjsunit/tools/tickprocessor-test.only-summary
|
// Resources: test/mjsunit/tools/tickprocessor-test.only-summary
|
||||||
// Resources: test/mjsunit/tools/tickprocessor-test.separate-baseline-handlers
|
// Resources: test/mjsunit/tools/tickprocessor-test.separate-sparkplug-handlers
|
||||||
// Resources: test/mjsunit/tools/tickprocessor-test.separate-bytecodes
|
// Resources: test/mjsunit/tools/tickprocessor-test.separate-bytecodes
|
||||||
// Resources: test/mjsunit/tools/tickprocessor-test.separate-ic
|
// Resources: test/mjsunit/tools/tickprocessor-test.separate-ic
|
||||||
|
|
||||||
@ -417,9 +417,9 @@ await (async function testProcessing() {
|
|||||||
'SeparateBytecodes': [
|
'SeparateBytecodes': [
|
||||||
'tickprocessor-test.log', 'tickprocessor-test.separate-bytecodes',
|
'tickprocessor-test.log', 'tickprocessor-test.separate-bytecodes',
|
||||||
['--separate-ic=false', '--separate-bytecodes']],
|
['--separate-ic=false', '--separate-bytecodes']],
|
||||||
'SeparateBaselineHandlers': [
|
'SeparateSparkplugHandlers': [
|
||||||
'tickprocessor-test.log', 'tickprocessor-test.separate-baseline-handlers',
|
'tickprocessor-test.log', 'tickprocessor-test.separate-sparkplug-handlers',
|
||||||
['--separate-ic=false', '--separate-baseline-handlers']],
|
['--separate-ic=false', '--separate-sparkplug-handlers']],
|
||||||
'SeparateIc': [
|
'SeparateIc': [
|
||||||
'tickprocessor-test.log', 'tickprocessor-test.separate-ic',
|
'tickprocessor-test.log', 'tickprocessor-test.separate-ic',
|
||||||
['--separate-ic=true']],
|
['--separate-ic=true']],
|
||||||
@ -479,4 +479,4 @@ async function testEndToEnd(dir, sourceFile, ignoredRefOutput, params) {
|
|||||||
const printMonitor = new PrintMonitor(dir + ignoredRefOutput);
|
const printMonitor = new PrintMonitor(dir + ignoredRefOutput);
|
||||||
await tickProcessor.processLogFileInTest(tmpLogFile);
|
await tickProcessor.processLogFileInTest(tmpLogFile);
|
||||||
tickProcessor.printStatistics();
|
tickProcessor.printStatistics();
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1185,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
|
|||||||
let parts = location.pathname.split("/").slice(0, -1);
|
let parts = location.pathname.split("/").slice(0, -1);
|
||||||
url = location.origin + parts.join('/') + '/' + url;
|
url = location.origin + parts.join('/') + '/' + url;
|
||||||
}
|
}
|
||||||
let response = await fetch(url);
|
let response = await fetch(url, {timeout: 20});
|
||||||
if (!response.ok) return false;
|
if (!response.ok) return false;
|
||||||
let filename = url.split('/');
|
let filename = url.split('/');
|
||||||
filename = filename[filename.length - 1];
|
filename = filename[filename.length - 1];
|
||||||
|
@ -186,15 +186,16 @@ export class Script {
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let sourceMapPayload;
|
let sourceMapPayload;
|
||||||
|
const options = { timeout: 15 };
|
||||||
try {
|
try {
|
||||||
sourceMapPayload = await fetch(sourceMapURL);
|
sourceMapPayload = await fetch(sourceMapURL, options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof TypeError && sourceMapFetchPrefix) {
|
if (e instanceof TypeError && sourceMapFetchPrefix) {
|
||||||
// Try again with fetch prefix.
|
// Try again with fetch prefix.
|
||||||
// TODO(leszeks): Remove the retry once the prefix is
|
// TODO(leszeks): Remove the retry once the prefix is
|
||||||
// configurable.
|
// configurable.
|
||||||
sourceMapPayload =
|
sourceMapPayload =
|
||||||
await fetch(sourceMapFetchPrefix + sourceMapURL);
|
await fetch(sourceMapFetchPrefix + sourceMapURL, options);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@ -350,7 +351,8 @@ export class Profile {
|
|||||||
static CodeState = {
|
static CodeState = {
|
||||||
COMPILED: 0,
|
COMPILED: 0,
|
||||||
IGNITION: 1,
|
IGNITION: 1,
|
||||||
BASELINE: 2,
|
SPARKPLUG: 2,
|
||||||
|
MAGLEV: 4,
|
||||||
TURBOFAN: 5,
|
TURBOFAN: 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +361,7 @@ export class Profile {
|
|||||||
GC: 1,
|
GC: 1,
|
||||||
PARSER: 2,
|
PARSER: 2,
|
||||||
BYTECODE_COMPILER: 3,
|
BYTECODE_COMPILER: 3,
|
||||||
// TODO(cbruni): add BASELINE_COMPILER
|
// TODO(cbruni): add SPARKPLUG_COMPILER
|
||||||
COMPILER: 4,
|
COMPILER: 4,
|
||||||
OTHER: 5,
|
OTHER: 5,
|
||||||
EXTERNAL: 6,
|
EXTERNAL: 6,
|
||||||
@ -381,7 +383,9 @@ export class Profile {
|
|||||||
case '~':
|
case '~':
|
||||||
return this.CodeState.IGNITION;
|
return this.CodeState.IGNITION;
|
||||||
case '^':
|
case '^':
|
||||||
return this.CodeState.BASELINE;
|
return this.CodeState.SPARKPLUG;
|
||||||
|
case '+':
|
||||||
|
return this.CodeState.MAGLEV;
|
||||||
case '*':
|
case '*':
|
||||||
return this.CodeState.TURBOFAN;
|
return this.CodeState.TURBOFAN;
|
||||||
}
|
}
|
||||||
@ -393,8 +397,10 @@ export class Profile {
|
|||||||
return "Builtin";
|
return "Builtin";
|
||||||
} else if (state === this.CodeState.IGNITION) {
|
} else if (state === this.CodeState.IGNITION) {
|
||||||
return "Unopt";
|
return "Unopt";
|
||||||
} else if (state === this.CodeState.BASELINE) {
|
} else if (state === this.CodeState.SPARKPLUG) {
|
||||||
return "Baseline";
|
return "Sparkplug";
|
||||||
|
} else if (state === this.CodeState.MAGLEV) {
|
||||||
|
return "Maglev";
|
||||||
} else if (state === this.CodeState.TURBOFAN) {
|
} else if (state === this.CodeState.TURBOFAN) {
|
||||||
return "Opt";
|
return "Opt";
|
||||||
}
|
}
|
||||||
@ -425,7 +431,7 @@ export class Profile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever the specified operation has failed finding a function
|
* Called whenever the specified operation has failed finding a function
|
||||||
* containing the specified address. Should be overriden by subclasses.
|
* containing the specified address. Should be overridden by subclasses.
|
||||||
* See the Profile.Operation enum for the list of
|
* See the Profile.Operation enum for the list of
|
||||||
* possible operations.
|
* possible operations.
|
||||||
*
|
*
|
||||||
|
@ -8,7 +8,7 @@ PERF_DATA_PREFIX="chrome_renderer"
|
|||||||
RENDERER_ID="0"
|
RENDERER_ID="0"
|
||||||
for i in "$@"; do
|
for i in "$@"; do
|
||||||
case $i in
|
case $i in
|
||||||
--help)
|
-h|--help)
|
||||||
echo "Usage: path/to/chrome --renderer-cmd-prefix='$0 [OPTION]' [CHROME OPTIONS]"
|
echo "Usage: path/to/chrome --renderer-cmd-prefix='$0 [OPTION]' [CHROME OPTIONS]"
|
||||||
echo "This script is mostly used in conjuction with linux_perf.py to run linux-perf"
|
echo "This script is mostly used in conjuction with linux_perf.py to run linux-perf"
|
||||||
echo "for each renderer process."
|
echo "for each renderer process."
|
||||||
|
@ -13,7 +13,7 @@ found in the LICENSE file. -->
|
|||||||
<link rel="modulepreload" href="./view/helper.mjs" >
|
<link rel="modulepreload" href="./view/helper.mjs" >
|
||||||
<link rel="preload" href="../js/log-file-reader-template.html" as="fetch" crossorigin="anonymous">
|
<link rel="preload" href="../js/log-file-reader-template.html" as="fetch" crossorigin="anonymous">
|
||||||
<script type="module">
|
<script type="module">
|
||||||
// Force instatiating the log-reader before anything else.
|
// Force instantiating the log-reader before anything else.
|
||||||
import "./view/log-file-reader.mjs";
|
import "./view/log-file-reader.mjs";
|
||||||
// Delay loading of the main App
|
// Delay loading of the main App
|
||||||
(async function() {
|
(async function() {
|
||||||
@ -173,6 +173,12 @@ found in the LICENSE file. -->
|
|||||||
<dd>Log ticks from the sampling profiler.</dd>
|
<dd>Log ticks from the sampling profiler.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<h3>Local Symbol Server</h3>
|
||||||
|
To get detailed C++ symbols for local binaries you can host the
|
||||||
|
system-analyzer locally using <code>tools/system-analyzer/local-server.sh</code>.
|
||||||
|
You can then access the analyzer on
|
||||||
|
<a href="http://localhost:8000/system-analyzer/index.html">localhost</a>.
|
||||||
|
|
||||||
<h3>Keyboard Shortcuts for Navigation</h3>
|
<h3>Keyboard Shortcuts for Navigation</h3>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><kbd>A</kbd></dt>
|
<dt><kbd>A</kbd></dt>
|
||||||
|
55
tools/system-analyzer/local-server.sh
Executable file
55
tools/system-analyzer/local-server.sh
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright 2022 the V8 project authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style license that can be
|
||||||
|
# found in the LICENSE file.
|
||||||
|
|
||||||
|
for i in "$@"; do
|
||||||
|
case $i in
|
||||||
|
-h|--help)
|
||||||
|
echo "Starts a local server for V8's system anaylizer"
|
||||||
|
echo "It's accessible http://localhost:8000"
|
||||||
|
echo "Note: The server also exposes local binary information via 'nm'"
|
||||||
|
exit;
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option: $i"
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! command -v ws &> /dev/null
|
||||||
|
then
|
||||||
|
echo "'ws' not found!"
|
||||||
|
echo "Please install local-web-server:"
|
||||||
|
echo "npm install local-web-server"
|
||||||
|
echo ""
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOOLS_DIR=`readlink "$0"` || TOOLS_DIR="$0";
|
||||||
|
TOOLS_DIR=`dirname "$TOOLS_DIR"`;
|
||||||
|
cd "$TOOLS_DIR/.."
|
||||||
|
TOOLS_DIR=`pwd -P`
|
||||||
|
|
||||||
|
if lsof -t -i TCP:8000; then
|
||||||
|
echo "locahost:8000 is already in use. You can kill it with:"
|
||||||
|
echo "lsof -t -i TCP:8000 | xargs kill"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Starting local symbol server"
|
||||||
|
ws --stack $TOOLS_DIR/system-analyzer/lws-middleware.js lws-static lws-index & PID=$!
|
||||||
|
|
||||||
|
# Kill server after 1h
|
||||||
|
for i in `seq 3600`; do
|
||||||
|
if ps -p $PID > /dev/null 2>&1; then
|
||||||
|
sleep 1;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ps -p $PID > /dev/null 2>&1; then
|
||||||
|
echo "Automatically killing the local server after timeout"
|
||||||
|
kill $PID
|
||||||
|
fi
|
@ -327,9 +327,10 @@ export class Processor extends LogReader {
|
|||||||
const url = new URL('http://localhost:8000/v8/info/platform')
|
const url = new URL('http://localhost:8000/v8/info/platform')
|
||||||
let platform = 'linux'
|
let platform = 'linux'
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url, {timeout: 1});
|
||||||
platform = await response.text();
|
platform = await response.text();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.warn(`Local symbol server is not running on ${url}`);
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
if (platform === 'darwin') {
|
if (platform === 'darwin') {
|
||||||
|
@ -36,12 +36,12 @@ class V8Profile extends Profile {
|
|||||||
static IC_RE =
|
static IC_RE =
|
||||||
/^(LoadGlobalIC: )|(Handler: )|(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/;
|
/^(LoadGlobalIC: )|(Handler: )|(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/;
|
||||||
static BYTECODES_RE = /^(BytecodeHandler: )/;
|
static BYTECODES_RE = /^(BytecodeHandler: )/;
|
||||||
static BASELINE_HANDLERS_RE = /^(Builtin: .*Baseline.*)/;
|
static SPARKPLUG_HANDLERS_RE = /^(Builtin: .*Baseline.*)/;
|
||||||
static BUILTINS_RE = /^(Builtin: )/;
|
static BUILTINS_RE = /^(Builtin: )/;
|
||||||
static STUBS_RE = /^(Stub: )/;
|
static STUBS_RE = /^(Stub: )/;
|
||||||
|
|
||||||
constructor(separateIc, separateBytecodes, separateBuiltins, separateStubs,
|
constructor(separateIc, separateBytecodes, separateBuiltins, separateStubs,
|
||||||
separateBaselineHandlers) {
|
separateSparkplugHandlers) {
|
||||||
super();
|
super();
|
||||||
const regexps = [];
|
const regexps = [];
|
||||||
if (!separateIc) regexps.push(V8Profile.IC_RE);
|
if (!separateIc) regexps.push(V8Profile.IC_RE);
|
||||||
@ -137,7 +137,7 @@ class CppEntriesProvider {
|
|||||||
let response;
|
let response;
|
||||||
let json;
|
let json;
|
||||||
try {
|
try {
|
||||||
response = await fetch(url);
|
response = await fetch(url, { timeout: 20 });
|
||||||
if (response.status == 404) {
|
if (response.status == 404) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Local symbol server returned 404: ${await response.text()}`);
|
`Local symbol server returned 404: ${await response.text()}`);
|
||||||
@ -388,8 +388,8 @@ export class ArgumentsProcessor extends BaseArgumentsProcessor {
|
|||||||
'Separate Builtin entries'],
|
'Separate Builtin entries'],
|
||||||
'--separate-stubs': ['separateStubs', parseBool,
|
'--separate-stubs': ['separateStubs', parseBool,
|
||||||
'Separate Stub entries'],
|
'Separate Stub entries'],
|
||||||
'--separate-baseline-handlers': ['separateBaselineHandlers', parseBool,
|
'--separate-sparkplug-handlers': ['separateSparkplugHandlers', parseBool,
|
||||||
'Separate Baseline Handler entries'],
|
'Separate Sparkplug Handler entries'],
|
||||||
'--linux': ['platform', 'linux',
|
'--linux': ['platform', 'linux',
|
||||||
'Specify that we are running on *nix platform'],
|
'Specify that we are running on *nix platform'],
|
||||||
'--windows': ['platform', 'windows',
|
'--windows': ['platform', 'windows',
|
||||||
@ -441,7 +441,7 @@ export class ArgumentsProcessor extends BaseArgumentsProcessor {
|
|||||||
separateBytecodes: false,
|
separateBytecodes: false,
|
||||||
separateBuiltins: true,
|
separateBuiltins: true,
|
||||||
separateStubs: true,
|
separateStubs: true,
|
||||||
separateBaselineHandlers: false,
|
separateSparkplugHandlers: false,
|
||||||
preprocessJson: null,
|
preprocessJson: null,
|
||||||
sourceMap: null,
|
sourceMap: null,
|
||||||
targetRootFS: '',
|
targetRootFS: '',
|
||||||
@ -478,7 +478,7 @@ export class TickProcessor extends LogReader {
|
|||||||
params.separateBytecodes,
|
params.separateBytecodes,
|
||||||
params.separateBuiltins,
|
params.separateBuiltins,
|
||||||
params.separateStubs,
|
params.separateStubs,
|
||||||
params.separateBaselineHandlers,
|
params.separateSparkplugHandlers,
|
||||||
params.callGraphSize,
|
params.callGraphSize,
|
||||||
params.ignoreUnknown,
|
params.ignoreUnknown,
|
||||||
params.stateFilter,
|
params.stateFilter,
|
||||||
@ -498,7 +498,7 @@ export class TickProcessor extends LogReader {
|
|||||||
separateBytecodes,
|
separateBytecodes,
|
||||||
separateBuiltins,
|
separateBuiltins,
|
||||||
separateStubs,
|
separateStubs,
|
||||||
separateBaselineHandlers,
|
separateSparkplugHandlers,
|
||||||
callGraphSize,
|
callGraphSize,
|
||||||
ignoreUnknown,
|
ignoreUnknown,
|
||||||
stateFilter,
|
stateFilter,
|
||||||
@ -632,7 +632,7 @@ export class TickProcessor extends LogReader {
|
|||||||
this.profile_ = new JsonProfile();
|
this.profile_ = new JsonProfile();
|
||||||
} else {
|
} else {
|
||||||
this.profile_ = new V8Profile(separateIc, separateBytecodes,
|
this.profile_ = new V8Profile(separateIc, separateBytecodes,
|
||||||
separateBuiltins, separateStubs, separateBaselineHandlers);
|
separateBuiltins, separateStubs, separateSparkplugHandlers);
|
||||||
}
|
}
|
||||||
this.codeTypes_ = {};
|
this.codeTypes_ = {};
|
||||||
// Count each tick as a time unit.
|
// Count each tick as a time unit.
|
||||||
@ -660,7 +660,7 @@ export class TickProcessor extends LogReader {
|
|||||||
GC: 1,
|
GC: 1,
|
||||||
PARSER: 2,
|
PARSER: 2,
|
||||||
BYTECODE_COMPILER: 3,
|
BYTECODE_COMPILER: 3,
|
||||||
// TODO(cbruni): add BASELINE_COMPILER
|
// TODO(cbruni): add SPARKPLUG_COMPILER
|
||||||
COMPILER: 4,
|
COMPILER: 4,
|
||||||
OTHER: 5,
|
OTHER: 5,
|
||||||
EXTERNAL: 6,
|
EXTERNAL: 6,
|
||||||
|
Loading…
Reference in New Issue
Block a user