Chromium Code Reviews

Side by Side Diff: tools/binary_size/explain_binary_size_delta.py

Issue 397593007: Handle shared memory symbols better in the binarysize tool. (Closed)
Patch Set: Shared symbols: Rebased to newer master. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Describe the size difference of two binaries. 6 """Describe the size difference of two binaries.
7 7
8 Generates a description of the size difference of two binaries based 8 Generates a description of the size difference of two binaries based
9 on the difference of the size of various symbols. 9 on the difference of the size of various symbols.
10 10
(...skipping 20 matching lines...)
31 --nm-out /tmp/nm2.dump 31 --nm-out /tmp/nm2.dump
32 32
33 # cleanup useless files 33 # cleanup useless files
34 rm -r /tmp/throwaway 34 rm -r /tmp/throwaway
35 35
36 # run this tool 36 # run this tool
37 explain_binary_size_delta.py --nm1 /tmp/nm1.dump --nm2 /tmp/nm2.dump 37 explain_binary_size_delta.py --nm1 /tmp/nm1.dump --nm2 /tmp/nm2.dump
38 """ 38 """
39 39
40 import collections 40 import collections
41 from collections import Counter
42 from math import ceil
41 import operator 43 import operator
42 import optparse 44 import optparse
43 import os 45 import os
44 import sys 46 import sys
45 47
46 import binary_size_utils 48 import binary_size_utils
47 49
48 50
51 def CalculateSharedAddresses(symbols):
52 """Checks how many symbols share the same memory space."""
Andrew Hayden (chromium.org) 2015/02/16 12:47:38 Please document the return type.
Daniel Bratell 2015/02/18 13:31:53 Done.
53 count = Counter()
54 for _, _, _, _, address in symbols:
55 count[address] += 1
56
57 # metacount = Counter()
Andrew Hayden (chromium.org) 2015/02/16 12:47:38 Please remove the commented lines 57-61 or uncomme
Daniel Bratell 2015/02/18 13:31:53 Done.
58 # for share_count in count.itervalues():
59 # metacount[share_count] += 1
60 # for (key, value) in metacount.items():
61 # print("%d symbols were shared %d times" % ((value * key), key))
62 return count
63
49 def Compare(symbols1, symbols2): 64 def Compare(symbols1, symbols2):
50 """Executes a comparison of the symbols in symbols1 and symbols2. 65 """Executes a comparison of the symbols in symbols1 and symbols2.
51 66
52 Returns: 67 Returns:
53 tuple of lists: (added_symbols, removed_symbols, changed_symbols, others) 68 tuple of lists: (added_symbols, removed_symbols, changed_symbols, others)
54 """ 69 """
55 added = [] # tuples 70 added = [] # tuples
56 removed = [] # tuples 71 removed = [] # tuples
57 changed = [] # tuples 72 changed = [] # tuples
58 unchanged = [] # tuples 73 unchanged = [] # tuples
59 74
60 cache1 = {} 75 cache1 = {}
61 cache2 = {} 76 cache2 = {}
62 # Make a map of (file, symbol_type) : (symbol_name, symbol_size) 77 # Make a map of (file, symbol_type) : (symbol_name, effective_symbol_size)
63 for cache, symbols in ((cache1, symbols1), (cache2, symbols2)): 78 share_count1 = CalculateSharedAddresses(symbols1)
64 for symbol_name, symbol_type, symbol_size, file_path in symbols: 79 share_count2 = CalculateSharedAddresses(symbols2)
80 for cache, symbols, share_count in ((cache1, symbols1, share_count1),
81 (cache2, symbols2, share_count2)):
82 for symbol_name, symbol_type, symbol_size, file_path, address in symbols:
65 if 'vtable for ' in symbol_name: 83 if 'vtable for ' in symbol_name:
66 symbol_type = '@' # hack to categorize these separately 84 symbol_type = '@' # hack to categorize these separately
67 if file_path: 85 if file_path:
68 file_path = os.path.normpath(file_path) 86 file_path = os.path.normpath(file_path)
69 else: 87 else:
70 file_path = '(No Path)' 88 file_path = '(No Path)'
89 shared_count = share_count[address]
90 if shared_count == 1:
91 effective_symbol_size = symbol_size
92 else:
93 assert shared_count > 1
94 effective_symbol_size = int(ceil(symbol_size / float(shared_count)))
Andrew Hayden (chromium.org) 2015/02/16 12:47:38 For clarity, I'd prefer that we turn this line int
Daniel Bratell 2015/02/18 13:31:53 Done.
71 key = (file_path, symbol_type) 95 key = (file_path, symbol_type)
72 bucket = cache.setdefault(key, {}) 96 bucket = cache.setdefault(key, {})
73 size_list = bucket.setdefault(symbol_name, []) 97 size_list = bucket.setdefault(symbol_name, [])
74 size_list.append(symbol_size) 98 size_list.append(effective_symbol_size)
75 99
76 # Now diff them. We iterate over the elements in cache1. For each symbol 100 # Now diff them. We iterate over the elements in cache1. For each symbol
77 # that we find in cache2, we record whether it was deleted, changed, or 101 # that we find in cache2, we record whether it was deleted, changed, or
78 # unchanged. We then remove it from cache2; all the symbols that remain 102 # unchanged. We then remove it from cache2; all the symbols that remain
79 # in cache2 at the end of the iteration over cache1 are the 'new' symbols. 103 # in cache2 at the end of the iteration over cache1 are the 'new' symbols.
80 for key, bucket1 in cache1.items(): 104 for key, bucket1 in cache1.items():
81 bucket2 = cache2.get(key) 105 bucket2 = cache2.get(key)
82 if not bucket2: 106 if not bucket2:
83 # A file was removed. Everything in bucket1 is dead. 107 # A file was removed. Everything in bucket1 is dead.
84 for symbol_name, symbol_size_list in bucket1.items(): 108 for symbol_name, symbol_size_list in bucket1.items():
(...skipping 85 matching lines...)
170 else: 194 else:
171 shrunk.append(item) 195 shrunk.append(item)
172 196
173 new_symbols = CrunchStatsData(added) 197 new_symbols = CrunchStatsData(added)
174 removed_symbols = CrunchStatsData(removed) 198 removed_symbols = CrunchStatsData(removed)
175 grown_symbols = CrunchStatsData(grown) 199 grown_symbols = CrunchStatsData(grown)
176 shrunk_symbols = CrunchStatsData(shrunk) 200 shrunk_symbols = CrunchStatsData(shrunk)
177 sections = [new_symbols, removed_symbols, grown_symbols, shrunk_symbols] 201 sections = [new_symbols, removed_symbols, grown_symbols, shrunk_symbols]
178 for section in sections: 202 for section in sections:
179 for file_path, symbol_type, symbol_name, size1, size2 in section.symbols: 203 for file_path, symbol_type, symbol_name, size1, size2 in section.symbols:
204 assert not '&' in file_path, "File path: " + file_path
Andrew Hayden (chromium.org) 2015/02/16 12:47:38 Is there some context for this being added?
Daniel Bratell 2015/02/18 13:31:53 I really can't remember. Probably remains from som
180 section.sources.add(file_path) 205 section.sources.add(file_path)
181 if size1 is not None: 206 if size1 is not None:
182 section.before_size += size1 207 section.before_size += size1
183 if size2 is not None: 208 if size2 is not None:
184 section.after_size += size2 209 section.after_size += size2
185 bucket = section.symbols_by_path.setdefault(file_path, []) 210 bucket = section.symbols_by_path.setdefault(file_path, [])
186 bucket.append((symbol_name, symbol_type, size1, size2)) 211 bucket.append((symbol_name, symbol_type, size1, size2))
187 212
188 total_change = sum(s.after_size - s.before_size for s in sections) 213 total_change = sum(s.after_size - s.before_size for s in sections)
189 summary = 'Total change: %s bytes' % DeltaStr(total_change) 214 summary = 'Total change: %s bytes' % DeltaStr(total_change)
(...skipping 161 matching lines...)
351 with file(path, 'r') as nm_input: 376 with file(path, 'r') as nm_input:
352 if opts.verbose: 377 if opts.verbose:
353 print 'parsing ' + path + '...' 378 print 'parsing ' + path + '...'
354 symbols.append(list(binary_size_utils.ParseNm(nm_input))) 379 symbols.append(list(binary_size_utils.ParseNm(nm_input)))
355 (added, removed, changed, unchanged) = Compare(symbols[0], symbols[1]) 380 (added, removed, changed, unchanged) = Compare(symbols[0], symbols[1])
356 CrunchStats(added, removed, changed, unchanged, 381 CrunchStats(added, removed, changed, unchanged,
357 opts.showsources | opts.showsymbols, opts.showsymbols) 382 opts.showsources | opts.showsymbols, opts.showsymbols)
358 383
359 if __name__ == '__main__': 384 if __name__ == '__main__':
360 sys.exit(main()) 385 sys.exit(main())
OLDNEW

Powered by Google App Engine