• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5
6"""Writes a Perf-formated json file with stats about Skia's size in flutter."""
7
8
9from __future__ import print_function
10import json
11import os
12import subprocess
13import sys
14
15
16def main():
17  # This should be the stripped file from
18  # out/android_release/lib.stripped/libflutter.so
19  stripped_file = sys.argv[1]
20  out_dir = sys.argv[2]
21  keystr = sys.argv[3]
22  propstr = sys.argv[4]
23  bloaty_path = sys.argv[5]
24  # This is the unstripped out/android_release/libflutter.so
25  # The symbols in it are needed to get the compileunits data.
26  symbols_file = sys.argv[6]
27  config = sys.argv[7]
28  total_size_bytes_key = sys.argv[8]
29  lib_name = sys.argv[9]
30  magic_seperator = sys.argv[10]
31
32  results = {
33    'key': { },
34    'results': { }
35  }
36
37  props = propstr.split(' ')
38  for i in range(0, len(props), 2):
39    results[props[i]] = props[i+1]
40
41  keys = keystr.split(' ')
42  for i in range(0, len(keys), 2):
43    results['key'][keys[i]] = keys[i+1]
44
45  # Human "readable" reports as an FYI.
46  print(magic_seperator)
47  print('Report by file, then by symbol with ellided/combined templates')
48  lines = subprocess.check_output([bloaty_path, stripped_file,
49                                 '-d', 'compileunits,symbols', '-s', 'file',
50                                 '-n', '0', '--tsv', '--demangle=short',
51                                 '--debug-file=%s' % symbols_file])
52  grand_total = print_skia_lines_file_symbol(lines)
53  print(magic_seperator)
54  print('Report by file, then by symbol with full templates')
55  lines = subprocess.check_output([bloaty_path, stripped_file,
56                                 '-d', 'compileunits,symbols', '-s', 'file',
57                                 '-n', '0', '--tsv', '--demangle=full',
58                                 '--debug-file=%s' % symbols_file])
59  print_skia_lines_file_symbol(lines)
60  print(magic_seperator)
61
62  print('Report by symbol, then by file with ellided/combined templates')
63  lines = subprocess.check_output([bloaty_path, stripped_file,
64                                 '-d', 'symbols,compileunits', '-s', 'file',
65                                 '-n', '0', '--tsv', '--demangle=short',
66                                 '--debug-file=%s' % symbols_file])
67  print_skia_lines_symbol_file(lines)
68  print(magic_seperator)
69
70  print('Report by symbol, then by file with full templates')
71  lines = subprocess.check_output([bloaty_path, stripped_file,
72                                 '-d', 'symbols,compileunits', '-s', 'file',
73                                 '-n', '0', '--tsv', '--demangle=full',
74                                 '--debug-file=%s' % symbols_file])
75  print_skia_lines_symbol_file(lines)
76  print(magic_seperator)
77
78  r = {
79    # Use the default config as stats about the whole binary
80    config : {
81      total_size_bytes_key: grand_total
82    },
83  }
84
85  results['results'][lib_name] = r
86
87  # Make debugging easier
88  print(json.dumps(results, indent=2))
89
90  with open(os.path.join(out_dir, lib_name+'.json'), 'w') as output:
91    output.write(json.dumps(results, indent=2))
92
93
94def bytes_or_kb(num):
95  if num < 1024:
96    return '%d bytes' % num
97  else:
98    return '%1.1f KiB' % (num / 1024.0)
99
100
101def print_skia_lines_file_symbol(lines):
102  lines = lines.split('\n')
103  grand_total = 0
104  sub_total = 0
105  cur_file = ''
106
107  for line in lines:
108    # Line looks like:
109    # ../../third_party/skia/src/file.cpp\tSkTSect<>::intersects()\t1224\t1348
110    parts = line.split('\t')
111    if len(parts) != 4:
112      continue
113    this_file = parts[0]
114    if 'third_party/skia' not in this_file:
115      continue
116    symbol    = parts[1]
117    if '.debug' in symbol:
118      continue
119    # vmsize    = parts[2] Not needed
120    filesize  = int(parts[3])
121
122    if this_file != cur_file:
123      if cur_file != '':
124        print('\t%-100s: %s' % ('Total File Size', bytes_or_kb(sub_total)))
125      sub_total = 0
126      cur_file = this_file
127      print(this_file.replace('../../third_party/skia', 'skia'))
128
129    print('\t%-100s: %s' % (symbol, bytes_or_kb(filesize)))
130    sub_total += filesize
131    grand_total += filesize
132
133  print('\t%-100s: %s' % ('Total File Size', bytes_or_kb(sub_total)))
134  print('=======================================')
135  print('Grand Total File Size: %s' % bytes_or_kb(grand_total))
136  return grand_total
137
138
139def print_skia_lines_symbol_file(lines):
140  lines = lines.split('\n')
141
142  for line in lines:
143    # Line looks like:
144    # SkTSect<>::intersects()\t../../third_party/skia/src/file.cpp\t1224\t1348
145    parts = line.split('\t')
146    if len(parts) != 4:
147      continue
148    symbol    = parts[0]
149    if 'section' in symbol:
150      continue
151    this_file = parts[1]
152    if 'third_party/skia' not in this_file:
153      continue
154    this_file = this_file.replace('../../third_party/skia', 'skia')
155    # vmsize    = parts[2] Not needed
156    filesize  = int(parts[3])
157
158    print('%-10s: %-80s in %s' % (bytes_or_kb(filesize), symbol, this_file))
159
160
161if __name__ == '__main__':
162  main()
163