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

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

Issue 2854173003: supersize: Don't cluster by default. Make Diff() accept only SizeInfo. (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
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 7
8 import models 8 import models
9 9
10 10
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 50
51 # If this is the first matched symbol of an alias group, initialize its 51 # If this is the first matched symbol of an alias group, initialize its
52 # aliases list. The remaining aliases will be appended when diff'ed. 52 # aliases list. The remaining aliases will be appended when diff'ed.
53 if after_sym.aliases: 53 if after_sym.aliases:
54 ret.aliases = [ret] 54 ret.aliases = [ret]
55 diffed_symbol_by_after_aliases[id(after_sym.aliases)] = ret 55 diffed_symbol_by_after_aliases[id(after_sym.aliases)] = ret
56 return ret 56 return ret
57 57
58 58
59 def _CloneUnmatched(after_symbols, diffed_symbol_by_after_aliases): 59 def _CloneUnmatched(after_symbols, diffed_symbol_by_after_aliases):
60 ret = [] 60 ret = [None] * len(after_symbols)
61 for sym in after_symbols: 61 for i, sym in enumerate(after_symbols):
62 cloned = sym 62 cloned = sym
63 if sym.IsGroup(): 63 if sym.aliases:
64 cloned = models.SymbolDiff(
65 [], _CloneUnmatched(sym, diffed_symbol_by_after_aliases), [],
66 name=sym.name, full_name=sym.full_name, section_name=sym.section_name)
67 elif sym.aliases:
68 diffed_alias = diffed_symbol_by_after_aliases.get(id(sym.aliases)) 64 diffed_alias = diffed_symbol_by_after_aliases.get(id(sym.aliases))
69 if diffed_alias: 65 if diffed_alias:
70 # At least one alias was diffed. 66 # At least one alias was diffed.
71 cloned = _CloneAlias(sym, diffed_alias) 67 cloned = _CloneAlias(sym, diffed_alias)
72 ret.append(cloned) 68 ret[i] = cloned
73 return ret 69 return ret
74 70
75 71
76 def _NegateAndClone(before_symbols, matched_before_aliases, 72 def _NegateAndClone(before_symbols, matched_before_aliases,
77 negated_symbol_by_before_aliases): 73 negated_symbol_by_before_aliases):
78 ret = [] 74 ret = [None] * len(before_symbols)
79 for sym in before_symbols: 75 for i, sym in enumerate(before_symbols):
80 if sym.IsGroup(): 76 if sym.aliases:
81 cloned = models.SymbolDiff( 77 negated_alias = negated_symbol_by_before_aliases.get(id(sym.aliases))
82 [], _NegateAndClone(sym, matched_before_aliases, 78 if negated_alias:
83 negated_symbol_by_before_aliases), [], 79 cloned = _CloneAlias(sym, negated_alias)
84 name=sym.name, full_name=sym.full_name, section_name=sym.section_name) 80 else:
81 all_aliases_removed = id(sym.aliases) not in matched_before_aliases
82 # If all alises are removed, then given them negative size to reflect
83 # the savings.
84 if all_aliases_removed:
85 cloned = _CloneSymbol(sym, -sym.size_without_padding)
86 cloned.padding = -sym.padding
87 else:
88 # But if only a subset of aliases are removed, do not actually treat
89 # them as aliases anymore, or else they will weigh down the PSS of
90 # the symbols that were not removed.
91 cloned = _CloneSymbol(sym, 0)
92 cloned.aliases = [cloned]
93 negated_symbol_by_before_aliases[id(sym.aliases)] = cloned
85 else: 94 else:
86 negated_alias = None 95 cloned = _CloneSymbol(sym, -sym.size_without_padding)
87 if sym.aliases: 96 cloned.padding = -sym.padding
88 negated_alias = negated_symbol_by_before_aliases.get(id(sym.aliases)) 97 ret[i] = cloned
89 if negated_alias:
90 cloned = _CloneAlias(sym, negated_alias)
91 else:
92 all_aliases_removed = id(sym.aliases) not in matched_before_aliases
93 # If all alises are removed, then given them negative size to reflect
94 # the savings.
95 if all_aliases_removed:
96 cloned = _CloneSymbol(sym, -sym.size_without_padding)
97 cloned.padding = -sym.padding
98 else:
99 # But if only a subset of aliases are removed, do not actually treat
100 # them as aliases anymore, or else they will weigh down the PSS of
101 # the symbols that were not removed.
102 cloned = _CloneSymbol(sym, 0)
103 cloned.aliases = [cloned]
104 negated_symbol_by_before_aliases[id(sym.aliases)] = cloned
105 else:
106 cloned = _CloneSymbol(sym, -sym.size_without_padding)
107 cloned.padding = -sym.padding
108 ret.append(cloned)
109 return ret 98 return ret
110 99
111 100
112 # TODO(agrieve): Diff logic does not work correctly when aliased symbols span
113 # mulitple groups. We should simplify by not allowing recursion (allow diffs
114 # only on SizeInfo, apply logic to raw_symbols, re-cluster after-the-fact.
115 def _DiffSymbolGroups(before, after): 101 def _DiffSymbolGroups(before, after):
116 before_symbols_by_key = collections.defaultdict(list) 102 before_symbols_by_key = collections.defaultdict(list)
117 for s in before: 103 for s in before:
118 before_symbols_by_key[s._Key()].append(s) 104 before_symbols_by_key[s._Key()].append(s)
119 105
120 similar = [] 106 similar = []
121 diffed_symbol_by_after_aliases = {} 107 diffed_symbol_by_after_aliases = {}
122 matched_before_aliases = set() 108 matched_before_aliases = set()
123 unmatched_after_syms = [] 109 unmatched_after_syms = []
124 # For similar symbols, padding is zeroed out. In order to not lose the 110 # For similar symbols, padding is zeroed out. In order to not lose the
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 for section_name, padding in padding_by_section_name.iteritems(): 142 for section_name, padding in padding_by_section_name.iteritems():
157 if padding != 0: 143 if padding != 0:
158 similar.append(models.Symbol( 144 similar.append(models.Symbol(
159 section_name, padding, 145 section_name, padding,
160 name="** aggregate padding of diff'ed symbols")) 146 name="** aggregate padding of diff'ed symbols"))
161 return models.SymbolDiff( 147 return models.SymbolDiff(
162 added, removed, similar, name=after.name, full_name=after.full_name, 148 added, removed, similar, name=after.name, full_name=after.full_name,
163 section_name=after.section_name) 149 section_name=after.section_name)
164 150
165 151
166 def Diff(before, after): 152 def Diff(before, after, cluster=True):
167 """Diffs two SizeInfo or SymbolGroup objects. 153 """Diffs two SizeInfo objects. Returns a SizeInfoDiff.
168 154
169 When diffing SizeInfos, a SizeInfoDiff is returned. 155 Args:
170 When diffing SymbolGroups, a SymbolDiff is returned. 156 cluster: When True, calls SymbolGroup.Cluster() after diffing. This
171 157 generally reduces noise.
172 Returns:
173 Returns a SizeInfo when args are of type SizeInfo.
174 Returns a SymbolDiff when args are of type SymbolGroup.
175 """ 158 """
176 if isinstance(after, models.SizeInfo): 159 assert isinstance(before, models.SizeInfo)
177 assert isinstance(before, models.SizeInfo) 160 assert isinstance(after, models.SizeInfo)
178 section_sizes = {k: after.section_sizes[k] - v 161 section_sizes = {k: after.section_sizes[k] - v
179 for k, v in before.section_sizes.iteritems()} 162 for k, v in before.section_sizes.iteritems()}
180 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols) 163 symbol_diff = _DiffSymbolGroups(before.symbols, after.symbols)
181 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata, 164 if cluster:
182 after.metadata) 165 symbol_diff = symbol_diff.Cluster()
183 166 return models.SizeInfoDiff(section_sizes, symbol_diff, before.metadata,
184 assert (isinstance(after, models.SymbolGroup) and 167 after.metadata)
185 isinstance(before, models.SymbolGroup))
186 return _DiffSymbolGroups(before, after)
187
188
OLDNEW
« no previous file with comments | « tools/binary_size/libsupersize/describe.py ('k') | tools/binary_size/libsupersize/file_format.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698