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 the given cpp file.""" 7 8 9from __future__ import print_function 10import csv 11import json 12import os 13import re 14import subprocess 15import sys 16 17 18def main(): 19 input_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 total_size_bytes_key = sys.argv[6] 25 magic_seperator = sys.argv[7] 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 # Human "readable" overview as an FYI. 41 print(magic_seperator) 42 print('Note that template instantiations are grouped together, ' 43 'thus the elided types.') 44 print(subprocess.check_output([bloaty_path, input_file, 45 '-d', 'sections,shortsymbols', '-n', '200'])) 46 print(' ') 47 48 sections = subprocess.check_output([bloaty_path, input_file, '-d', 49 'sections', '-n', '0', '--csv']) 50 51 name = os.path.basename(input_file) 52 53 r = { 54 # Use the default config as stats about the whole binary 55 'default' : { 56 total_size_bytes_key: os.path.getsize(input_file) 57 }, 58 } 59 60 # report section by section data. Sections are like .text, .data, etc. 61 for section_row in sections.strip().split('\n'): 62 # Follows schema sections,vmsize,filesize 63 parts = section_row.split(',') 64 if len(parts) < 3 or parts[0] == 'sections': 65 # If we see section, that's the table header 66 continue 67 section = parts[0] 68 # part[1] is "VM Size", part[2] is "File Size". From the bloaty docs: 69 # The "VM SIZE" column tells you how much space the binary will take 70 # when it is loaded into memory. The "FILE SIZE" column tells you about 71 # how much space the binary is taking on disk. 72 vmsize = parts[1] # In bytes 73 filesize = parts[2] # In bytes 74 section = re.sub('[^0-9a-zA-Z_]', '_', section) 75 r['section'+section] = { 76 'in_file_size_bytes': int(filesize), 77 'vm_size_bytes': int(vmsize), 78 } 79 80 print(magic_seperator) 81 results['results'][name] = r 82 83 # Make debugging easier 84 print(json.dumps(results, indent=2)) 85 86 with open(os.path.join(out_dir, name+'.json'), 'w') as output: 87 output.write(json.dumps(results, indent=2)) 88 89 90if __name__ == '__main__': 91 main() 92