1dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui#!/usr/bin/env python 2dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# 3dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# Copyright (C) 2015 The Android Open Source Project 4dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# 5dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# Licensed under the Apache License, Version 2.0 (the "License"); 6dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# you may not use this file except in compliance with the License. 7dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# You may obtain a copy of the License at 8dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# 9dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# http://www.apache.org/licenses/LICENSE-2.0 10dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# 11dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# Unless required by applicable law or agreed to in writing, software 12dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# distributed under the License is distributed on an "AS IS" BASIS, 13dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# See the License for the specific language governing permissions and 15dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# limitations under the License. 16dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui# 17dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 18dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui"""Simpleperf gui reporter: provide gui interface for simpleperf report command. 19dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 20dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin CuiThere are two ways to use gui reporter. One way is to pass it a report file 21dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuigenerated by simpleperf report command, and reporter will display it. The 22dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiother ways is to pass it any arguments you want to use when calling 23dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuisimpleperf report command. The reporter will call `simpleperf report` to 24dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuigenerate report file, and display it. 25dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui""" 26dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 27dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiimport os.path 28dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiimport re 29dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiimport subprocess 30dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiimport sys 31dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuifrom tkFont import * 32dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuifrom Tkinter import * 33dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuifrom ttk import * 34dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 35dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin CuiPAD_X = 3 36dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin CuiPAD_Y = 3 37dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 38dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 39dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiclass CallTreeNode(object): 40dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 41dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui """Representing a node in call-graph.""" 42dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 43dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def __init__(self, percentage, function_name): 44dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.percentage = percentage 45dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.call_stack = [function_name] 46dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.children = [] 47dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 48dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def add_call(self, function_name): 49dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.call_stack.append(function_name) 50dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 51dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def add_child(self, node): 52dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.children.append(node) 53dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 54dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def __str__(self): 55dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs = self.dump() 56dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui return '\n'.join(strs) 57dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 58dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def dump(self): 59dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs = [] 60dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs.append('CallTreeNode percentage = %.2f' % self.percentage) 61dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for function_name in self.call_stack: 62dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs.append(' %s' % function_name) 63dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for child in self.children: 64dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui child_strs = child.dump() 65dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs.extend([' ' + x for x in child_strs]) 66dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui return strs 67dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 68dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 69dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiclass ReportItem(object): 70dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 71dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui """Representing one item in report, may contain a CallTree.""" 72dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 73dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def __init__(self, raw_line): 74dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.raw_line = raw_line 75dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.call_tree = None 76dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 77dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def __str__(self): 78dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs = [] 79dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs.append('ReportItem (raw_line %s)' % self.raw_line) 80dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if self.call_tree is not None: 81dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui strs.append('%s' % self.call_tree) 82dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui return '\n'.join(strs) 83dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 84dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 85dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuidef parse_report_items(lines): 86dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_items = [] 87dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui cur_report_item = None 88dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui call_tree_stack = {} 89dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui vertical_columns = [] 90dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui last_node = None 91dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 92dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for line in lines: 93dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if not line: 94dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui continue 95dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if not line[0].isspace(): 96dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui cur_report_item = ReportItem(line) 97dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_items.append(cur_report_item) 98dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui # Each report item can have different column depths. 99dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui vertical_columns = [] 100dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 101dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for i in range(len(line)): 102dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if line[i] == '|': 103dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if not vertical_columns or vertical_columns[-1] < i: 104dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui vertical_columns.append(i) 105dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 106dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if not line.strip('| \t'): 107dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui continue 108dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if line.find('-') == -1: 109dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui line = line.strip('| \t') 110dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui function_name = line 111dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui last_node.add_call(function_name) 112dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 113dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui pos = line.find('-') 114dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui depth = -1 115dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for i in range(len(vertical_columns)): 116dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if pos >= vertical_columns[i]: 117dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui depth = i 118dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui assert depth != -1 119dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 120dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui line = line.strip('|- \t') 121dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui m = re.search(r'^([\d\.]+)%[-\s]+(.+)$', line) 122dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if m: 123dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui percentage = float(m.group(1)) 124dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui function_name = m.group(2) 125dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 126dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui percentage = 100.0 127dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui function_name = line 128dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 129dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui node = CallTreeNode(percentage, function_name) 130dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if depth == 0: 131dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui cur_report_item.call_tree = node 132dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 133dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui call_tree_stack[depth - 1].add_child(node) 134dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui call_tree_stack[depth] = node 135dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui last_node = node 136dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 137dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui return report_items 138dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 139dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 140dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiclass ReportWindow(object): 141dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 142dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui """A window used to display report file.""" 143dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 144dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def __init__(self, master, report_context, title_line, report_items): 145dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui frame = Frame(master) 146dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui frame.pack(fill=BOTH, expand=1) 147dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 148dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui font = Font(family='courier', size=10) 149dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 150dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui # Report Context 151dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for line in report_context: 152dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label = Label(frame, text=line, font=font) 153dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label.pack(anchor=W, padx=PAD_X, pady=PAD_Y) 154dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 155dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui # Space 156dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label = Label(frame, text='', font=font) 157dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label.pack(anchor=W, padx=PAD_X, pady=PAD_Y) 158dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 159dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui # Title 160dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label = Label(frame, text=' ' + title_line, font=font) 161dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui label.pack(anchor=W, padx=PAD_X, pady=PAD_Y) 162dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 163dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui # Report Items 164dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_frame = Frame(frame) 165dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_frame.pack(fill=BOTH, expand=1) 166dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 167dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui yscrollbar = Scrollbar(report_frame) 168dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui yscrollbar.pack(side=RIGHT, fill=Y) 169dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui xscrollbar = Scrollbar(report_frame, orient=HORIZONTAL) 170dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui xscrollbar.pack(side=BOTTOM, fill=X) 171dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 172dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tree = Treeview(report_frame, columns=[title_line], show='') 173dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tree.pack(side=LEFT, fill=BOTH, expand=1) 174dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tree.tag_configure('set_font', font=font) 175dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 176dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tree.config(yscrollcommand=yscrollbar.set) 177dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui yscrollbar.config(command=tree.yview) 178dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tree.config(xscrollcommand=xscrollbar.set) 179dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui xscrollbar.config(command=tree.xview) 180dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 181dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.display_report_items(tree, report_items) 182dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 183dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def display_report_items(self, tree, report_items): 184dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for report_item in report_items: 185dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui prefix_str = '+ ' if report_item.call_tree is not None else ' ' 186dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui id = tree.insert( 187dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui '', 188dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 'end', 189dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui None, 190dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui values=[ 191dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui prefix_str + 192dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_item.raw_line], 193dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tag='set_font') 194dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if report_item.call_tree is not None: 195dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.display_call_tree(tree, id, report_item.call_tree, 1) 196dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 197dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui def display_call_tree(self, tree, parent_id, node, indent): 198dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui id = parent_id 199dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui indent_str = ' ' * indent 200dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 201dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if node.percentage != 100.0: 202dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui percentage_str = '%.2f%%' % node.percentage 203dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 204dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui percentage_str = '' 205dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui first_open = True if node.percentage == 100.0 else False 206dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 207dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for i in range(len(node.call_stack)): 208dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui s = indent_str 209dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui s += '+ ' if node.children else ' ' 210dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui s += percentage_str if i == 0 else ' ' * len(percentage_str) 211dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui s += node.call_stack[i] 212dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui child_open = first_open if i == 0 else True 213dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui id = tree.insert(id, 'end', None, values=[s], open=child_open, 214dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui tag='set_font') 215dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 216dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for child in node.children: 217dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui self.display_call_tree(tree, id, child, indent + 1) 218dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 219dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 220dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuidef display_report_file(report_file): 221dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui fh = open(report_file, 'r') 222dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui lines = fh.readlines() 223dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui fh.close() 224dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 225dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui lines = [x.rstrip() for x in lines] 226dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 227dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui blank_line_index = -1 228dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui for i in range(len(lines)): 229dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if not lines[i]: 230dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui blank_line_index = i 231dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui break 232dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui assert blank_line_index != -1 233dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui assert blank_line_index + 1 < len(lines) 234dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 235dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_context = lines[:blank_line_index] 236dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui title_line = lines[blank_line_index + 1] 237dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui report_items = parse_report_items(lines[blank_line_index + 2:]) 238dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 239dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui root = Tk() 240dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui ReportWindow(root, report_context, title_line, report_items) 241dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui root.mainloop() 242dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 243dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 244dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuidef call_simpleperf_report(args, report_file): 245dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui output_fh = open(report_file, 'w') 246dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui args = ['simpleperf', 'report'] + args 247dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui subprocess.check_call(args, stdout=output_fh) 248dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui output_fh.close() 249dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 250dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 251dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuidef main(): 252dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]): 253dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui display_report_file(sys.argv[1]) 254dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui else: 255dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui call_simpleperf_report(sys.argv[1:], 'perf.report') 256dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui display_report_file('perf.report') 257dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 258dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui 259dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cuiif __name__ == '__main__': 260dae17fd9fcc78800d2447c8470f7a1ecd813c2cdYabin Cui main() 261