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

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

Issue 2880003002: supersize: A few fixes for Android+clang builds (Closed)
Patch Set: rebase 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 | « tools/binary_size/README.md ('k') | tools/binary_size/libsupersize/function_signature.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 4
5 """Main Python API for analyzing binary size.""" 5 """Main Python API for analyzing binary size."""
6 6
7 import argparse 7 import argparse
8 import calendar 8 import calendar
9 import collections 9 import collections
10 import datetime 10 import datetime
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 name_list = aliases_by_address.get(s.address) 317 name_list = aliases_by_address.get(s.address)
318 if name_list: 318 if name_list:
319 if s.full_name not in name_list: 319 if s.full_name not in name_list:
320 logging.warning('Name missing from aliases: %s %s', s.full_name, 320 logging.warning('Name missing from aliases: %s %s', s.full_name,
321 name_list) 321 name_list)
322 continue 322 continue
323 replacements.append((i, name_list)) 323 replacements.append((i, name_list))
324 num_new_symbols += len(name_list) - 1 324 num_new_symbols += len(name_list) - 1
325 325
326 if float(num_new_symbols) / len(raw_symbols) < .05: 326 if float(num_new_symbols) / len(raw_symbols) < .05:
327 # TODO(agrieve): Figure out if there's a way to get alias information from
328 # clang-compiled nm.
327 logging.warning('Number of aliases is oddly low (%.0f%%). It should ' 329 logging.warning('Number of aliases is oddly low (%.0f%%). It should '
328 'usually be around 25%%. Ensure --tool-prefix is correct.', 330 'usually be around 25%%. Ensure --tool-prefix is correct. '
331 'Ignore this if you compiled with clang.',
329 float(num_new_symbols) / len(raw_symbols) * 100) 332 float(num_new_symbols) / len(raw_symbols) * 100)
330 333
331 # Step 2: Create new symbols as siblings to each existing one. 334 # Step 2: Create new symbols as siblings to each existing one.
332 logging.debug('Creating %d aliases', num_new_symbols) 335 logging.debug('Creating %d aliases', num_new_symbols)
333 src_cursor_end = len(raw_symbols) 336 src_cursor_end = len(raw_symbols)
334 raw_symbols += [None] * num_new_symbols 337 raw_symbols += [None] * num_new_symbols
335 dst_cursor_end = len(raw_symbols) 338 dst_cursor_end = len(raw_symbols)
336 for src_index, name_list in reversed(replacements): 339 for src_index, name_list in reversed(replacements):
337 # Copy over symbols that come after the current one. 340 # Copy over symbols that come after the current one.
338 chunk_size = src_cursor_end - src_index - 1 341 chunk_size = src_cursor_end - src_index - 1
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 gn_args = _ParseGnArgs(os.path.join(output_directory, 'args.gn')) 400 gn_args = _ParseGnArgs(os.path.join(output_directory, 'args.gn'))
398 metadata[models.METADATA_MAP_FILENAME] = relative_to_out(map_path) 401 metadata[models.METADATA_MAP_FILENAME] = relative_to_out(map_path)
399 metadata[models.METADATA_ELF_FILENAME] = relative_to_out(elf_path) 402 metadata[models.METADATA_ELF_FILENAME] = relative_to_out(elf_path)
400 metadata[models.METADATA_GN_ARGS] = gn_args 403 metadata[models.METADATA_GN_ARGS] = gn_args
401 404
402 if apk_path: 405 if apk_path:
403 metadata[models.METADATA_APK_FILENAME] = relative_to_out(apk_path) 406 metadata[models.METADATA_APK_FILENAME] = relative_to_out(apk_path)
404 return metadata 407 return metadata
405 408
406 409
407 def CreateSizeInfo(map_path, elf_path, tool_prefix, output_directory, 410 def CreateSizeInfo(map_path, elf_path, tool_prefix, output_directory):
408 raw_only=False):
409 """Creates a SizeInfo. 411 """Creates a SizeInfo.
410 412
411 Args: 413 Args:
412 map_path: Path to the linker .map(.gz) file to parse. 414 map_path: Path to the linker .map(.gz) file to parse.
413 elf_path: Path to the corresponding unstripped ELF file. Used to find symbol 415 elf_path: Path to the corresponding unstripped ELF file. Used to find symbol
414 aliases and inlined functions. Can be None. 416 aliases and inlined functions. Can be None.
415 tool_prefix: Prefix for c++filt & nm (required). 417 tool_prefix: Prefix for c++filt & nm (required).
416 output_directory: Build output directory. If None, source_paths and symbol 418 output_directory: Build output directory. If None, source_paths and symbol
417 alias information will not be recorded. 419 alias information will not be recorded.
418 raw_only: Fill in just the information required for creating a .size file.
419 """ 420 """
420 source_mapper = None 421 source_mapper = None
421 if output_directory: 422 if output_directory:
422 # Start by finding the elf_object_paths, so that nm can run on them while 423 # Start by finding the elf_object_paths, so that nm can run on them while
423 # the linker .map is being parsed. 424 # the linker .map is being parsed.
424 logging.info('Parsing ninja files.') 425 logging.info('Parsing ninja files.')
425 source_mapper, elf_object_paths = ninja_parser.Parse( 426 source_mapper, elf_object_paths = ninja_parser.Parse(
426 output_directory, elf_path) 427 output_directory, elf_path)
427 assert not elf_path or elf_object_paths, ( 428 assert not elf_path or elf_object_paths, (
428 'Failed to find link command in ninja files for ' + 429 'Failed to find link command in ninja files for ' +
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 _ComputeAnscestorPathsAndNormalizeObjectPaths( 501 _ComputeAnscestorPathsAndNormalizeObjectPaths(
501 raw_symbols, object_paths_by_name, source_mapper) 502 raw_symbols, object_paths_by_name, source_mapper)
502 503
503 if not elf_path or not output_directory: 504 if not elf_path or not output_directory:
504 logging.info('Normalizing object paths.') 505 logging.info('Normalizing object paths.')
505 for symbol in raw_symbols: 506 for symbol in raw_symbols:
506 symbol.object_path = _NormalizeObjectPath(symbol.object_path) 507 symbol.object_path = _NormalizeObjectPath(symbol.object_path)
507 508
508 size_info = models.SizeInfo(section_sizes, raw_symbols) 509 size_info = models.SizeInfo(section_sizes, raw_symbols)
509 510
510 # Name normalization not strictly required, but makes for smaller files. 511 # When creating the .size file, name normalization is not strictly required,
511 if raw_only: 512 # but makes for smaller files.
512 logging.info('Normalizing symbol names') 513 # Padding not required either, but it is useful to check for large padding and
513 _NormalizeNames(size_info.raw_symbols) 514 # log a warning.
514 else: 515 _PostProcessSizeInfo(size_info)
515 _PostProcessSizeInfo(size_info)
516 516
517 if logging.getLogger().isEnabledFor(logging.DEBUG): 517 if logging.getLogger().isEnabledFor(logging.INFO):
518 # Padding is reported in size coverage logs.
519 if raw_only:
520 _CalculatePadding(size_info.raw_symbols)
521 for line in describe.DescribeSizeInfoCoverage(size_info): 518 for line in describe.DescribeSizeInfoCoverage(size_info):
522 logging.info(line) 519 logging.info(line)
523 logging.info('Recorded info for %d symbols', len(size_info.raw_symbols)) 520 logging.info('Recorded info for %d symbols', len(size_info.raw_symbols))
524 return size_info 521 return size_info
525 522
526 523
527 def _DetectGitRevision(directory): 524 def _DetectGitRevision(directory):
528 try: 525 try:
529 git_rev = subprocess.check_output( 526 git_rev = subprocess.check_output(
530 ['git', '-C', directory, 'rev-parse', 'HEAD']) 527 ['git', '-C', directory, 'rev-parse', 'HEAD'])
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 if not args.no_source_paths: 654 if not args.no_source_paths:
658 output_directory = lazy_paths.VerifyOutputDirectory() 655 output_directory = lazy_paths.VerifyOutputDirectory()
659 656
660 metadata = CreateMetadata(map_path, elf_path, apk_path, tool_prefix, 657 metadata = CreateMetadata(map_path, elf_path, apk_path, tool_prefix,
661 output_directory) 658 output_directory)
662 if apk_path and elf_path: 659 if apk_path and elf_path:
663 # Extraction takes around 1 second, so do it in parallel. 660 # Extraction takes around 1 second, so do it in parallel.
664 apk_elf_result = concurrent.ForkAndCall( 661 apk_elf_result = concurrent.ForkAndCall(
665 _ElfInfoFromApk, (apk_path, apk_so_path, tool_prefix)) 662 _ElfInfoFromApk, (apk_path, apk_so_path, tool_prefix))
666 663
667 size_info = CreateSizeInfo( 664 size_info = CreateSizeInfo(map_path, elf_path, tool_prefix, output_directory)
668 map_path, elf_path, tool_prefix, output_directory, raw_only=True)
669 665
670 if metadata: 666 if metadata:
671 size_info.metadata = metadata 667 size_info.metadata = metadata
672 668
673 if apk_path: 669 if apk_path:
674 logging.debug('Extracting section sizes from .so within .apk') 670 logging.debug('Extracting section sizes from .so within .apk')
675 unstripped_section_sizes = size_info.section_sizes 671 unstripped_section_sizes = size_info.section_sizes
676 apk_build_id, size_info.section_sizes = apk_elf_result.get() 672 apk_build_id, size_info.section_sizes = apk_elf_result.get()
677 assert apk_build_id == metadata[models.METADATA_ELF_BUILD_ID], ( 673 assert apk_build_id == metadata[models.METADATA_ELF_BUILD_ID], (
678 'BuildID for %s within %s did not match the one at %s' % 674 'BuildID for %s within %s did not match the one at %s' %
(...skipping 13 matching lines...) Expand all
692 logging.warning('Packed section not present: %s', packed_section_name) 688 logging.warning('Packed section not present: %s', packed_section_name)
693 else: 689 else:
694 size_info.section_sizes['%s (unpacked)' % packed_section_name] = ( 690 size_info.section_sizes['%s (unpacked)' % packed_section_name] = (
695 unstripped_section_sizes.get(packed_section_name)) 691 unstripped_section_sizes.get(packed_section_name))
696 692
697 logging.info('Recording metadata: \n %s', 693 logging.info('Recording metadata: \n %s',
698 '\n '.join(describe.DescribeMetadata(size_info.metadata))) 694 '\n '.join(describe.DescribeMetadata(size_info.metadata)))
699 logging.info('Saving result to %s', args.size_file) 695 logging.info('Saving result to %s', args.size_file)
700 file_format.SaveSizeInfo(size_info, args.size_file) 696 file_format.SaveSizeInfo(size_info, args.size_file)
701 logging.info('Done') 697 logging.info('Done')
OLDNEW
« no previous file with comments | « tools/binary_size/README.md ('k') | tools/binary_size/libsupersize/function_signature.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698