Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(492)

Unified Diff: tools/ignition/linux_perf_bytecode_annotate.py

Issue 1945673002: [Interpreter] Add a bytecode annotate tool. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/ignition/linux_perf_bytecode_annotate_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/ignition/linux_perf_bytecode_annotate.py
diff --git a/tools/ignition/linux_perf_bytecode_annotate.py b/tools/ignition/linux_perf_bytecode_annotate.py
new file mode 100755
index 0000000000000000000000000000000000000000..6681190d9909a461b14de2bd2a6ee73c58caa49a
--- /dev/null
+++ b/tools/ignition/linux_perf_bytecode_annotate.py
@@ -0,0 +1,174 @@
+#! /usr/bin/python2
+#
+# Copyright 2016 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.
+#
+
+import argparse
+import collections
+import os
+import subprocess
+import sys
+
+
+__DESCRIPTION = """
+Processes a perf.data sample file and annotates the hottest instructions in a
+given bytecode handler.
+"""
+
+
+__HELP_EPILOGUE = """
+Note:
+ This tool uses the disassembly of interpreter's bytecode handler codegen
+ from out/<arch>.debug/d8. you should ensure that this binary is in-sync with
+ the version used to generate the perf profile.
+
+ Also, the tool depends on the symbol offsets from perf samples being accurate.
+ As such, you should use the ":pp" suffix for events.
+
+Examples:
+ EVENT_TYPE=cycles:pp tools/run-perf.sh out/x64.release/d8
+ tools/ignition/linux_perf_bytecode_annotate.py Add
+"""
+
+
+def bytecode_offset_generator(perf_stream, bytecode_name):
+ skip_until_end_of_chain = False
+ bytecode_symbol = "BytecodeHandler:" + bytecode_name;
+
+ for line in perf_stream:
+ # Lines starting with a "#" are comments, skip them.
+ if line[0] == "#":
+ continue
+ line = line.strip()
+
+ # Empty line signals the end of the callchain.
+ if not line:
+ skip_until_end_of_chain = False
+ continue
+
+ if skip_until_end_of_chain:
+ continue
+
+ symbol_and_offset = line.split(" ", 1)[1]
+
+ if symbol_and_offset.startswith("BytecodeHandler:"):
+ skip_until_end_of_chain = True
+
+ if symbol_and_offset.startswith(bytecode_symbol):
+ yield int(symbol_and_offset.split("+", 1)[1], 16)
+
+
+def bytecode_offset_counts(bytecode_offsets):
+ offset_counts = collections.defaultdict(int)
+ for offset in bytecode_offsets:
+ offset_counts[offset] += 1
+ return offset_counts
+
+
+def bytecode_disassembly_generator(ignition_codegen, bytecode_name):
+ name_string = "name = " + bytecode_name
+ for line in ignition_codegen:
+ if line.startswith(name_string):
+ break
+
+ # Found the bytecode disassembly.
+ for line in ignition_codegen:
+ line = line.strip()
+ # Blank line marks the end of the bytecode's disassembly.
+ if not line:
+ return
+
+ # Only yield disassembly output.
+ if not line.startswith("0x"):
+ continue
+
+ yield line
+
+
+def print_disassembly_annotation(offset_counts, bytecode_disassembly):
+ total = sum(offset_counts.values())
+ offsets = sorted(offset_counts, reverse=True)
+ def next_offset():
+ return offsets.pop() if offsets else -1
+
+ current_offset = next_offset()
+ print current_offset;
+
+ for line in bytecode_disassembly:
+ disassembly_offset = int(line.split()[1])
+ if disassembly_offset == current_offset:
+ count = offset_counts[current_offset]
+ percentage = 100.0 * count / total
+ print "{:>8d} ({:>5.1f}%) ".format(count, percentage),
+ current_offset = next_offset()
+ else:
+ print " ",
+ print line
+
+ if offsets:
+ print ("WARNING: Offsets not empty. Output is most likely invalid due to "
+ "a mismatch between perf output and debug d8 binary.")
+
+
+def parse_command_line():
+ command_line_parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=__DESCRIPTION,
+ epilog=__HELP_EPILOGUE)
+
+ command_line_parser.add_argument(
+ "--arch", "-a",
+ help="The architecture (default: x64)",
+ default="x64",
+ )
+ command_line_parser.add_argument(
+ "--input", "-i",
+ help="perf sample file to process (default: perf.data)",
+ default="perf.data",
+ metavar="<perf filename>",
+ dest="perf_filename"
+ )
+ command_line_parser.add_argument(
+ "--output", "-o",
+ help="output file name (stdout if omitted)",
+ type=argparse.FileType("wt"),
+ default=sys.stdout,
+ metavar="<output filename>",
+ dest="output_stream"
+ )
+ command_line_parser.add_argument(
+ "bytecode_name",
+ metavar="<bytecode name>",
+ nargs="?",
+ help="The bytecode handler to annotate"
+ )
+
+ return command_line_parser.parse_args()
+
+
+def main():
+ program_options = parse_command_line()
+ perf = subprocess.Popen(["perf", "script", "-f", "ip,sym,symoff",
+ "-i", program_options.perf_filename],
+ stdout=subprocess.PIPE)
+
+ v8_root_path = os.path.dirname(__file__) + "/../../"
+ d8_path = "{}/out/{}.debug/d8".format(v8_root_path, program_options.arch)
+ d8_codegen = subprocess.Popen([d8_path, "--ignition",
+ "--trace-ignition-codegen", "-e", "1"],
+ stdout=subprocess.PIPE)
+
+ bytecode_offsets = bytecode_offset_generator(
+ perf.stdout, program_options.bytecode_name)
+ offset_counts = bytecode_offset_counts(bytecode_offsets)
+
+ bytecode_disassembly = bytecode_disassembly_generator(
+ d8_codegen.stdout, program_options.bytecode_name)
+
+ print_disassembly_annotation(offset_counts, bytecode_disassembly)
+
+
+if __name__ == "__main__":
+ main()
« no previous file with comments | « no previous file | tools/ignition/linux_perf_bytecode_annotate_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698