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

Side by Side Diff: build/android/resource_sizes.py

Issue 2243343004: Revert of 🚀 Add dex info and static initializers to resource_sizes.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 | « build/android/method_count.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 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 """Prints the size of each given file and optionally computes the size of 6 """Prints the size of each given file and optionally computes the size of
7 libchrome.so without the dependencies added for building with android NDK. 7 libchrome.so without the dependencies added for building with android NDK.
8 Also breaks down the contents of the APK to determine the installed size 8 Also breaks down the contents of the APK to determine the installed size
9 and assign size contributions to different classes of file. 9 and assign size contributions to different classes of file.
10 """ 10 """
11 11
12 import collections 12 import collections
13 import json 13 import json
14 import logging 14 import logging
15 import operator 15 import operator
16 import optparse 16 import optparse
17 import os 17 import os
18 import re 18 import re
19 import struct 19 import struct
20 import sys 20 import sys
21 import tempfile 21 import tempfile
22 import zipfile 22 import zipfile
23 import zlib 23 import zlib
24 24
25 import devil_chromium 25 import devil_chromium
26 from devil.utils import cmd_helper 26 from devil.utils import cmd_helper
27 import method_count
28 from pylib import constants 27 from pylib import constants
29 from pylib.constants import host_paths 28 from pylib.constants import host_paths
30 29
31 _GRIT_PATH = os.path.join(host_paths.DIR_SOURCE_ROOT, 'tools', 'grit') 30 _GRIT_PATH = os.path.join(host_paths.DIR_SOURCE_ROOT, 'tools', 'grit')
32 31
33 # Prepend the grit module from the source tree so it takes precedence over other 32 # Prepend the grit module from the source tree so it takes precedence over other
34 # grit versions that might present in the search path. 33 # grit versions that might present in the search path.
35 with host_paths.SysPath(_GRIT_PATH, 1): 34 with host_paths.SysPath(_GRIT_PATH, 1):
36 from grit.format import data_pack # pylint: disable=import-error 35 from grit.format import data_pack # pylint: disable=import-error
37 36
38 with host_paths.SysPath(host_paths.BUILD_COMMON_PATH): 37 with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
39 import perf_tests_results_helper # pylint: disable=import-error 38 import perf_tests_results_helper # pylint: disable=import-error
40 39
41
42 # Python had a bug in zipinfo parsing that triggers on ChromeModern.apk 40 # Python had a bug in zipinfo parsing that triggers on ChromeModern.apk
43 # https://bugs.python.org/issue14315 41 # https://bugs.python.org/issue14315
44 def _PatchedDecodeExtra(self): 42 def _PatchedDecodeExtra(self):
45 # Try to decode the extra field. 43 # Try to decode the extra field.
46 extra = self.extra 44 extra = self.extra
47 unpack = struct.unpack 45 unpack = struct.unpack
48 while len(extra) >= 4: 46 while len(extra) >= 4:
49 tp, ln = unpack('<HH', extra[:4]) 47 tp, ln = unpack('<HH', extra[:4])
50 if tp == 1: 48 if tp == 1:
51 if ln >= 24: 49 if ln >= 24:
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 if m: 347 if m:
350 i = int(m.group('id')) 348 i = int(m.group('id'))
351 name = m.group('name') 349 name = m.group('name')
352 if i in id_name_map and name != id_name_map[i]: 350 if i in id_name_map and name != id_name_map[i]:
353 print 'WARNING: Resource ID conflict %s (%s vs %s)' % ( 351 print 'WARNING: Resource ID conflict %s (%s vs %s)' % (
354 i, id_name_map[i], name) 352 i, id_name_map[i], name)
355 id_name_map[i] = name 353 id_name_map[i] = name
356 return id_name_map 354 return id_name_map
357 355
358 356
359 def _PrintStaticInitializersCountFromApk(apk_filename, chartjson=None): 357 def PrintStaticInitializersCount(so_with_symbols_path, chartjson=None):
360 print 'Finding static initializers (can take a minute)' 358 """Emits the performance result for static initializers found in the provided
361 with zipfile.ZipFile(apk_filename) as z: 359 shared library. Additionally, files for which static initializers were
362 namelist = z.namelist() 360 found are printed on the standard output.
363 out_dir = constants.GetOutDirectory()
364 si_count = 0
365 for subpath in namelist:
366 if subpath.endswith('.so'):
367 unstripped_path = os.path.join(out_dir, 'lib.unstripped',
368 os.path.basename(subpath))
369 if os.path.exists(unstripped_path):
370 si_count += _PrintStaticInitializersCount(unstripped_path)
371 else:
372 raise Exception('Unstripped .so not found. Looked here: %s',
373 unstripped_path)
374 ReportPerfResult(chartjson, 'StaticInitializersCount', 'count', si_count,
375 'count')
376
377
378 def _PrintStaticInitializersCount(so_with_symbols_path):
379 """Counts the number of static initializers in the given shared library.
380 Additionally, files for which static initializers were found are printed
381 on the standard output.
382 361
383 Args: 362 Args:
384 so_with_symbols_path: Path to the unstripped libchrome.so file. 363 so_with_symbols_path: Path to the unstripped libchrome.so file.
385
386 Returns:
387 The number of static initializers found.
388 """ 364 """
389 # GetStaticInitializers uses get-static-initializers.py to get a list of all 365 # GetStaticInitializers uses get-static-initializers.py to get a list of all
390 # static initializers. This does not work on all archs (particularly arm). 366 # static initializers. This does not work on all archs (particularly arm).
391 # TODO(rnephew): Get rid of warning when crbug.com/585588 is fixed. 367 # TODO(rnephew): Get rid of warning when crbug.com/585588 is fixed.
392 si_count = CountStaticInitializers(so_with_symbols_path) 368 si_count = CountStaticInitializers(so_with_symbols_path)
393 static_initializers = GetStaticInitializers(so_with_symbols_path) 369 static_initializers = GetStaticInitializers(so_with_symbols_path)
394 static_initializers_count = len(static_initializers) - 1 # Minus summary. 370 if si_count != len(static_initializers):
395 if si_count != static_initializers_count:
396 print ('There are %d files with static initializers, but ' 371 print ('There are %d files with static initializers, but '
397 'dump-static-initializers found %d:' % 372 'dump-static-initializers found %d:' %
398 (si_count, static_initializers_count)) 373 (si_count, len(static_initializers)))
399 else: 374 else:
400 print '%s - Found %d files with static initializers:' % ( 375 print 'Found %d files with static initializers:' % si_count
401 os.path.basename(so_with_symbols_path), si_count)
402 print '\n'.join(static_initializers) 376 print '\n'.join(static_initializers)
403 377
404 return si_count 378 ReportPerfResult(chartjson, 'StaticInitializersCount', 'count',
379 si_count, 'count')
405 380
406 def _FormatBytes(byts): 381 def _FormatBytes(byts):
407 """Pretty-print a number of bytes.""" 382 """Pretty-print a number of bytes."""
408 if byts > 2**20.0: 383 if byts > 2**20.0:
409 byts /= 2**20.0 384 byts /= 2**20.0
410 return '%.2fm' % byts 385 return '%.2fm' % byts
411 if byts > 2**10.0: 386 if byts > 2**10.0:
412 byts /= 2**10.0 387 byts /= 2**10.0
413 return '%.2fk' % byts 388 return '%.2fk' % byts
414 return str(byts) 389 return str(byts)
415 390
416 391
417 def _CalculateCompressedSize(file_path): 392 def _CalculateCompressedSize(file_path):
418 CHUNK_SIZE = 256 * 1024 393 CHUNK_SIZE = 256 * 1024
419 compressor = zlib.compressobj() 394 compressor = zlib.compressobj()
420 total_size = 0 395 total_size = 0
421 with open(file_path, 'rb') as f: 396 with open(file_path, 'rb') as f:
422 for chunk in iter(lambda: f.read(CHUNK_SIZE), ''): 397 for chunk in iter(lambda: f.read(CHUNK_SIZE), ''):
423 total_size += len(compressor.compress(chunk)) 398 total_size += len(compressor.compress(chunk))
424 total_size += len(compressor.flush()) 399 total_size += len(compressor.flush())
425 return total_size 400 return total_size
426 401
427 402
428 def _PrintDexAnalysis(apk_filename, chartjson=None):
429 sizes = method_count.ExtractSizesFromZip(apk_filename)
430
431 graph_title = os.path.basename(apk_filename) + '_Dex'
432 dex_metrics = method_count.CONTRIBUTORS_TO_DEX_CACHE
433 for key, label in dex_metrics.iteritems():
434 ReportPerfResult(chartjson, graph_title, label, sizes[key], 'entries')
435
436 graph_title = '%sCache' % graph_title
437 ReportPerfResult(chartjson, graph_title, 'DexCache', sizes['dex_cache_size'],
438 'bytes')
439
440
441 def main(argv): 403 def main(argv):
442 usage = """Usage: %prog [options] file1 file2 ... 404 usage = """Usage: %prog [options] file1 file2 ...
443 405
444 Pass any number of files to graph their sizes. Any files with the extension 406 Pass any number of files to graph their sizes. Any files with the extension
445 '.apk' will be broken down into their components on a separate graph.""" 407 '.apk' will be broken down into their components on a separate graph."""
446 option_parser = optparse.OptionParser(usage=usage) 408 option_parser = optparse.OptionParser(usage=usage)
447 option_parser.add_option('--so-path', help='Path to libchrome.so.') 409 option_parser.add_option('--so-path', help='Path to libchrome.so.')
448 option_parser.add_option('--so-with-symbols-path', 410 option_parser.add_option('--so-with-symbols-path',
449 help='Path to libchrome.so with symbols.') 411 help='Path to libchrome.so with symbols.')
450 option_parser.add_option('--min-pak-resource-size', type='int', 412 option_parser.add_option('--min-pak-resource-size', type='int',
(...skipping 24 matching lines...) Expand all
475 # more. 437 # more.
476 if options.so_path: 438 if options.so_path:
477 files.append(options.so_path) 439 files.append(options.so_path)
478 440
479 if not files: 441 if not files:
480 option_parser.error('Must specify a file') 442 option_parser.error('Must specify a file')
481 443
482 devil_chromium.Initialize() 444 devil_chromium.Initialize()
483 445
484 if options.so_with_symbols_path: 446 if options.so_with_symbols_path:
485 si_count = _PrintStaticInitializersCount(options.so_with_symbols_path) 447 PrintStaticInitializersCount(
486 ReportPerfResult(chartjson, 'StaticInitializersCount', 'count', si_count, 448 options.so_with_symbols_path, chartjson=chartjson)
487 'count')
488 449
489 PrintResourceSizes(files, chartjson=chartjson) 450 PrintResourceSizes(files, chartjson=chartjson)
490 451
491 for f in files: 452 for f in files:
492 if f.endswith('.apk'): 453 if f.endswith('.apk'):
493 PrintApkAnalysis(f, chartjson=chartjson) 454 PrintApkAnalysis(f, chartjson=chartjson)
494 PrintPakAnalysis(f, options.min_pak_resource_size) 455 PrintPakAnalysis(f, options.min_pak_resource_size)
495 _PrintDexAnalysis(f, chartjson=chartjson)
496 if not options.so_with_symbols_path:
497 _PrintStaticInitializersCountFromApk(f, chartjson=chartjson)
498 456
499 if chartjson: 457 if chartjson:
500 results_path = os.path.join(options.output_dir, 'results-chart.json') 458 results_path = os.path.join(options.output_dir, 'results-chart.json')
501 logging.critical('Dumping json to %s', results_path) 459 logging.critical('Dumping json to %s', results_path)
502 with open(results_path, 'w') as json_file: 460 with open(results_path, 'w') as json_file:
503 json.dump(chartjson, json_file) 461 json.dump(chartjson, json_file)
504 462
505 463
506 if __name__ == '__main__': 464 if __name__ == '__main__':
507 sys.exit(main(sys.argv)) 465 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/method_count.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698