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