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

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

Issue 2857153002: supersize: Tweak diff symbol matching for generated symbols (Closed)
Patch Set: 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
18 Examples of symbols with shared keys:
19 "** merge strings"
20 "** symbol gap 3", "** symbol gap 5"
21 "foo() [clone ##]"
22 "CSWTCH.61", "CSWTCH.62"
23 "._468", "._467"
24 ".L__unnamed_1193", ".L__unnamed_712"
25 """
26 name = symbol.full_name or symbol.name
27 if name:
estevenson 2017/05/03 17:29:06 nit: this check seems superfluous since the rest o
agrieve 2017/05/03 18:27:08 Done.
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.
estevenson 2017/05/03 17:29:06 Just to confirm I understand: On Linux there are
agrieve 2017/05/03 18:27:07 Updated the pydoc to make confirm the "why". But
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