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

Side by Side Diff: tools/ignition/linux_perf_report.py

Issue 2477363002: [Tools] Enable grouping of jited code in linux_perf_report.py. (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | tools/ignition/linux_perf_report_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #! /usr/bin/python2 1 #! /usr/bin/python2
2 # 2 #
3 # Copyright 2016 the V8 project authors. All rights reserved. 3 # Copyright 2016 the V8 project authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 # 6 #
7 7
8 import argparse 8 import argparse
9 import collections 9 import collections
10 import re 10 import re
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 # See the hottest bytecodes on Octane benchmark, by number of samples. 45 # See the hottest bytecodes on Octane benchmark, by number of samples.
46 # 46 #
47 $ tools/run-perf.sh out/x64.release/d8 \\ 47 $ tools/run-perf.sh out/x64.release/d8 \\
48 --ignition --noturbo --nocrankshaft octane/run.js 48 --ignition --noturbo --nocrankshaft octane/run.js
49 $ tools/ignition/linux_perf_report.py 49 $ tools/ignition/linux_perf_report.py
50 """ 50 """
51 51
52 52
53 COMPILER_SYMBOLS_RE = re.compile( 53 COMPILER_SYMBOLS_RE = re.compile(
54 r"v8::internal::(?:\(anonymous namespace\)::)?Compile|v8::internal::Parser") 54 r"v8::internal::(?:\(anonymous namespace\)::)?Compile|v8::internal::Parser")
55 JIT_CODE_SYMBOLS_RE = re.compile(
56 r"(LazyCompile|Compile|Eval|Script):(\*|~)")
55 57
56 58
57 def strip_function_parameters(symbol): 59 def strip_function_parameters(symbol):
58 if symbol[-1] != ')': return symbol 60 if symbol[-1] != ')': return symbol
59 pos = 1 61 pos = 1
60 parenthesis_count = 0 62 parenthesis_count = 0
61 for c in reversed(symbol): 63 for c in reversed(symbol):
62 if c == ')': 64 if c == ')':
63 parenthesis_count += 1 65 parenthesis_count += 1
64 elif c == '(': 66 elif c == '(':
65 parenthesis_count -= 1 67 parenthesis_count -= 1
66 if parenthesis_count == 0: 68 if parenthesis_count == 0:
67 break 69 break
68 else: 70 else:
69 pos += 1 71 pos += 1
70 return symbol[:-pos] 72 return symbol[:-pos]
71 73
72 74
73 def collapsed_callchains_generator(perf_stream, show_all=False, 75 def collapsed_callchains_generator(perf_stream, hide_other=False,
76 hide_compiler=False, hide_jit=False,
74 show_full_signatures=False): 77 show_full_signatures=False):
75 current_chain = [] 78 current_chain = []
76 skip_until_end_of_chain = False 79 skip_until_end_of_chain = False
77 compiler_symbol_in_chain = False 80 compiler_symbol_in_chain = False
78 81
79 for line in perf_stream: 82 for line in perf_stream:
80 # Lines starting with a "#" are comments, skip them. 83 # Lines starting with a "#" are comments, skip them.
81 if line[0] == "#": 84 if line[0] == "#":
82 continue 85 continue
83 86
84 line = line.strip() 87 line = line.strip()
85 88
86 # Empty line signals the end of the callchain. 89 # Empty line signals the end of the callchain.
87 if not line: 90 if not line:
88 if not skip_until_end_of_chain and current_chain and show_all: 91 if (not skip_until_end_of_chain and current_chain
92 and not hide_other):
89 current_chain.append("[other]") 93 current_chain.append("[other]")
90 yield current_chain 94 yield current_chain
91 # Reset parser status. 95 # Reset parser status.
92 current_chain = [] 96 current_chain = []
93 skip_until_end_of_chain = False 97 skip_until_end_of_chain = False
94 compiler_symbol_in_chain = False 98 compiler_symbol_in_chain = False
95 continue 99 continue
96 100
97 if skip_until_end_of_chain: 101 if skip_until_end_of_chain:
98 continue 102 continue
99 103
100 # Trim the leading address and the trailing +offset, if present. 104 # Trim the leading address and the trailing +offset, if present.
101 symbol = line.split(" ", 1)[1].split("+", 1)[0] 105 symbol = line.split(" ", 1)[1].split("+", 1)[0]
102 if not show_full_signatures: 106 if not show_full_signatures:
103 symbol = strip_function_parameters(symbol) 107 symbol = strip_function_parameters(symbol)
108
109 # Avoid chains of [unknown]
110 if symbol == "[unknown]" and current_chain[-1] == "[unknown]":
mythria 2016/11/08 09:47:07 It is possible that symbol is unknown and the curr
111 continue
112
104 current_chain.append(symbol) 113 current_chain.append(symbol)
105 114
106 if symbol.startswith("BytecodeHandler:"): 115 if symbol.startswith("BytecodeHandler:"):
116 current_chain.append("[interpreter]")
107 yield current_chain 117 yield current_chain
108 skip_until_end_of_chain = True 118 skip_until_end_of_chain = True
119 elif JIT_CODE_SYMBOLS_RE.match(symbol):
120 if not hide_jit:
121 current_chain.append("[jit]")
122 yield current_chain
123 skip_until_end_of_chain = True
109 elif symbol == "Stub:CEntryStub" and compiler_symbol_in_chain: 124 elif symbol == "Stub:CEntryStub" and compiler_symbol_in_chain:
110 if show_all: 125 if not hide_compiler:
111 current_chain[-1] = "[compiler]" 126 current_chain.append("[compiler]")
112 yield current_chain 127 yield current_chain
113 skip_until_end_of_chain = True 128 skip_until_end_of_chain = True
114 elif COMPILER_SYMBOLS_RE.match(symbol): 129 elif COMPILER_SYMBOLS_RE.match(symbol):
115 compiler_symbol_in_chain = True 130 compiler_symbol_in_chain = True
116 elif symbol == "Builtin:InterpreterEntryTrampoline": 131 elif symbol == "Builtin:InterpreterEntryTrampoline":
117 if len(current_chain) == 1: 132 if len(current_chain) == 1:
118 yield ["[entry trampoline]"] 133 yield ["[entry trampoline]"]
119 else: 134 else:
120 # If we see an InterpreterEntryTrampoline which is not at the top of the 135 # If we see an InterpreterEntryTrampoline which is not at the top of the
121 # chain and doesn't have a BytecodeHandler above it, then we have 136 # chain and doesn't have a BytecodeHandler above it, then we have
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 default="perf.data", 189 default="perf.data",
175 metavar="<perf filename>" 190 metavar="<perf filename>"
176 ) 191 )
177 command_line_parser.add_argument( 192 command_line_parser.add_argument(
178 "--flamegraph", "-f", 193 "--flamegraph", "-f",
179 help="output an input file for flamegraph.pl, not a report", 194 help="output an input file for flamegraph.pl, not a report",
180 action="store_true", 195 action="store_true",
181 dest="output_flamegraph" 196 dest="output_flamegraph"
182 ) 197 )
183 command_line_parser.add_argument( 198 command_line_parser.add_argument(
184 "--show-all", "-a", 199 "--hide-other",
185 help="show samples outside Ignition bytecode handlers", 200 help="Hide other samples",
186 action="store_true" 201 action="store_true"
187 ) 202 )
188 command_line_parser.add_argument( 203 command_line_parser.add_argument(
204 "--hide-compiler",
205 help="Hide samples during compilation",
206 action="store_true"
207 )
208 command_line_parser.add_argument(
209 "--hide-jit",
210 help="Hide samples from JIT code execution",
211 action="store_true"
212 )
213 command_line_parser.add_argument(
189 "--show-full-signatures", "-s", 214 "--show-full-signatures", "-s",
190 help="show full signatures instead of function names", 215 help="show full signatures instead of function names",
191 action="store_true" 216 action="store_true"
192 ) 217 )
193 command_line_parser.add_argument( 218 command_line_parser.add_argument(
194 "--output", "-o", 219 "--output", "-o",
195 help="output file name (stdout if omitted)", 220 help="output file name (stdout if omitted)",
196 type=argparse.FileType('wt'), 221 type=argparse.FileType('wt'),
197 default=sys.stdout, 222 default=sys.stdout,
198 metavar="<output filename>", 223 metavar="<output filename>",
199 dest="output_stream" 224 dest="output_stream"
200 ) 225 )
201 226
202 return command_line_parser.parse_args() 227 return command_line_parser.parse_args()
203 228
204 229
205 def main(): 230 def main():
206 program_options = parse_command_line() 231 program_options = parse_command_line()
207 232
208 perf = subprocess.Popen(["perf", "script", "--fields", "ip,sym", 233 perf = subprocess.Popen(["perf", "script", "--fields", "ip,sym",
209 "-i", program_options.perf_filename], 234 "-i", program_options.perf_filename],
210 stdout=subprocess.PIPE) 235 stdout=subprocess.PIPE)
211 236
212 callchains = collapsed_callchains_generator( 237 callchains = collapsed_callchains_generator(
213 perf.stdout, program_options.show_all, 238 perf.stdout, program_options.hide_other, program_options.hide_compiler,
214 program_options.show_full_signatures) 239 program_options.hide_jit, program_options.show_full_signatures)
215 240
216 if program_options.output_flamegraph: 241 if program_options.output_flamegraph:
217 write_flamegraph_input_file(program_options.output_stream, callchains) 242 write_flamegraph_input_file(program_options.output_stream, callchains)
218 else: 243 else:
219 write_handlers_report(program_options.output_stream, callchains) 244 write_handlers_report(program_options.output_stream, callchains)
220 245
221 246
222 if __name__ == "__main__": 247 if __name__ == "__main__":
223 main() 248 main()
OLDNEW
« no previous file with comments | « no previous file | tools/ignition/linux_perf_report_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698