# Copyright 2018 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Writes a Perf-formated json file with stats about Skia's size in flutter.""" from __future__ import print_function import json import os import subprocess import sys def main(): # This should be the stripped file from # out/android_release/lib.stripped/libflutter.so stripped_file = sys.argv[1] out_dir = sys.argv[2] keystr = sys.argv[3] propstr = sys.argv[4] bloaty_path = sys.argv[5] # This is the unstripped out/android_release/libflutter.so # The symbols in it are needed to get the compileunits data. symbols_file = sys.argv[6] config = sys.argv[7] total_size_bytes_key = sys.argv[8] lib_name = sys.argv[9] magic_seperator = sys.argv[10] results = { 'key': { }, 'results': { } } props = propstr.split(' ') for i in range(0, len(props), 2): results[props[i]] = props[i+1] keys = keystr.split(' ') for i in range(0, len(keys), 2): results['key'][keys[i]] = keys[i+1] # Human "readable" reports as an FYI. print(magic_seperator) print('Report by file, then by symbol with ellided/combined templates') lines = subprocess.check_output([bloaty_path, stripped_file, '-d', 'compileunits,symbols', '-s', 'file', '-n', '0', '--tsv', '--demangle=short', '--debug-file=%s' % symbols_file]) grand_total = print_skia_lines_file_symbol(lines) print(magic_seperator) print('Report by file, then by symbol with full templates') lines = subprocess.check_output([bloaty_path, stripped_file, '-d', 'compileunits,symbols', '-s', 'file', '-n', '0', '--tsv', '--demangle=full', '--debug-file=%s' % symbols_file]) print_skia_lines_file_symbol(lines) print(magic_seperator) print('Report by symbol, then by file with ellided/combined templates') lines = subprocess.check_output([bloaty_path, stripped_file, '-d', 'symbols,compileunits', '-s', 'file', '-n', '0', '--tsv', '--demangle=short', '--debug-file=%s' % symbols_file]) print_skia_lines_symbol_file(lines) print(magic_seperator) print('Report by symbol, then by file with full templates') lines = subprocess.check_output([bloaty_path, stripped_file, '-d', 'symbols,compileunits', '-s', 'file', '-n', '0', '--tsv', '--demangle=full', '--debug-file=%s' % symbols_file]) print_skia_lines_symbol_file(lines) print(magic_seperator) r = { # Use the default config as stats about the whole binary config : { total_size_bytes_key: grand_total }, } results['results'][lib_name] = r # Make debugging easier print(json.dumps(results, indent=2)) with open(os.path.join(out_dir, lib_name+'.json'), 'w') as output: output.write(json.dumps(results, indent=2)) def bytes_or_kb(num): if num < 1024: return '%d bytes' % num else: return '%1.1f KiB' % (num / 1024.0) def print_skia_lines_file_symbol(lines): lines = lines.split('\n') grand_total = 0 sub_total = 0 cur_file = '' for line in lines: # Line looks like: # ../../third_party/skia/src/file.cpp\tSkTSect<>::intersects()\t1224\t1348 parts = line.split('\t') if len(parts) != 4: continue this_file = parts[0] if 'third_party/skia' not in this_file: continue symbol = parts[1] if '.debug' in symbol: continue # vmsize = parts[2] Not needed filesize = int(parts[3]) if this_file != cur_file: if cur_file != '': print('\t%-100s: %s' % ('Total File Size', bytes_or_kb(sub_total))) sub_total = 0 cur_file = this_file print(this_file.replace('../../third_party/skia', 'skia')) print('\t%-100s: %s' % (symbol, bytes_or_kb(filesize))) sub_total += filesize grand_total += filesize print('\t%-100s: %s' % ('Total File Size', bytes_or_kb(sub_total))) print('=======================================') print('Grand Total File Size: %s' % bytes_or_kb(grand_total)) return grand_total def print_skia_lines_symbol_file(lines): lines = lines.split('\n') for line in lines: # Line looks like: # SkTSect<>::intersects()\t../../third_party/skia/src/file.cpp\t1224\t1348 parts = line.split('\t') if len(parts) != 4: continue symbol = parts[0] if 'section' in symbol: continue this_file = parts[1] if 'third_party/skia' not in this_file: continue this_file = this_file.replace('../../third_party/skia', 'skia') # vmsize = parts[2] Not needed filesize = int(parts[3]) print('%-10s: %-80s in %s' % (bytes_or_kb(filesize), symbol, this_file)) if __name__ == '__main__': main()