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

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

Issue 2828333003: supersize: Strip linker-added prefixes from symbol names (Closed)
Patch Set: 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
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 """Classes that comprise the data model for binary size analysis. 4 """Classes that comprise the data model for binary size analysis.
5 5
6 The primary classes are Symbol, and SymbolGroup. 6 The primary classes are Symbol, and SymbolGroup.
7 7
8 Description of common properties: 8 Description of common properties:
9 * address: The start address of the symbol. 9 * address: The start address of the symbol.
10 May be 0 (e.g. for .bss or for SymbolGroups). 10 May be 0 (e.g. for .bss or for SymbolGroups).
(...skipping 29 matching lines...) Expand all
40 METADATA_GN_ARGS = 'gn_args' 40 METADATA_GN_ARGS = 'gn_args'
41 41
42 42
43 SECTION_TO_SECTION_NAME = { 43 SECTION_TO_SECTION_NAME = {
44 'b': '.bss', 44 'b': '.bss',
45 'd': '.data', 45 'd': '.data',
46 'r': '.rodata', 46 'r': '.rodata',
47 't': '.text', 47 't': '.text',
48 } 48 }
49 49
50 FLAG_ANONYMOUS = 1
51 FLAG_STARTUP = 2
52 FLAG_UNLIKELY = 4
53 FLAG_REL = 8
54 FLAG_REL_LOCAL = 16
55
50 56
51 class SizeInfo(object): 57 class SizeInfo(object):
52 """Represents all size information for a single binary. 58 """Represents all size information for a single binary.
53 59
54 Fields: 60 Fields:
55 section_sizes: A dict of section_name -> size. 61 section_sizes: A dict of section_name -> size.
56 raw_symbols: A flat list of all symbols. 62 raw_symbols: A flat list of all symbols.
57 symbols: A SymbolGroup containing raw_symbols, but with some Symbols grouped 63 symbols: A SymbolGroup containing raw_symbols, but with some Symbols grouped
58 into sub-SymbolGroups. 64 into sub-SymbolGroups.
59 metadata: A dict. 65 metadata: A dict.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 return self.section_name[1] 121 return self.section_name[1]
116 122
117 @property 123 @property
118 def size_without_padding(self): 124 def size_without_padding(self):
119 return self.size - self.padding 125 return self.size - self.padding
120 126
121 @property 127 @property
122 def end_address(self): 128 def end_address(self):
123 return self.address + self.size_without_padding 129 return self.address + self.size_without_padding
124 130
131 @property
132 def is_anonymous(self):
133 return bool(self.flags & FLAG_ANONYMOUS)
134
135 def FlagsString(self):
136 # Most flags are 0.
137 flags = self.flags
138 if not flags:
139 return '{}'
140 parts = []
141 if flags & FLAG_ANONYMOUS:
142 parts.append('anon')
143 if flags & FLAG_STARTUP:
144 parts.append('startup')
145 if flags & FLAG_UNLIKELY:
146 parts.append('unlikely')
147 if flags & FLAG_REL:
148 parts.append('rel')
149 if flags & FLAG_REL_LOCAL:
150 parts.append('rel.loc')
151 return '{%s}' % ','.join(parts)
152
125 def IsBss(self): 153 def IsBss(self):
126 return self.section_name == '.bss' 154 return self.section_name == '.bss'
127 155
128 def IsGroup(self): 156 def IsGroup(self):
129 return False 157 return False
130 158
131 def IsGenerated(self): 159 def IsGenerated(self):
132 # TODO(agrieve): Also match generated functions such as: 160 # TODO(agrieve): Also match generated functions such as:
133 # startup._GLOBAL__sub_I_page_allocator.cc 161 # startup._GLOBAL__sub_I_page_allocator.cc
134 return self.name.endswith(']') and not self.name.endswith('[]') 162 return self.name.endswith(']') and not self.name.endswith('[]')
(...skipping 14 matching lines...) Expand all
149 177
150 class Symbol(BaseSymbol): 178 class Symbol(BaseSymbol):
151 """Represents a single symbol within a binary. 179 """Represents a single symbol within a binary.
152 180
153 Refer to module docs for field descriptions. 181 Refer to module docs for field descriptions.
154 """ 182 """
155 183
156 __slots__ = ( 184 __slots__ = (
157 'address', 185 'address',
158 'full_name', 186 'full_name',
159 'is_anonymous', 187 'flags',
160 'object_path', 188 'object_path',
161 'name', 189 'name',
162 'padding', 190 'padding',
163 'section_name', 191 'section_name',
164 'source_path', 192 'source_path',
165 'size', 193 'size',
166 ) 194 )
167 195
168 def __init__(self, section_name, size_without_padding, address=None, 196 def __init__(self, section_name, size_without_padding, address=None,
169 name=None, source_path=None, object_path=None, 197 name=None, source_path=None, object_path=None, full_name=None,
170 full_name=None, is_anonymous=False): 198 flags=0):
171 self.section_name = section_name 199 self.section_name = section_name
172 self.address = address or 0 200 self.address = address or 0
173 self.name = name or '' 201 self.name = name or ''
174 self.full_name = full_name or '' 202 self.full_name = full_name or ''
175 self.source_path = source_path or '' 203 self.source_path = source_path or ''
176 self.object_path = object_path or '' 204 self.object_path = object_path or ''
177 self.size = size_without_padding 205 self.size = size_without_padding
178 # Change this to be a bitfield of flags if ever there is a need to add 206 self.flags = flags
179 # another similar thing.
180 self.is_anonymous = is_anonymous
181 self.padding = 0 207 self.padding = 0
182 208
183 def __repr__(self): 209 def __repr__(self):
184 return ('%s@%x(size_without_padding=%d,padding=%d,name=%s,path=%s,anon=%d)' 210 return ('%s@%x(size_without_padding=%d,padding=%d,name=%s,path=%s,flags=%s)'
185 % (self.section_name, self.address, self.size_without_padding, 211 % (self.section_name, self.address, self.size_without_padding,
186 self.padding, self.name, self.source_path or self.object_path, 212 self.padding, self.name, self.source_path or self.object_path,
187 int(self.is_anonymous))) 213 self.FlagsString()))
188 214
189 215
190 class SymbolGroup(BaseSymbol): 216 class SymbolGroup(BaseSymbol):
191 """Represents a group of symbols using the same interface as Symbol. 217 """Represents a group of symbols using the same interface as Symbol.
192 218
193 SymbolGroups are immutable. All filtering / sorting will return new 219 SymbolGroups are immutable. All filtering / sorting will return new
194 SymbolGroups objects. 220 SymbolGroups objects.
195 221
196 Overrides many __functions__. E.g. the following are all valid: 222 Overrides many __functions__. E.g. the following are all valid:
197 * len(group) 223 * len(group)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 after_symbols = self._symbols + [s for s in other if id(s) not in self_ids] 288 after_symbols = self._symbols + [s for s in other if id(s) not in self_ids]
263 return self._CreateTransformed( 289 return self._CreateTransformed(
264 after_symbols, section_name=self.section_name, is_sorted=False) 290 after_symbols, section_name=self.section_name, is_sorted=False)
265 291
266 @property 292 @property
267 def address(self): 293 def address(self):
268 first = self._symbols[0].address 294 first = self._symbols[0].address
269 return first if all(s.address == first for s in self._symbols) else 0 295 return first if all(s.address == first for s in self._symbols) else 0
270 296
271 @property 297 @property
272 def is_anonymous(self): 298 def flags(self):
273 first = self._symbols[0].is_anonymous 299 first = self._symbols[0].flags
274 return first if all( 300 return first if all(s.flags == first for s in self._symbols) else 0
275 s.is_anonymous == first for s in self._symbols) else False
276 301
277 @property 302 @property
278 def object_path(self): 303 def object_path(self):
279 first = self._symbols[0].object_path 304 first = self._symbols[0].object_path
280 return first if all(s.object_path == first for s in self._symbols) else None 305 return first if all(s.object_path == first for s in self._symbols) else None
281 306
282 @property 307 @property
283 def source_path(self): 308 def source_path(self):
284 first = self._symbols[0].source_path 309 first = self._symbols[0].source_path
285 return first if all(s.source_path == first for s in self._symbols) else None 310 return first if all(s.source_path == first for s in self._symbols) else None
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 if before_sym.IsGroup() and after_sym.IsGroup(): 669 if before_sym.IsGroup() and after_sym.IsGroup():
645 merged_sym = _DiffSymbols(before_sym, after_sym) 670 merged_sym = _DiffSymbols(before_sym, after_sym)
646 else: 671 else:
647 size_diff = (after_sym.size_without_padding - 672 size_diff = (after_sym.size_without_padding -
648 before_sym.size_without_padding) 673 before_sym.size_without_padding)
649 merged_sym = Symbol(after_sym.section_name, size_diff, 674 merged_sym = Symbol(after_sym.section_name, size_diff,
650 address=after_sym.address, name=after_sym.name, 675 address=after_sym.address, name=after_sym.name,
651 source_path=after_sym.source_path, 676 source_path=after_sym.source_path,
652 object_path=after_sym.object_path, 677 object_path=after_sym.object_path,
653 full_name=after_sym.full_name, 678 full_name=after_sym.full_name,
654 is_anonymous=after_sym.is_anonymous) 679 flags=after_sym.flags)
655 680
656 # Diffs are more stable when comparing size without padding, except when 681 # Diffs are more stable when comparing size without padding, except when
657 # the symbol is a padding-only symbol. 682 # the symbol is a padding-only symbol.
658 if after_sym.size_without_padding == 0 and size_diff == 0: 683 if after_sym.size_without_padding == 0 and size_diff == 0:
659 merged_sym.padding = after_sym.padding - before_sym.padding 684 merged_sym.padding = after_sym.padding - before_sym.padding
660 else: 685 else:
661 padding_by_section_name[after_sym.section_name] += ( 686 padding_by_section_name[after_sym.section_name] += (
662 after_sym.padding - before_sym.padding) 687 after_sym.padding - before_sym.padding)
663 688
664 similar.append(merged_sym) 689 similar.append(merged_sym)
(...skipping 16 matching lines...) Expand all
681 706
682 def _ExtractPrefixBeforeSeparator(string, separator, count=1): 707 def _ExtractPrefixBeforeSeparator(string, separator, count=1):
683 idx = -len(separator) 708 idx = -len(separator)
684 prev_idx = None 709 prev_idx = None
685 for _ in xrange(count): 710 for _ in xrange(count):
686 idx = string.find(separator, idx + len(separator)) 711 idx = string.find(separator, idx + len(separator))
687 if idx < 0: 712 if idx < 0:
688 break 713 break
689 prev_idx = idx 714 prev_idx = idx
690 return string[:prev_idx] 715 return string[:prev_idx]
OLDNEW
« no previous file with comments | « tools/binary_size/libsupersize/file_format.py ('k') | tools/binary_size/libsupersize/testdata/ActualDiff.golden » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698