| 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 itertools | 7 import itertools |
| 8 import time |
| 7 | 9 |
| 8 import models | 10 import models |
| 9 | 11 |
| 10 | 12 |
| 11 class Describer(object): | 13 class Describer(object): |
| 12 def __init__(self, verbose=False): | 14 def __init__(self, verbose=False): |
| 13 self.verbose = verbose | 15 self.verbose = verbose |
| 14 | 16 |
| 15 def _DescribeSectionSizes(self, section_sizes): | 17 def _DescribeSectionSizes(self, section_sizes): |
| 16 relevant_names = models.SECTION_TO_SECTION_NAME.values() | 18 relevant_names = models.SECTION_TO_SECTION_NAME.values() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 28 yield '{}: {:,} bytes ({:.1%})'.format(name, size, percent) | 30 yield '{}: {:,} bytes ({:.1%})'.format(name, size, percent) |
| 29 | 31 |
| 30 def _DescribeSymbol(self, sym): | 32 def _DescribeSymbol(self, sym): |
| 31 # SymbolGroups are passed here when we don't want to expand them. | 33 # SymbolGroups are passed here when we don't want to expand them. |
| 32 if sym.IsGroup(): | 34 if sym.IsGroup(): |
| 33 yield '{} {:<8} {} (count={})'.format(sym.section, sym.size, sym.name, | 35 yield '{} {:<8} {} (count={})'.format(sym.section, sym.size, sym.name, |
| 34 len(sym)) | 36 len(sym)) |
| 35 return | 37 return |
| 36 | 38 |
| 37 yield '{}@0x{:<8x} {:<7} {}'.format( | 39 yield '{}@0x{:<8x} {:<7} {}'.format( |
| 38 sym.section, sym.address, sym.size, sym.path or '<no path>') | 40 sym.section, sym.address, sym.size, |
| 41 sym.source_path or sym.object_path or '{no path}') |
| 39 if sym.name: | 42 if sym.name: |
| 40 yield '{:22}{}'.format('', sym.name) | 43 yield '{:22}{}'.format('', sym.name) |
| 41 | 44 |
| 42 def _DescribeSymbolGroup(self, group, prefix_func=None): | 45 def _DescribeSymbolGroup(self, group, prefix_func=None): |
| 43 yield 'Showing {:,} symbols with total size: {:} bytes'.format( | 46 yield 'Showing {:,} symbols with total size: {:} bytes'.format( |
| 44 len(group), group.size) | 47 len(group), group.size) |
| 45 yield 'First columns are: running total, type, size' | 48 yield 'First columns are: running total, type, size' |
| 46 | 49 |
| 47 running_total = 0 | 50 running_total = 0 |
| 48 prefix = '' | 51 prefix = '' |
| (...skipping 22 matching lines...) Expand all Loading... |
| 71 if sym.size: | 74 if sym.size: |
| 72 return '~ ' | 75 return '~ ' |
| 73 return '= ' | 76 return '= ' |
| 74 | 77 |
| 75 diff = diff if self.verbose else diff.WhereNotUnchanged() | 78 diff = diff if self.verbose else diff.WhereNotUnchanged() |
| 76 group_desc = self._DescribeSymbolGroup(diff, prefix_func=prefix_func) | 79 group_desc = self._DescribeSymbolGroup(diff, prefix_func=prefix_func) |
| 77 return itertools.chain((header_str,), group_desc) | 80 return itertools.chain((header_str,), group_desc) |
| 78 | 81 |
| 79 def GenerateLines(self, obj): | 82 def GenerateLines(self, obj): |
| 80 if isinstance(obj, models.SizeInfo): | 83 if isinstance(obj, models.SizeInfo): |
| 84 metadata_desc = 'Metadata: %s' % DescribeSizeInfoMetadata(obj) |
| 81 section_desc = self._DescribeSectionSizes(obj.section_sizes) | 85 section_desc = self._DescribeSectionSizes(obj.section_sizes) |
| 82 group_desc = self.GenerateLines(obj.symbols) | 86 group_desc = self.GenerateLines(obj.symbols) |
| 83 return itertools.chain(section_desc, ('',), group_desc) | 87 return itertools.chain((metadata_desc,), section_desc, ('',), group_desc) |
| 84 | 88 |
| 85 if isinstance(obj, models.SymbolDiff): | 89 if isinstance(obj, models.SymbolDiff): |
| 86 return self._DescribeSymbolDiff(obj) | 90 return self._DescribeSymbolDiff(obj) |
| 87 | 91 |
| 88 if isinstance(obj, models.SymbolGroup): | 92 if isinstance(obj, models.SymbolGroup): |
| 89 return self._DescribeSymbolGroup(obj) | 93 return self._DescribeSymbolGroup(obj) |
| 90 | 94 |
| 91 if isinstance(obj, models.Symbol): | 95 if isinstance(obj, models.Symbol): |
| 92 return self._DescribeSymbol(obj) | 96 return self._DescribeSymbol(obj) |
| 93 | 97 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 122 attributed_syms = star_syms.Inverted().WhereHasAnyAttribution() | 126 attributed_syms = star_syms.Inverted().WhereHasAnyAttribution() |
| 123 anonymous_syms = attributed_syms.Inverted() | 127 anonymous_syms = attributed_syms.Inverted() |
| 124 if star_syms or anonymous_syms: | 128 if star_syms or anonymous_syms: |
| 125 missing_size = star_syms.size + anonymous_syms.size | 129 missing_size = star_syms.size + anonymous_syms.size |
| 126 yield ('+ Without %d merge sections and %d anonymous entries (' | 130 yield ('+ Without %d merge sections and %d anonymous entries (' |
| 127 'accounting for %d bytes):') % ( | 131 'accounting for %d bytes):') % ( |
| 128 len(star_syms), len(anonymous_syms), missing_size) | 132 len(star_syms), len(anonymous_syms), missing_size) |
| 129 yield '+ ' + one_stat(attributed_syms) | 133 yield '+ ' + one_stat(attributed_syms) |
| 130 | 134 |
| 131 | 135 |
| 136 def _UtcToLocal(utc): |
| 137 epoch = time.mktime(utc.timetuple()) |
| 138 offset = (datetime.datetime.fromtimestamp(epoch) - |
| 139 datetime.datetime.utcfromtimestamp(epoch)) |
| 140 return utc + offset |
| 141 |
| 142 |
| 143 def DescribeSizeInfoMetadata(size_info): |
| 144 time_str = 'Unknown' |
| 145 if size_info.timestamp: |
| 146 time_str = _UtcToLocal(size_info.timestamp).strftime('%Y-%m-%d %H:%M:%S') |
| 147 return 'time=%s tag=%s' % (time_str, size_info.tag) |
| 148 |
| 149 |
| 132 def GenerateLines(obj, verbose=False): | 150 def GenerateLines(obj, verbose=False): |
| 133 return Describer(verbose).GenerateLines(obj) | 151 return Describer(verbose).GenerateLines(obj) |
| 134 | 152 |
| 135 | 153 |
| 136 def WriteLines(lines, func): | 154 def WriteLines(lines, func): |
| 137 for l in lines: | 155 for l in lines: |
| 138 func(l) | 156 func(l) |
| 139 func('\n') | 157 func('\n') |
| OLD | NEW |