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