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

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

Issue 2795593005: //tools/binary_size: Various enhancements to console.py (Closed)
Patch Set: Review fixes Created 3 years, 8 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
« no previous file with comments | « tools/binary_size/console.py ('k') | tools/binary_size/integration_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 # 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
11 11
12 12
13 def _PrettySize(size):
14 # Arbitrarily chosen cut-off.
15 if abs(size) < 2000:
16 return '%d bytes' % size
17 # Always show 3 digits.
18 size /= 1024.0
19 if abs(size) < 10:
20 return '%.2fkb' % size
21 elif abs(size) < 100:
22 return '%.1fkb' % size
23 elif abs(size) < 1024:
24 return '%dkb' % size
25 size /= 1024.0
26 if abs(size) < 10:
27 return '%.2fmb' % size
28 # We shouldn't be seeing sizes > 100mb.
29 return '%.1fmb' % size
30
31
13 class Describer(object): 32 class Describer(object):
14 def __init__(self, verbose=False): 33 def __init__(self, verbose=False):
15 self.verbose = verbose 34 self.verbose = verbose
16 35
17 def _DescribeSectionSizes(self, section_sizes): 36 def _DescribeSectionSizes(self, section_sizes):
18 relevant_names = models.SECTION_TO_SECTION_NAME.values() 37 relevant_names = models.SECTION_TO_SECTION_NAME.values()
19 section_names = sorted(k for k in section_sizes.iterkeys() 38 section_names = sorted(k for k in section_sizes.iterkeys()
20 if k in relevant_names or k.startswith('.data')) 39 if k in relevant_names or k.startswith('.data'))
21 total_bytes = sum(v for k, v in section_sizes.iteritems() 40 total_bytes = sum(v for k, v in section_sizes.iteritems()
22 if k in section_names and k != '.bss') 41 if k in section_names and k != '.bss')
23 yield 'Section Sizes (Total={:,} bytes):'.format(total_bytes) 42 yield 'Section Sizes (Total={:,} bytes):'.format(total_bytes)
24 for name in section_names: 43 for name in section_names:
25 size = section_sizes[name] 44 size = section_sizes[name]
26 if name == '.bss': 45 if name == '.bss':
27 yield '{}: {:,} bytes (not included in totals)'.format(name, size) 46 yield '{}: {:,} bytes (not included in totals)'.format(name, size)
28 else: 47 else:
29 percent = float(size) / total_bytes if total_bytes else 0 48 percent = float(size) / total_bytes if total_bytes else 0
30 yield '{}: {:,} bytes ({:.1%})'.format(name, size, percent) 49 yield '{}: {:,} bytes ({:.1%})'.format(name, size, percent)
31 50
32 def _DescribeSymbol(self, sym): 51 def _DescribeSymbol(self, sym):
33 # SymbolGroups are passed here when we don't want to expand them. 52 # SymbolGroups are passed here when we don't want to expand them.
34 if sym.IsGroup(): 53 if sym.IsGroup():
35 yield '{} {:<8} {} (count={})'.format(sym.section, sym.size, sym.name, 54 if self.verbose:
36 len(sym)) 55 yield ('{} {:<8} {} (count={}) padding={} '
56 'size_without_padding={}').format(
57 sym.section, sym.size, sym.name, len(sym), sym.padding,
58 sym.size_without_padding)
59 else:
60 yield '{} {:<8} {} (count={})'.format(sym.section, sym.size, sym.name,
61 len(sym))
37 return 62 return
38 63
39 yield '{}@0x{:<8x} {:<7} {}'.format( 64 if self.verbose:
40 sym.section, sym.address, sym.size, 65 yield '{}@0x{:<8x} size={} padding={} size_without_padding={}'.format(
41 sym.source_path or sym.object_path or '{no path}') 66 sym.section, sym.address, sym.size, sym.padding,
42 if sym.name: 67 sym.size_without_padding)
43 yield '{:22}{}'.format('', sym.name) 68 yield ' source_path={} \tobject_path={}'.format(
69 sym.source_path, sym.object_path)
70 if sym.full_name:
71 yield ' full_name={} \tis_anonymous={}'.format(
72 sym.full_name, sym.is_anonymous)
73 if sym.name:
74 yield ' name={} \tis_anonymous={}'.format(
75 sym.name, sym.is_anonymous)
76 else:
77 yield '{}@0x{:<8x} {:<7} {}'.format(
78 sym.section, sym.address, sym.size,
79 sym.source_path or sym.object_path or '{no path}')
80 if sym.name:
81 yield ' {}'.format(sym.name)
44 82
45 def _DescribeSymbolGroup(self, group, prefix_func=None): 83 def _DescribeSymbolGroup(self, group, prefix_func=None):
46 yield 'Showing {:,} symbols with total size: {:} bytes'.format( 84 total_size = group.size
47 len(group), group.size) 85 yield 'Showing {:,} symbols with total size: {} bytes'.format(
86 len(group), total_size)
87 code_syms = group.WhereInSection('t')
88 code_size = code_syms.size
89 ro_size = code_syms.Inverted().WhereInSection('r').size
90 yield '.text={:<10} .rodata={:<10} other={:<10} total={}'.format(
91 _PrettySize(code_size), _PrettySize(ro_size),
92 _PrettySize(total_size - code_size - ro_size),
93 _PrettySize(total_size))
48 yield 'First columns are: running total, type, size' 94 yield 'First columns are: running total, type, size'
49 95
50 running_total = 0 96 running_total = 0
51 prefix = '' 97 prefix = ''
98 sorted_syms = group if group.is_sorted else group.Sorted()
52 99
53 for s in group.Sorted(): 100 prefix = ''
101 for s in sorted_syms:
54 if group.IsBss() or not s.IsBss(): 102 if group.IsBss() or not s.IsBss():
55 running_total += s.size 103 running_total += s.size
56 if prefix_func:
57 prefix = prefix_func(s)
58 for l in self._DescribeSymbol(s): 104 for l in self._DescribeSymbol(s):
59 yield '{}{:8} {}'.format(prefix, running_total, l) 105 if l[:4].isspace():
106 yield '{} {}'.format(' ' * (8 + len(prefix)), l)
107 else:
108 if prefix_func:
109 prefix = prefix_func(s)
110 yield '{}{:8} {}'.format(prefix, running_total, l)
60 111
61 def _DescribeSymbolDiff(self, diff): 112 def _DescribeSymbolDiff(self, diff):
62 template = ('{} symbols added (+), {} changed (~), {} removed (-), ' 113 template = ('{} symbols added (+), {} changed (~), {} removed (-), '
63 '{} unchanged ({})') 114 '{} unchanged ({})')
64 unchanged_msg = '=' if self.verbose else 'not shown' 115 unchanged_msg = '=' if self.verbose else 'not shown'
65 header_str = (template.format( 116 header_str = (template.format(
66 diff.added_count, diff.changed_count, diff.removed_count, 117 diff.added_count, diff.changed_count, diff.removed_count,
67 diff.unchanged_count, unchanged_msg)) 118 diff.unchanged_count, unchanged_msg))
68 119
69 def prefix_func(sym): 120 def prefix_func(sym):
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 epoch = time.mktime(utc.timetuple()) 188 epoch = time.mktime(utc.timetuple())
138 offset = (datetime.datetime.fromtimestamp(epoch) - 189 offset = (datetime.datetime.fromtimestamp(epoch) -
139 datetime.datetime.utcfromtimestamp(epoch)) 190 datetime.datetime.utcfromtimestamp(epoch))
140 return utc + offset 191 return utc + offset
141 192
142 193
143 def DescribeSizeInfoMetadata(size_info): 194 def DescribeSizeInfoMetadata(size_info):
144 time_str = 'Unknown' 195 time_str = 'Unknown'
145 if size_info.timestamp: 196 if size_info.timestamp:
146 time_str = _UtcToLocal(size_info.timestamp).strftime('%Y-%m-%d %H:%M:%S') 197 time_str = _UtcToLocal(size_info.timestamp).strftime('%Y-%m-%d %H:%M:%S')
147 return 'time=%s tag=%s' % (time_str, size_info.tag) 198 return 'mapfile mtime=%s \ttag=%s' % (time_str, size_info.tag)
148 199
149 200
150 def GenerateLines(obj, verbose=False): 201 def GenerateLines(obj, verbose=False):
151 return Describer(verbose).GenerateLines(obj) 202 return Describer(verbose).GenerateLines(obj)
152 203
153 204
154 def WriteLines(lines, func): 205 def WriteLines(lines, func):
155 for l in lines: 206 for l in lines:
156 func(l) 207 func(l)
157 func('\n') 208 func('\n')
OLDNEW
« no previous file with comments | « tools/binary_size/console.py ('k') | tools/binary_size/integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698