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

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

Issue 2857153002: supersize: Tweak diff symbol matching for generated symbols (Closed)
Patch Set: review Created 3 years, 7 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
« no previous file with comments | « no previous file | tools/binary_size/libsupersize/integration_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 """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 8
8 import models 9 import models
9 10
10 11
12 def _SymbolKey(symbol):
13 """Returns a tuple that can be used to see if two Symbol are the same.
14
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.
17 We do this because the numbering of these generated symbols is not stable.
18
19 Examples of symbols with shared keys:
20 "** merge strings"
21 "** symbol gap 3", "** symbol gap 5"
22 "foo() [clone ##]"
23 "CSWTCH.61", "CSWTCH.62"
24 "._468", "._467"
25 ".L__unnamed_1193", ".L__unnamed_712"
26 """
27 name = symbol.full_name or symbol.name
28 clone_idx = name.find(' [clone ')
29 if clone_idx != -1:
30 name = name[:clone_idx]
31 if name.startswith('*'):
32 # "symbol gap 3 (bar)" -> "symbol gaps"
33 name = re.sub(r'\s+\d+( \(.*\))?$', 's', name)
34
35 if '.' not in name:
36 return (symbol.section_name, name)
37 # Compiler or Linker generated symbol.
38 name = re.sub(r'[.0-9]', '', name) # Strip out all numbers and dots.
39 return (symbol.section_name, name, symbol.object_path)
40
41
11 def _CloneSymbol(sym, size): 42 def _CloneSymbol(sym, size):
12 """Returns a copy of |sym| with an updated |size|. 43 """Returns a copy of |sym| with an updated |size|.
13 44
14 Padding and aliases are not copied. 45 Padding and aliases are not copied.
15 """ 46 """
16 return models.Symbol( 47 return models.Symbol(
17 sym.section_name, size, address=sym.address, name=sym.name, 48 sym.section_name, size, address=sym.address, name=sym.name,
18 source_path=sym.source_path, object_path=sym.object_path, 49 source_path=sym.source_path, object_path=sym.object_path,
19 full_name=sym.full_name, flags=sym.flags) 50 full_name=sym.full_name, flags=sym.flags)
20 51
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 else: 125 else:
95 cloned = _CloneSymbol(sym, -sym.size_without_padding) 126 cloned = _CloneSymbol(sym, -sym.size_without_padding)
96 cloned.padding = -sym.padding 127 cloned.padding = -sym.padding
97 ret[i] = cloned 128 ret[i] = cloned
98 return ret 129 return ret
99 130
100 131
101 def _DiffSymbolGroups(before, after): 132 def _DiffSymbolGroups(before, after):
102 before_symbols_by_key = collections.defaultdict(list) 133 before_symbols_by_key = collections.defaultdict(list)
103 for s in before: 134 for s in before:
104 before_symbols_by_key[s._Key()].append(s) 135 before_symbols_by_key[_SymbolKey(s)].append(s)
105 136
106 similar = [] 137 similar = []
107 diffed_symbol_by_after_aliases = {} 138 diffed_symbol_by_after_aliases = {}
108 matched_before_aliases = set() 139 matched_before_aliases = set()
109 unmatched_after_syms = [] 140 unmatched_after_syms = []
110 # For similar symbols, padding is zeroed out. In order to not lose the 141 # For similar symbols, padding is zeroed out. In order to not lose the
111 # information entirely, store it in aggregate. 142 # information entirely, store it in aggregate.
112 padding_by_section_name = collections.defaultdict(int) 143 padding_by_section_name = collections.defaultdict(int)
113 144
114 # Step 1: Create all delta symbols and record unmatched symbols. 145 # Step 1: Create all delta symbols and record unmatched symbols.
115 for after_sym in after: 146 for after_sym in after:
116 matching_syms = before_symbols_by_key.get(after_sym._Key()) 147 matching_syms = before_symbols_by_key.get(_SymbolKey(after_sym))
117 if matching_syms: 148 if matching_syms:
118 before_sym = matching_syms.pop(0) 149 before_sym = matching_syms.pop(0)
119 if before_sym.IsGroup() and after_sym.IsGroup(): 150 if before_sym.IsGroup() and after_sym.IsGroup():
120 similar.append(_DiffSymbolGroups(before_sym, after_sym)) 151 similar.append(_DiffSymbolGroups(before_sym, after_sym))
121 else: 152 else:
122 if before_sym.aliases: 153 if before_sym.aliases:
123 matched_before_aliases.add(id(before_sym.aliases)) 154 matched_before_aliases.add(id(before_sym.aliases))
124 similar.append( 155 similar.append(
125 _DiffSymbol(before_sym, after_sym, diffed_symbol_by_after_aliases, 156 _DiffSymbol(before_sym, after_sym, diffed_symbol_by_after_aliases,
126 padding_by_section_name)) 157 padding_by_section_name))
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 """ 189 """
159 assert isinstance(before, models.SizeInfo) 190 assert isinstance(before, models.SizeInfo)
160 assert isinstance(after, models.SizeInfo) 191 assert isinstance(after, models.SizeInfo)
161 section_sizes = {k: after.section_sizes[k] - v 192 section_sizes = {k: after.section_sizes[k] - v
162 for k, v in before.section_sizes.iteritems()} 193 for k, v in before.section_sizes.iteritems()}
163 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols) 194 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols)
164 if cluster: 195 if cluster:
165 symbol_diff = symbol_diff.Cluster() 196 symbol_diff = symbol_diff.Cluster()
166 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata, 197 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata,
167 after.metadata) 198 after.metadata)
OLDNEW
« no previous file with comments | « no previous file | tools/binary_size/libsupersize/integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698