| Index: build/android/resource_sizes.py
|
| diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py
|
| index 9877cdf8056a6fcfadbfde4980a2d87c5371d517..d2ad748664c67f606bf88b782b817cecfb7a34bb 100755
|
| --- a/build/android/resource_sizes.py
|
| +++ b/build/android/resource_sizes.py
|
| @@ -16,6 +16,7 @@ import operator
|
| import optparse
|
| import os
|
| import re
|
| +import shutil
|
| import struct
|
| import sys
|
| import tempfile
|
| @@ -99,6 +100,49 @@ _DUMP_STATIC_INITIALIZERS_PATH = os.path.join(
|
| # Pragma exists when enable_resource_whitelist_generation=true.
|
| _RC_HEADER_RE = re.compile(
|
| r'^#define (?P<name>\w+) (?:_Pragma\(.*?\) )?(?P<id>\d+)$')
|
| +_READELF_SIZES_METRICS = {
|
| + 'text': ['.text'],
|
| + 'data': ['.data', '.rodata'],
|
| + 'relocations': ['.rel.dyn', '.rel.plt', '.data.rel.ro', '.data.rel.ro.loca'],
|
| + 'unwind': ['.ARM.extab', '.ARM.exidx'],
|
| + 'symbols': ['.dynsym', '.dynstr', '.dynamic', '.shstrtab', '.got', '.plt'],
|
| + 'bss': ['.bss'],
|
| + # Group any section headers not listed above into the "other" group in case
|
| + # section headers change over time.
|
| + # 'other': ['.hash', '.init_array', '.fini_array', '.comment',
|
| + # '.note.gnu.gold-ve', '.ARM.attributes', '.note.gnu.build-i',
|
| + # '.gnu.version', '.gnu.version_d', '.gnu.version_r']
|
| +}
|
| +
|
| +
|
| +def _ExtractMainLibSectionSizesFromApk(apk_path, main_lib_path):
|
| + tmpdir = tempfile.mkdtemp(suffix='_apk_extract')
|
| + grouped_section_sizes = collections.defaultdict(int)
|
| + try:
|
| + with zipfile.ZipFile(apk_path, 'r') as z:
|
| + extracted_lib_path = z.extract(main_lib_path, tmpdir)
|
| + section_sizes = _CreateSectionNameSizeMap(extracted_lib_path)
|
| +
|
| + for group_name, section_names in _READELF_SIZES_METRICS.iteritems():
|
| + for section_name in section_names:
|
| + grouped_section_sizes[group_name] += section_sizes.pop(section_name)
|
| +
|
| + grouped_section_sizes['other'] = sum(s for s in section_sizes.values())
|
| +
|
| + return grouped_section_sizes
|
| + finally:
|
| + shutil.rmtree(tmpdir)
|
| +
|
| +
|
| +def _CreateSectionNameSizeMap(so_path):
|
| + stdout = cmd_helper.GetCmdOutput(['readelf', '-S', so_path])
|
| + section_sizes = {}
|
| + # Matches [ 2] .dynsym DYNSYM 00000158 000158 004f70 10 A 3 1 4
|
| + for match in re.finditer(r'\[[\s\d]+\] (\..*)$', stdout, re.MULTILINE):
|
| + items = match.group(1).split()
|
| + section_sizes[items[0]] = int(items[4], 16)
|
| +
|
| + return section_sizes
|
|
|
|
|
| def CountStaticInitializers(so_path):
|
| @@ -365,6 +409,12 @@ def PrintApkAnalysis(apk_filename, chartjson=None):
|
| ReportPerfResult(chartjson, apk_basename + '_Specifics',
|
| 'other lib size', secondary_size, 'bytes')
|
|
|
| + main_lib_section_sizes = _ExtractMainLibSectionSizesFromApk(
|
| + apk_filename, main_lib_info.filename)
|
| + for metric_name, size in main_lib_section_sizes.iteritems():
|
| + ReportPerfResult(chartjson, apk_basename + '_MainLibInfo',
|
| + metric_name, size, 'bytes')
|
| +
|
| # Main metric that we want to monitor for jumps.
|
| normalized_apk_size = total_apk_size
|
| # Always look at uncompressed .dex & .so.
|
|
|