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

Side by Side Diff: tools/binary_size/libsupersize/describe.py

Issue 2864063002: Supersize: Chrome-specific breakdowns, console tweaks (Closed)
Patch Set: review tweaks Created 3 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 unified diff | Download patch
OLDNEW
1 # Copyright 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 """Methods for converting model objects to human-readable formats.""" 4 """Methods for converting model objects to human-readable formats."""
5 5
6 import datetime 6 import datetime
7 import itertools 7 import itertools
8 import time 8 import time
9 9
10 import models 10 import models
(...skipping 11 matching lines...) Expand all
22 return '%.1fkb' % size 22 return '%.1fkb' % size
23 elif abs(size) < 1024: 23 elif abs(size) < 1024:
24 return '%dkb' % size 24 return '%dkb' % size
25 size /= 1024.0 25 size /= 1024.0
26 if abs(size) < 10: 26 if abs(size) < 10:
27 return '%.2fmb' % size 27 return '%.2fmb' % size
28 # We shouldn't be seeing sizes > 100mb. 28 # We shouldn't be seeing sizes > 100mb.
29 return '%.1fmb' % size 29 return '%.1fmb' % size
30 30
31 31
32 def _FormatPss(pss):
33 # Shows a decimal for small numbers to make it clear that a shared symbol has
34 # a non-zero pss.
35 if pss > 10:
36 return str(int(pss))
37 ret = str(round(pss, 1))
38 if ret.endswith('.0'):
39 ret = ret[:-2]
40 return ret
41
42
32 def _DiffPrefix(diff, sym): 43 def _DiffPrefix(diff, sym):
33 if diff.IsAdded(sym): 44 if diff.IsAdded(sym):
34 return '+ ' 45 return '+ '
35 if diff.IsRemoved(sym): 46 if diff.IsRemoved(sym):
36 return '- ' 47 return '- '
37 if sym.size: 48 if sym.size:
38 return '~ ' 49 return '~ '
39 return '= ' 50 return '= '
40 51
41 52
(...skipping 19 matching lines...) Expand all
61 yield ' {}: {:,} bytes ({:.1%})'.format(name, size, percent) 72 yield ' {}: {:,} bytes ({:.1%})'.format(name, size, percent)
62 73
63 if self.verbose: 74 if self.verbose:
64 yield '' 75 yield ''
65 yield 'Other section sizes:' 76 yield 'Other section sizes:'
66 section_names = sorted(k for k in section_sizes.iterkeys() 77 section_names = sorted(k for k in section_sizes.iterkeys()
67 if k not in section_names) 78 if k not in section_names)
68 for name in section_names: 79 for name in section_names:
69 yield ' {}: {:,} bytes'.format(name, section_sizes[name]) 80 yield ' {}: {:,} bytes'.format(name, section_sizes[name])
70 81
71 def _DescribeSymbol(self, sym): 82 def _DescribeSymbol(self, sym, single_line=False):
72 if sym.IsGroup(): 83 if sym.IsGroup():
73 address = 'Group' 84 address = 'Group'
74 else: 85 else:
75 address = hex(sym.address) 86 address = hex(sym.address)
76 if self.verbose: 87 if self.verbose:
77 count_part = ' count=%d' % len(sym) if sym.IsGroup() else '' 88 count_part = ' count=%d' % len(sym) if sym.IsGroup() else ''
78 yield '{}@{:<9s} pss={} padding={} size_without_padding={}{}'.format( 89 yield '{}@{:<9s} pss={} padding={} size_without_padding={}{}'.format(
79 sym.section, address, int(sym.pss), sym.padding, 90 sym.section, address, _FormatPss(sym.pss), sym.padding,
80 sym.size_without_padding, count_part) 91 sym.size_without_padding, count_part)
81 yield ' source_path={} \tobject_path={}'.format( 92 yield ' source_path={} \tobject_path={}'.format(
82 sym.source_path, sym.object_path) 93 sym.source_path, sym.object_path)
83 if sym.name: 94 if sym.name:
84 yield ' flags={} name={}'.format(sym.FlagsString(), sym.name) 95 yield ' flags={} name={}'.format(sym.FlagsString(), sym.name)
85 if sym.full_name: 96 if sym.full_name:
86 yield ' full_name={}'.format(sym.full_name) 97 yield ' full_name={}'.format(sym.full_name)
87 elif sym.full_name: 98 elif sym.full_name:
88 yield ' flags={} full_name={}'.format( 99 yield ' flags={} full_name={}'.format(
89 sym.FlagsString(), sym.full_name) 100 sym.FlagsString(), sym.full_name)
101 elif single_line:
102 count_part = ' (count=%d)' % len(sym) if sym.IsGroup() else ''
103 yield '{}@{:<9s} {:<7} {}{}'.format(
104 sym.section, address, _FormatPss(sym.pss), sym.name, count_part)
90 else: 105 else:
91 yield '{}@{:<9s} {:<7} {}'.format( 106 yield '{}@{:<9s} {:<7} {}'.format(
92 sym.section, address, int(sym.pss), 107 sym.section, address, _FormatPss(sym.pss),
93 sym.source_path or sym.object_path or '{no path}') 108 sym.source_path or sym.object_path or '{no path}')
94 if sym.name: 109 if sym.name:
95 count_part = ' (count=%d)' % len(sym) if sym.IsGroup() else '' 110 count_part = ' (count=%d)' % len(sym) if sym.IsGroup() else ''
96 yield ' {}{}'.format(sym.name, count_part) 111 yield ' {}{}'.format(sym.name, count_part)
97 112
98 def _DescribeSymbolGroupChildren(self, group, indent=0): 113 def _DescribeSymbolGroupChildren(self, group, indent=0):
99 running_total = 0 114 running_total = 0
100 sorted_syms = group if group.is_sorted else group.Sorted() 115 running_percent = 0
101 is_diff = isinstance(group, models.SymbolDiff) 116 is_diff = isinstance(group, models.SymbolDiff)
117 all_groups = all(s.IsGroup() for s in group)
102 118
103 indent_prefix = '> ' * indent 119 indent_prefix = '> ' * indent
104 diff_prefix = '' 120 diff_prefix = ''
105 for s in sorted_syms: 121 total = group.pss
122 for index, s in enumerate(group):
106 if group.IsBss() or not s.IsBss(): 123 if group.IsBss() or not s.IsBss():
107 running_total += s.pss 124 running_total += s.pss
108 for l in self._DescribeSymbol(s): 125 running_percent = running_total / total
126 for l in self._DescribeSymbol(s, single_line=all_groups):
109 if l[:4].isspace(): 127 if l[:4].isspace():
110 indent_size = 8 + len(indent_prefix) + len(diff_prefix) 128 indent_size = 8 + len(indent_prefix) + len(diff_prefix)
111 yield '{} {}'.format(' ' * indent_size, l) 129 yield '{} {}'.format(' ' * indent_size, l)
112 else: 130 else:
113 if is_diff: 131 if is_diff:
114 diff_prefix = _DiffPrefix(group, s) 132 diff_prefix = _DiffPrefix(group, s)
115 yield '{}{}{:8} {}'.format(indent_prefix, diff_prefix, 133 yield '{}{}{:<4} {:>8} {:7} {}'.format(
116 int(running_total), l) 134 indent_prefix, diff_prefix, str(index) + ')',
135 _FormatPss(running_total), '({:.1%})'.format(running_percent), l)
117 136
118 if self.recursive and s.IsGroup(): 137 if self.recursive and s.IsGroup():
119 for l in self._DescribeSymbolGroupChildren(s, indent=indent + 1): 138 for l in self._DescribeSymbolGroupChildren(s, indent=indent + 1):
120 yield l 139 yield l
121 140
122 def _DescribeSymbolGroup(self, group): 141 def _DescribeSymbolGroup(self, group):
123 total_size = group.pss 142 total_size = group.pss
124 code_syms = group.WhereInSection('t') 143 code_size = 0
125 code_size = code_syms.pss 144 ro_size = 0
126 ro_size = code_syms.Inverted().WhereInSection('r').pss 145 unique_paths = set()
127 unique_paths = set(s.object_path for s in group) 146 for s in group.IterLeafSymbols():
147 if s.section == 't':
148 code_size += s.pss
149 elif s.section == 'r':
150 ro_size += s.pss
151 unique_paths.add(s.object_path)
128 header_desc = [ 152 header_desc = [
129 'Showing {:,} symbols ({:,} unique) with total pss: {} bytes'.format( 153 'Showing {:,} symbols ({:,} unique) with total pss: {} bytes'.format(
130 len(group), group.CountUniqueSymbols(), int(total_size)), 154 len(group), group.CountUniqueSymbols(), int(total_size)),
131 '.text={:<10} .rodata={:<10} other={:<10} total={}'.format( 155 '.text={:<10} .rodata={:<10} other={:<10} total={}'.format(
132 _PrettySize(int(code_size)), _PrettySize(int(ro_size)), 156 _PrettySize(int(code_size)), _PrettySize(int(ro_size)),
133 _PrettySize(int(total_size - code_size - ro_size)), 157 _PrettySize(int(total_size - code_size - ro_size)),
134 _PrettySize(int(total_size))), 158 _PrettySize(int(total_size))),
135 'Number of object files: {}'.format(len(unique_paths)), 159 'Number of object files: {}'.format(len(unique_paths)),
136 '', 160 '',
137 'First columns are: running total, address, pss', 161 'Index, Running Total, Section@Address, PSS',
162 '-' * 60
138 ] 163 ]
139 children_desc = self._DescribeSymbolGroupChildren(group) 164 children_desc = self._DescribeSymbolGroupChildren(group)
140 return itertools.chain(header_desc, children_desc) 165 return itertools.chain(header_desc, children_desc)
141 166
142 def _DescribeSymbolDiff(self, diff): 167 def _DescribeSymbolDiff(self, diff):
143 header_template = ('{} symbols added (+), {} changed (~), {} removed (-), ' 168 header_template = ('{} symbols added (+), {} changed (~), {} removed (-), '
144 '{} unchanged ({})') 169 '{} unchanged ({})')
145 unchanged_msg = '=' if self.verbose else 'not shown' 170 unchanged_msg = '=' if self.verbose else 'not shown'
146 symbol_delta_desc = [header_template.format( 171 symbol_delta_desc = [header_template.format(
147 diff.added_count, diff.changed_count, diff.removed_count, 172 diff.added_count, diff.changed_count, diff.removed_count,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 316
292 def GenerateLines(obj, verbose=False, recursive=False): 317 def GenerateLines(obj, verbose=False, recursive=False):
293 """Returns an iterable of lines (without \n) that describes |obj|.""" 318 """Returns an iterable of lines (without \n) that describes |obj|."""
294 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj) 319 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj)
295 320
296 321
297 def WriteLines(lines, func): 322 def WriteLines(lines, func):
298 for l in lines: 323 for l in lines:
299 func(l) 324 func(l)
300 func('\n') 325 func('\n')
OLDNEW
« no previous file with comments | « tools/binary_size/libsupersize/console.py ('k') | tools/binary_size/libsupersize/file_format.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698