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