OLD | NEW |
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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 def DescribeSizeInfoCoverage(size_info): | 221 def DescribeSizeInfoCoverage(size_info): |
222 """Yields lines describing how accurate |size_info| is.""" | 222 """Yields lines describing how accurate |size_info| is.""" |
223 for section in models.SECTION_TO_SECTION_NAME: | 223 for section in models.SECTION_TO_SECTION_NAME: |
224 if section == 'd': | 224 if section == 'd': |
225 expected_size = sum(v for k, v in size_info.section_sizes.iteritems() | 225 expected_size = sum(v for k, v in size_info.section_sizes.iteritems() |
226 if k.startswith('.data')) | 226 if k.startswith('.data')) |
227 else: | 227 else: |
228 expected_size = size_info.section_sizes[ | 228 expected_size = size_info.section_sizes[ |
229 models.SECTION_TO_SECTION_NAME[section]] | 229 models.SECTION_TO_SECTION_NAME[section]] |
230 | 230 |
231 def one_stat(group): | |
232 template = ('Section {}: has {:.1%} of {} bytes accounted for from ' | |
233 '{} symbols. {} bytes are unaccounted for.') | |
234 actual_size = group.size | |
235 size_percent = float(actual_size) / expected_size | |
236 return template.format(section, size_percent, actual_size, len(group), | |
237 expected_size - actual_size) | |
238 | 231 |
239 in_section = size_info.symbols.WhereInSection(section) | 232 in_section = size_info.symbols.WhereInSection(section) |
240 yield one_stat(in_section) | 233 actual_size = in_section.size |
| 234 size_percent = float(actual_size) / expected_size |
| 235 yield ('Section {}: has {:.1%} of {} bytes accounted for from ' |
| 236 '{} symbols. {} bytes are unaccounted for.').format( |
| 237 section, size_percent, actual_size, len(in_section), |
| 238 expected_size - actual_size) |
| 239 star_syms = in_section.WhereNameMatches(r'^\*') |
| 240 padding = in_section.padding - star_syms.padding |
| 241 anonymous_syms = star_syms.Inverted().WhereHasAnyAttribution().Inverted() |
241 yield '* Padding accounts for {} bytes ({:.1%})'.format( | 242 yield '* Padding accounts for {} bytes ({:.1%})'.format( |
242 in_section.padding, float(in_section.padding) / in_section.size) | 243 padding, float(padding) / in_section.size) |
| 244 if len(star_syms): |
| 245 yield ('* {} placeholders (symbols that start with **) account for ' |
| 246 '{} bytes ({:.1%})').format( |
| 247 len(star_syms), star_syms.pss, star_syms.pss / in_section.size) |
| 248 if anonymous_syms: |
| 249 yield '* {} anonymous symbols account for {} bytes ({:.1%})'.format( |
| 250 len(anonymous_syms), int(anonymous_syms.pss), |
| 251 star_syms.pss / in_section.size) |
243 | 252 |
244 aliased_symbols = in_section.Filter(lambda s: s.aliases) | 253 aliased_symbols = in_section.Filter(lambda s: s.aliases) |
245 if len(aliased_symbols): | 254 if section == 't': |
246 uniques = sum(1 for s in aliased_symbols.IterUniqueSymbols()) | 255 if len(aliased_symbols): |
247 yield '* Contains {} aliases, mapped to {} addresses ({} bytes)'.format( | 256 uniques = sum(1 for s in aliased_symbols.IterUniqueSymbols()) |
248 len(aliased_symbols), uniques, aliased_symbols.size) | 257 yield ('* Contains {} aliases, mapped to {} unique addresses ' |
249 else: | 258 '({} bytes)').format( |
250 yield '* Contains 0 aliases' | 259 len(aliased_symbols), uniques, aliased_symbols.size) |
| 260 else: |
| 261 yield '* Contains 0 aliases' |
251 | 262 |
252 inlined_symbols = in_section.WhereObjectPathMatches('{shared}') | 263 inlined_symbols = in_section.WhereObjectPathMatches('{shared}') |
253 if len(inlined_symbols): | 264 if len(inlined_symbols): |
254 yield '* {} symbols have shared ownership ({} bytes)'.format( | 265 yield '* {} symbols have shared ownership ({} bytes)'.format( |
255 len(inlined_symbols), inlined_symbols.size) | 266 len(inlined_symbols), inlined_symbols.size) |
256 else: | 267 else: |
257 yield '* 0 symbols have shared ownership' | 268 yield '* 0 symbols have shared ownership' |
258 | 269 |
259 star_syms = in_section.WhereNameMatches(r'^\*') | |
260 attributed_syms = star_syms.Inverted().WhereHasAnyAttribution() | |
261 anonymous_syms = attributed_syms.Inverted() | |
262 if star_syms or anonymous_syms: | |
263 missing_size = star_syms.pss + anonymous_syms.pss | |
264 anon_str = '' | |
265 if len(anonymous_syms): | |
266 anon_str = 'and {} anonymous entries '.format(len(anonymous_syms)) | |
267 yield '* Without {} merge sections {}(accounting for {} bytes):'.format( | |
268 len(star_syms), anon_str, int(missing_size)) | |
269 yield ' * ' + one_stat(attributed_syms) | |
270 | 270 |
271 | 271 |
272 def _UtcToLocal(utc): | 272 def _UtcToLocal(utc): |
273 epoch = time.mktime(utc.timetuple()) | 273 epoch = time.mktime(utc.timetuple()) |
274 offset = (datetime.datetime.fromtimestamp(epoch) - | 274 offset = (datetime.datetime.fromtimestamp(epoch) - |
275 datetime.datetime.utcfromtimestamp(epoch)) | 275 datetime.datetime.utcfromtimestamp(epoch)) |
276 return utc + offset | 276 return utc + offset |
277 | 277 |
278 | 278 |
279 def DescribeMetadata(metadata): | 279 def DescribeMetadata(metadata): |
(...skipping 11 matching lines...) Expand all Loading... |
291 | 291 |
292 def GenerateLines(obj, verbose=False, recursive=False): | 292 def GenerateLines(obj, verbose=False, recursive=False): |
293 """Returns an iterable of lines (without \n) that describes |obj|.""" | 293 """Returns an iterable of lines (without \n) that describes |obj|.""" |
294 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj) | 294 return Describer(verbose=verbose, recursive=recursive).GenerateLines(obj) |
295 | 295 |
296 | 296 |
297 def WriteLines(lines, func): | 297 def WriteLines(lines, func): |
298 for l in lines: | 298 for l in lines: |
299 func(l) | 299 func(l) |
300 func('\n') | 300 func('\n') |
OLD | NEW |