Chromium Code Reviews| Index: build/android/resource_sizes.py |
| diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py |
| index 9877cdf8056a6fcfadbfde4980a2d87c5371d517..af356fb1c92fcc7154cc3284338fa9513392df86 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,51 @@ _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_EXCLUDED_SECTIONS = ['.bss'] |
|
agrieve
2017/02/02 21:41:44
nit: I'm not sure why I suggested not including th
|
| +_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'], |
| + # 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( |
| + size for section_name, size in section_sizes.iteritems() |
| + if section_name not in _READELF_EXCLUDED_SECTIONS) |
| + |
| + 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 +411,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. |