| 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 """Logic for diffing two SizeInfo objects.""" | 4 """Logic for diffing two SizeInfo objects.""" |
| 5 | 5 |
| 6 import collections | 6 import collections |
| 7 import re | 7 import re |
| 8 | 8 |
| 9 import models | 9 import models |
| 10 | 10 |
| 11 | 11 |
| 12 def _SymbolKey(symbol): | 12 def _SymbolKey(symbol): |
| 13 """Returns a tuple that can be used to see if two Symbol are the same. | 13 """Returns a tuple that can be used to see if two Symbol are the same. |
| 14 | 14 |
| 15 Keys are not guaranteed to be unique within a SymbolGroup. When multiple | 15 Keys are not guaranteed to be unique within a SymbolGroup. When multiple |
| 16 symbols have the same key, they will be matched up in order of appearance. | 16 symbols have the same key, they will be matched up in order of appearance. |
| 17 We do this because the numbering of these generated symbols is not stable. | 17 We do this because the numbering of these generated symbols is not stable. |
| 18 | 18 |
| 19 Examples of symbols with shared keys: | 19 Examples of symbols with shared keys: |
| 20 "** merge strings" | 20 "** merge strings" |
| 21 "** symbol gap 3", "** symbol gap 5" | 21 "** symbol gap 3", "** symbol gap 5" |
| 22 "foo() [clone ##]" | 22 "foo() [clone ##]" |
| 23 "CSWTCH.61", "CSWTCH.62" | 23 "CSWTCH.61", "CSWTCH.62" |
| 24 "._468", "._467" | 24 "._468", "._467" |
| 25 ".L__unnamed_1193", ".L__unnamed_712" | 25 ".L__unnamed_1193", ".L__unnamed_712" |
| 26 """ | 26 """ |
| 27 name = symbol.full_name or symbol.name | 27 name = symbol.full_name |
| 28 clone_idx = name.find(' [clone ') | 28 clone_idx = name.find(' [clone ') |
| 29 if clone_idx != -1: | 29 if clone_idx != -1: |
| 30 name = name[:clone_idx] | 30 name = name[:clone_idx] |
| 31 if name.startswith('*'): | 31 if name.startswith('*'): |
| 32 # "symbol gap 3 (bar)" -> "symbol gaps" | 32 # "symbol gap 3 (bar)" -> "symbol gaps" |
| 33 name = re.sub(r'\s+\d+( \(.*\))?$', 's', name) | 33 name = re.sub(r'\s+\d+( \(.*\))?$', 's', name) |
| 34 | 34 |
| 35 if '.' not in name: | 35 if '.' not in name: |
| 36 return (symbol.section_name, name) | 36 return (symbol.section_name, name) |
| 37 # Compiler or Linker generated symbol. | 37 # Compiler or Linker generated symbol. |
| 38 name = re.sub(r'[.0-9]', '', name) # Strip out all numbers and dots. | 38 name = re.sub(r'[.0-9]', '', name) # Strip out all numbers and dots. |
| 39 return (symbol.section_name, name, symbol.object_path) | 39 return (symbol.section_name, name, symbol.object_path) |
| 40 | 40 |
| 41 | 41 |
| 42 def _CloneSymbol(sym, size): | 42 def _CloneSymbol(sym, size): |
| 43 """Returns a copy of |sym| with an updated |size|. | 43 """Returns a copy of |sym| with an updated |size|. |
| 44 | 44 |
| 45 Padding and aliases are not copied. | 45 Padding and aliases are not copied. |
| 46 """ | 46 """ |
| 47 return models.Symbol( | 47 return models.Symbol( |
| 48 sym.section_name, size, address=sym.address, name=sym.name, | 48 sym.section_name, size, address=sym.address, full_name=sym.full_name, |
| 49 source_path=sym.source_path, object_path=sym.object_path, | 49 template_name=sym.template_name, name=sym.name, |
| 50 full_name=sym.full_name, flags=sym.flags) | 50 source_path=sym.source_path, object_path=sym.object_path, flags=sym.flags) |
| 51 | 51 |
| 52 | 52 |
| 53 def _CloneAlias(sym, diffed_alias): | 53 def _CloneAlias(sym, diffed_alias): |
| 54 """Returns a copy of |sym| and making it an alias of |diffed_alias|.""" | 54 """Returns a copy of |sym| and making it an alias of |diffed_alias|.""" |
| 55 ret = _CloneSymbol(sym, diffed_alias.size_without_padding) | 55 ret = _CloneSymbol(sym, diffed_alias.size_without_padding) |
| 56 ret.padding = diffed_alias.padding | 56 ret.padding = diffed_alias.padding |
| 57 ret.aliases = diffed_alias.aliases | 57 ret.aliases = diffed_alias.aliases |
| 58 ret.aliases.append(ret) | 58 ret.aliases.append(ret) |
| 59 return ret | 59 return ret |
| 60 | 60 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 for remaining_syms in before_symbols_by_key.itervalues(): | 168 for remaining_syms in before_symbols_by_key.itervalues(): |
| 169 removed.extend(_NegateAndClone(remaining_syms, matched_before_aliases, | 169 removed.extend(_NegateAndClone(remaining_syms, matched_before_aliases, |
| 170 negated_symbol_by_before_aliases)) | 170 negated_symbol_by_before_aliases)) |
| 171 | 171 |
| 172 # Step 4: Create ** symbols to represent padding differences. | 172 # Step 4: Create ** symbols to represent padding differences. |
| 173 for section_name, padding in padding_by_section_name.iteritems(): | 173 for section_name, padding in padding_by_section_name.iteritems(): |
| 174 if padding != 0: | 174 if padding != 0: |
| 175 similar.append(models.Symbol( | 175 similar.append(models.Symbol( |
| 176 section_name, padding, | 176 section_name, padding, |
| 177 name="** aggregate padding of diff'ed symbols")) | 177 name="** aggregate padding of diff'ed symbols")) |
| 178 return models.SymbolDiff( | 178 return models.SymbolDiff(added, removed, similar) |
| 179 added, removed, similar, name=after.name, full_name=after.full_name, | |
| 180 section_name=after.section_name) | |
| 181 | 179 |
| 182 | 180 |
| 183 def Diff(before, after): | 181 def Diff(before, after): |
| 184 """Diffs two SizeInfo objects. Returns a SizeInfoDiff.""" | 182 """Diffs two SizeInfo objects. Returns a SizeInfoDiff.""" |
| 185 assert isinstance(before, models.SizeInfo) | 183 assert isinstance(before, models.SizeInfo) |
| 186 assert isinstance(after, models.SizeInfo) | 184 assert isinstance(after, models.SizeInfo) |
| 187 section_sizes = {k: after.section_sizes[k] - v | 185 section_sizes = {k: after.section_sizes[k] - v |
| 188 for k, v in before.section_sizes.iteritems()} | 186 for k, v in before.section_sizes.iteritems()} |
| 189 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols) | 187 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols) |
| 190 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata, | 188 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata, |
| 191 after.metadata) | 189 after.metadata) |
| OLD | NEW |