[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:
Camillo Bruni 2022-07-19 15:11:01 +02:00 committed by V8 LUCI CQ
parent 4b5ac613f8
commit 64aeabbc95
9 changed files with 95 additions and 27 deletions

View File

@ -39,7 +39,7 @@
// Resources: test/mjsunit/tools/tickprocessor-test.log
// Resources: test/mjsunit/tools/tickprocessor-test.log.symbols.json
// 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-ic
@ -417,9 +417,9 @@ await (async function testProcessing() {
'SeparateBytecodes': [
'tickprocessor-test.log', 'tickprocessor-test.separate-bytecodes',
['--separate-ic=false', '--separate-bytecodes']],
'SeparateBaselineHandlers': [
'tickprocessor-test.log', 'tickprocessor-test.separate-baseline-handlers',
['--separate-ic=false', '--separate-baseline-handlers']],
'SeparateSparkplugHandlers': [
'tickprocessor-test.log', 'tickprocessor-test.separate-sparkplug-handlers',
['--separate-ic=false', '--separate-sparkplug-handlers']],
'SeparateIc': [
'tickprocessor-test.log', 'tickprocessor-test.separate-ic',
['--separate-ic=true']],

View File

@ -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);
url = location.origin + parts.join('/') + '/' + url;
}
let response = await fetch(url);
let response = await fetch(url, {timeout: 20});
if (!response.ok) return false;
let filename = url.split('/');
filename = filename[filename.length - 1];

View File

@ -186,15 +186,16 @@ export class Script {
(async () => {
try {
let sourceMapPayload;
const options = { timeout: 15 };
try {
sourceMapPayload = await fetch(sourceMapURL);
sourceMapPayload = await fetch(sourceMapURL, options);
} catch (e) {
if (e instanceof TypeError && sourceMapFetchPrefix) {
// Try again with fetch prefix.
// TODO(leszeks): Remove the retry once the prefix is
// configurable.
sourceMapPayload =
await fetch(sourceMapFetchPrefix + sourceMapURL);
await fetch(sourceMapFetchPrefix + sourceMapURL, options);
} else {
throw e;
}
@ -350,7 +351,8 @@ export class Profile {
static CodeState = {
COMPILED: 0,
IGNITION: 1,
BASELINE: 2,
SPARKPLUG: 2,
MAGLEV: 4,
TURBOFAN: 5,
}
@ -359,7 +361,7 @@ export class Profile {
GC: 1,
PARSER: 2,
BYTECODE_COMPILER: 3,
// TODO(cbruni): add BASELINE_COMPILER
// TODO(cbruni): add SPARKPLUG_COMPILER
COMPILER: 4,
OTHER: 5,
EXTERNAL: 6,
@ -381,7 +383,9 @@ export class Profile {
case '~':
return this.CodeState.IGNITION;
case '^':
return this.CodeState.BASELINE;
return this.CodeState.SPARKPLUG;
case '+':
return this.CodeState.MAGLEV;
case '*':
return this.CodeState.TURBOFAN;
}
@ -393,8 +397,10 @@ export class Profile {
return "Builtin";
} else if (state === this.CodeState.IGNITION) {
return "Unopt";
} else if (state === this.CodeState.BASELINE) {
return "Baseline";
} else if (state === this.CodeState.SPARKPLUG) {
return "Sparkplug";
} else if (state === this.CodeState.MAGLEV) {
return "Maglev";
} else if (state === this.CodeState.TURBOFAN) {
return "Opt";
}
@ -425,7 +431,7 @@ export class Profile {
/**
* 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
* possible operations.
*

View File

@ -8,7 +8,7 @@ PERF_DATA_PREFIX="chrome_renderer"
RENDERER_ID="0"
for i in "$@"; do
case $i in
--help)
-h|--help)
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 "for each renderer process."

View File

@ -13,7 +13,7 @@ found in the LICENSE file. -->
<link rel="modulepreload" href="./view/helper.mjs" >
<link rel="preload" href="../js/log-file-reader-template.html" as="fetch" crossorigin="anonymous">
<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";
// Delay loading of the main App
(async function() {
@ -173,6 +173,12 @@ found in the LICENSE file. -->
<dd>Log ticks from the sampling profiler.</dd>
</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>
<dl>
<dt><kbd>A</kbd></dt>

View 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

View File

@ -327,9 +327,10 @@ export class Processor extends LogReader {
const url = new URL('http://localhost:8000/v8/info/platform')
let platform = 'linux'
try {
const response = await fetch(url);
const response = await fetch(url, {timeout: 1});
platform = await response.text();
} catch (e) {
console.warn(`Local symbol server is not running on ${url}`);
console.warn(e);
}
if (platform === 'darwin') {

View File

@ -36,12 +36,12 @@ class V8Profile extends Profile {
static IC_RE =
/^(LoadGlobalIC: )|(Handler: )|(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/;
static BYTECODES_RE = /^(BytecodeHandler: )/;
static BASELINE_HANDLERS_RE = /^(Builtin: .*Baseline.*)/;
static SPARKPLUG_HANDLERS_RE = /^(Builtin: .*Baseline.*)/;
static BUILTINS_RE = /^(Builtin: )/;
static STUBS_RE = /^(Stub: )/;
constructor(separateIc, separateBytecodes, separateBuiltins, separateStubs,
separateBaselineHandlers) {
separateSparkplugHandlers) {
super();
const regexps = [];
if (!separateIc) regexps.push(V8Profile.IC_RE);
@ -137,7 +137,7 @@ class CppEntriesProvider {
let response;
let json;
try {
response = await fetch(url);
response = await fetch(url, { timeout: 20 });
if (response.status == 404) {
throw new Error(
`Local symbol server returned 404: ${await response.text()}`);
@ -388,8 +388,8 @@ export class ArgumentsProcessor extends BaseArgumentsProcessor {
'Separate Builtin entries'],
'--separate-stubs': ['separateStubs', parseBool,
'Separate Stub entries'],
'--separate-baseline-handlers': ['separateBaselineHandlers', parseBool,
'Separate Baseline Handler entries'],
'--separate-sparkplug-handlers': ['separateSparkplugHandlers', parseBool,
'Separate Sparkplug Handler entries'],
'--linux': ['platform', 'linux',
'Specify that we are running on *nix platform'],
'--windows': ['platform', 'windows',
@ -441,7 +441,7 @@ export class ArgumentsProcessor extends BaseArgumentsProcessor {
separateBytecodes: false,
separateBuiltins: true,
separateStubs: true,
separateBaselineHandlers: false,
separateSparkplugHandlers: false,
preprocessJson: null,
sourceMap: null,
targetRootFS: '',
@ -478,7 +478,7 @@ export class TickProcessor extends LogReader {
params.separateBytecodes,
params.separateBuiltins,
params.separateStubs,
params.separateBaselineHandlers,
params.separateSparkplugHandlers,
params.callGraphSize,
params.ignoreUnknown,
params.stateFilter,
@ -498,7 +498,7 @@ export class TickProcessor extends LogReader {
separateBytecodes,
separateBuiltins,
separateStubs,
separateBaselineHandlers,
separateSparkplugHandlers,
callGraphSize,
ignoreUnknown,
stateFilter,
@ -632,7 +632,7 @@ export class TickProcessor extends LogReader {
this.profile_ = new JsonProfile();
} else {
this.profile_ = new V8Profile(separateIc, separateBytecodes,
separateBuiltins, separateStubs, separateBaselineHandlers);
separateBuiltins, separateStubs, separateSparkplugHandlers);
}
this.codeTypes_ = {};
// Count each tick as a time unit.
@ -660,7 +660,7 @@ export class TickProcessor extends LogReader {
GC: 1,
PARSER: 2,
BYTECODE_COMPILER: 3,
// TODO(cbruni): add BASELINE_COMPILER
// TODO(cbruni): add SPARKPLUG_COMPILER
COMPILER: 4,
OTHER: 5,
EXTERNAL: 6,