# 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.""" 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] 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] magic_seperator = '#$%^&*' # 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 'skia_in_flutter' : { 'total_size_bytes': grand_total }, } name = 'libflutter.so' results['results'][name] = r # Make debugging easier print json.dumps(results, indent=2) with open(os.path.join(out_dir, 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()