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..9fe681e58bb4928153ff3b8a8957fdae41273953 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_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: |
| + if section_name in section_sizes: |
|
estevenson
2017/02/03 16:46:29
Another option would be to just skip the grouping
agrieve
2017/02/03 17:01:52
This is actually already more broken out than what
estevenson
2017/02/03 20:00:49
Acknowledged.
|
| + 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 |
|
agrieve
2017/02/03 17:01:52
nit: add a comment saying multiline happens for 64
estevenson
2017/02/03 20:00:49
Added --wide instead.
|
| + # 000158 004f70 10 A 3 1 4 |
| + for match in re.finditer(r'\[[\s\d]+\] (\.[^\[]*)', stdout): |
| + 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. |