| OLD | NEW |
| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 100 |
| 101 # We have now analyzed all symbols that are in cache1 and removed all of | 101 # We have now analyzed all symbols that are in cache1 and removed all of |
| 102 # the encountered symbols from cache2. What's left in cache2 is the new | 102 # the encountered symbols from cache2. What's left in cache2 is the new |
| 103 # symbols. | 103 # symbols. |
| 104 for key, bucket2 in cache2.iteritems(): | 104 for key, bucket2 in cache2.iteritems(): |
| 105 for symbol_name, symbol_size in bucket2.items(): | 105 for symbol_name, symbol_size in bucket2.items(): |
| 106 added.append((key[0], key[1], symbol_name, None, symbol_size)) | 106 added.append((key[0], key[1], symbol_name, None, symbol_size)) |
| 107 return (added, removed, changed, unchanged) | 107 return (added, removed, changed, unchanged) |
| 108 | 108 |
| 109 | 109 |
| 110 def TestCompare(): | |
| 111 # List entries have form: symbol_name, symbol_type, symbol_size, file_path | |
| 112 symbol_list1 = ( | |
| 113 # File with one symbol, left as-is. | |
| 114 ( 'unchanged', 't', 1000, '/file_unchanged' ), | |
| 115 # File with one symbol, changed. | |
| 116 ( 'changed', 't', 1000, '/file_all_changed' ), | |
| 117 # File with one symbol, deleted. | |
| 118 ( 'removed', 't', 1000, '/file_all_deleted' ), | |
| 119 # File with two symbols, one unchanged, one changed, same bucket | |
| 120 ( 'unchanged', 't', 1000, '/file_pair_unchanged_changed' ), | |
| 121 ( 'changed', 't', 1000, '/file_pair_unchanged_changed' ), | |
| 122 # File with two symbols, one unchanged, one deleted, same bucket | |
| 123 ( 'unchanged', 't', 1000, '/file_pair_unchanged_removed' ), | |
| 124 ( 'removed', 't', 1000, '/file_pair_unchanged_removed' ), | |
| 125 # File with two symbols, one unchanged, one added, same bucket | |
| 126 ( 'unchanged', 't', 1000, '/file_pair_unchanged_added' ), | |
| 127 # File with two symbols, one unchanged, one changed, different bucket | |
| 128 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_changed' ), | |
| 129 ( 'changed', '@', 1000, '/file_pair_unchanged_diffbuck_changed' ), | |
| 130 # File with two symbols, one unchanged, one deleted, different bucket | |
| 131 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_removed' ), | |
| 132 ( 'removed', '@', 1000, '/file_pair_unchanged_diffbuck_removed' ), | |
| 133 # File with two symbols, one unchanged, one added, different bucket | |
| 134 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_added' ), | |
| 135 # File with four symbols, one added, one removed, one changed, one unchanged | |
| 136 ( 'size_changed', 't', 1000, '/file_tetra' ), | |
| 137 ( 'removed', 't', 1000, '/file_tetra' ), | |
| 138 ( 'unchanged', 't', 1000, '/file_tetra' ), | |
| 139 ) | |
| 140 | |
| 141 symbol_list2 = ( | |
| 142 # File with one symbol, left as-is. | |
| 143 ( 'unchanged', 't', 1000, '/file_unchanged' ), | |
| 144 # File with one symbol, changed. | |
| 145 ( 'changed', 't', 2000, '/file_all_changed' ), | |
| 146 # File with two symbols, one unchanged, one changed, same bucket | |
| 147 ( 'unchanged', 't', 1000, '/file_pair_unchanged_changed' ), | |
| 148 ( 'changed', 't', 2000, '/file_pair_unchanged_changed' ), | |
| 149 # File with two symbols, one unchanged, one deleted, same bucket | |
| 150 ( 'unchanged', 't', 1000, '/file_pair_unchanged_removed' ), | |
| 151 # File with two symbols, one unchanged, one added, same bucket | |
| 152 ( 'unchanged', 't', 1000, '/file_pair_unchanged_added' ), | |
| 153 ( 'added', 't', 1000, '/file_pair_unchanged_added' ), | |
| 154 # File with two symbols, one unchanged, one changed, different bucket | |
| 155 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_changed' ), | |
| 156 ( 'changed', '@', 2000, '/file_pair_unchanged_diffbuck_changed' ), | |
| 157 # File with two symbols, one unchanged, one deleted, different bucket | |
| 158 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_removed' ), | |
| 159 # File with two symbols, one unchanged, one added, different bucket | |
| 160 ( 'unchanged', 't', 1000, '/file_pair_unchanged_diffbuck_added' ), | |
| 161 ( 'added', '@', 1000, '/file_pair_unchanged_diffbuck_added' ), | |
| 162 # File with four symbols, one added, one removed, one changed, one unchanged | |
| 163 ( 'size_changed', 't', 2000, '/file_tetra' ), | |
| 164 ( 'unchanged', 't', 1000, '/file_tetra' ), | |
| 165 ( 'added', 't', 1000, '/file_tetra' ), | |
| 166 # New file with one symbol added | |
| 167 ( 'added', 't', 1000, '/file_new' ), | |
| 168 ) | |
| 169 | |
| 170 # Here we go | |
| 171 (added, removed, changed, unchanged) = Compare(symbol_list1, symbol_list2) | |
| 172 | |
| 173 # File with one symbol, left as-is. | |
| 174 assert ('/file_unchanged', 't', 'unchanged', 1000, 1000) in unchanged | |
| 175 # File with one symbol, changed. | |
| 176 assert ('/file_all_changed', 't', 'changed', 1000, 2000) in changed | |
| 177 # File with one symbol, deleted. | |
| 178 assert ('/file_all_deleted', 't', 'removed', 1000, None) in removed | |
| 179 # New file with one symbol added | |
| 180 assert ('/file_new', 't', 'added', None, 1000) in added | |
| 181 # File with two symbols, one unchanged, one changed, same bucket | |
| 182 assert ('/file_pair_unchanged_changed', | |
| 183 't', 'unchanged', 1000, 1000) in unchanged | |
| 184 assert ('/file_pair_unchanged_changed', | |
| 185 't', 'changed', 1000, 2000) in changed | |
| 186 # File with two symbols, one unchanged, one removed, same bucket | |
| 187 assert ('/file_pair_unchanged_removed', | |
| 188 't', 'unchanged', 1000, 1000) in unchanged | |
| 189 assert ('/file_pair_unchanged_removed', | |
| 190 't', 'removed', 1000, None) in removed | |
| 191 # File with two symbols, one unchanged, one added, same bucket | |
| 192 assert ('/file_pair_unchanged_added', | |
| 193 't', 'unchanged', 1000, 1000) in unchanged | |
| 194 assert ('/file_pair_unchanged_added', | |
| 195 't', 'added', None, 1000) in added | |
| 196 # File with two symbols, one unchanged, one changed, different bucket | |
| 197 assert ('/file_pair_unchanged_diffbuck_changed', | |
| 198 't', 'unchanged', 1000, 1000) in unchanged | |
| 199 assert ('/file_pair_unchanged_diffbuck_changed', | |
| 200 '@', 'changed', 1000, 2000) in changed | |
| 201 # File with two symbols, one unchanged, one removed, different bucket | |
| 202 assert ('/file_pair_unchanged_diffbuck_removed', | |
| 203 't', 'unchanged', 1000, 1000) in unchanged | |
| 204 assert ('/file_pair_unchanged_diffbuck_removed', | |
| 205 '@', 'removed', 1000, None) in removed | |
| 206 # File with two symbols, one unchanged, one added, different bucket | |
| 207 assert ('/file_pair_unchanged_diffbuck_added', | |
| 208 't', 'unchanged', 1000, 1000) in unchanged | |
| 209 assert ('/file_pair_unchanged_diffbuck_added', | |
| 210 '@', 'added', None, 1000) in added | |
| 211 # File with four symbols, one added, one removed, one changed, one unchanged | |
| 212 assert ('/file_tetra', 't', 'size_changed', 1000, 2000) in changed | |
| 213 assert ('/file_tetra', 't', 'unchanged', 1000, 1000) in unchanged | |
| 214 assert ('/file_tetra', 't', 'added', None, 1000) in added | |
| 215 assert ('/file_tetra', 't', 'removed', 1000, None) in removed | |
| 216 | |
| 217 # Now check final stats. | |
| 218 CrunchStats(added, removed, changed, unchanged, True, True) | |
| 219 | |
| 220 | |
| 221 def CrunchStats(added, removed, changed, unchanged, showsources, showsymbols): | 110 def CrunchStats(added, removed, changed, unchanged, showsources, showsymbols): |
| 222 """Outputs to stdout a summary of changes based on the symbol lists.""" | 111 """Outputs to stdout a summary of changes based on the symbol lists.""" |
| 223 print 'Symbol statistics:' | 112 print 'Symbol statistics:' |
| 224 sources_with_new_symbols = set() | 113 sources_with_new_symbols = set() |
| 225 new_symbols_size = 0 | 114 new_symbols_size = 0 |
| 226 new_symbols_by_path = {} | 115 new_symbols_by_path = {} |
| 227 for file_path, symbol_type, symbol_name, size1, size2 in added: | 116 for file_path, symbol_type, symbol_name, size1, size2 in added: |
| 228 sources_with_new_symbols.add(file_path) | 117 sources_with_new_symbols.add(file_path) |
| 229 new_symbols_size += size2 | 118 new_symbols_size += size2 |
| 230 bucket = new_symbols_by_path.setdefault(file_path, []) | 119 bucket = new_symbols_by_path.setdefault(file_path, []) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 removed_sources = (sources_with_removed_symbols - | 166 removed_sources = (sources_with_removed_symbols - |
| 278 maybe_unchanged_sources - | 167 maybe_unchanged_sources - |
| 279 sources_with_new_symbols) | 168 sources_with_new_symbols) |
| 280 partially_changed_sources = (sources_with_changed_symbols | | 169 partially_changed_sources = (sources_with_changed_symbols | |
| 281 sources_with_new_symbols | | 170 sources_with_new_symbols | |
| 282 sources_with_removed_symbols) - removed_sources - new_sources | 171 sources_with_removed_symbols) - removed_sources - new_sources |
| 283 allFiles = (sources_with_new_symbols | | 172 allFiles = (sources_with_new_symbols | |
| 284 sources_with_removed_symbols | | 173 sources_with_removed_symbols | |
| 285 sources_with_changed_symbols | | 174 sources_with_changed_symbols | |
| 286 maybe_unchanged_sources) | 175 maybe_unchanged_sources) |
| 287 print 'Source stats: ' | 176 print 'Source stats:' |
| 288 print(' %d sources encountered.' % len(allFiles)) | 177 print(' %d sources encountered.' % len(allFiles)) |
| 289 print(' %d completely new.' % len(new_sources)) | 178 print(' %d completely new.' % len(new_sources)) |
| 290 print(' %d removed completely.' % len(removed_sources)) | 179 print(' %d removed completely.' % len(removed_sources)) |
| 291 print(' %d partially changed.' % len(partially_changed_sources)) | 180 print(' %d partially changed.' % len(partially_changed_sources)) |
| 292 print(' %d completely unchanged.' % len(unchanged_sources)) | 181 print(' %d completely unchanged.' % len(unchanged_sources)) |
| 293 remainder = (allFiles - new_sources - removed_sources - | 182 remainder = (allFiles - new_sources - removed_sources - |
| 294 partially_changed_sources - unchanged_sources) | 183 partially_changed_sources - unchanged_sources) |
| 295 assert len(remainder) == 0 | 184 assert len(remainder) == 0 |
| 296 | 185 |
| 297 if not showsources: | 186 if not showsources: |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 parser.add_option('--nm1', metavar='PATH', | 261 parser.add_option('--nm1', metavar='PATH', |
| 373 help='the nm dump of the first library') | 262 help='the nm dump of the first library') |
| 374 parser.add_option('--nm2', metavar='PATH', | 263 parser.add_option('--nm2', metavar='PATH', |
| 375 help='the nm dump of the second library') | 264 help='the nm dump of the second library') |
| 376 parser.add_option('--showsources', action='store_true', default=False, | 265 parser.add_option('--showsources', action='store_true', default=False, |
| 377 help='show per-source statistics') | 266 help='show per-source statistics') |
| 378 parser.add_option('--showsymbols', action='store_true', default=False, | 267 parser.add_option('--showsymbols', action='store_true', default=False, |
| 379 help='show all symbol information; implies --showfiles') | 268 help='show all symbol information; implies --showfiles') |
| 380 parser.add_option('--verbose', action='store_true', default=False, | 269 parser.add_option('--verbose', action='store_true', default=False, |
| 381 help='output internal debugging stuff') | 270 help='output internal debugging stuff') |
| 382 parser.add_option('--selftest', action='store_true', default=False, | |
| 383 help='run internal diagnosis') | |
| 384 opts, _args = parser.parse_args() | 271 opts, _args = parser.parse_args() |
| 385 | 272 |
| 386 if opts.selftest: | |
| 387 TestCompare() | |
| 388 return | |
| 389 | |
| 390 if not opts.nm1: | 273 if not opts.nm1: |
| 391 parser.error('--nm1 is required') | 274 parser.error('--nm1 is required') |
| 392 if not opts.nm2: | 275 if not opts.nm2: |
| 393 parser.error('--nm2 is required') | 276 parser.error('--nm2 is required') |
| 394 symbols = [] | 277 symbols = [] |
| 395 for path in [opts.nm1, opts.nm2]: | 278 for path in [opts.nm1, opts.nm2]: |
| 396 with file(path, 'r') as nm_input: | 279 with file(path, 'r') as nm_input: |
| 397 if opts.verbose: | 280 if opts.verbose: |
| 398 print 'parsing ' + path + '...' | 281 print 'parsing ' + path + '...' |
| 399 symbols.append(list(binary_size_utils.ParseNm(nm_input))) | 282 symbols.append(list(binary_size_utils.ParseNm(nm_input))) |
| 400 (added, removed, changed, unchanged) = Compare(symbols[0], symbols[1]) | 283 (added, removed, changed, unchanged) = Compare(symbols[0], symbols[1]) |
| 401 CrunchStats(added, removed, changed, unchanged, | 284 CrunchStats(added, removed, changed, unchanged, |
| 402 opts.showsources | opts.showsymbols, opts.showsymbols) | 285 opts.showsources | opts.showsymbols, opts.showsymbols) |
| 403 | 286 |
| 404 if __name__ == '__main__': | 287 if __name__ == '__main__': |
| 405 sys.exit(main()) | 288 sys.exit(main()) |
| OLD | NEW |