| 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 |