Commit 64aeabbc authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[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: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81992}
parent 4b5ac613
...@@ -39,7 +39,7 @@ ...@@ -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() { ...@@ -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) { ...@@ -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();
} }
\ No newline at end of file
...@@ -1185,7 +1185,7 @@ code is governed by a BSD-style license that can be found in the LICENSE 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); 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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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" ...@@ -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. --> ...@@ -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. --> ...@@ -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>
......
#!/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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment