| # Copyright 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import json |
| import os |
| import string |
| import subprocess |
| import sys |
| |
| |
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
| |
| |
| def Run(*args): |
| with open(os.devnull, 'w') as null: |
| subprocess.check_call(args, stdout=null, stderr=null) |
| |
| |
| def FindNode(node, component): |
| for child in node['children']: |
| if child['name'] == component: |
| return child |
| return None |
| |
| |
| def InsertIntoTree(tree, source_name, size): |
| components = source_name.replace(':', '').split('\\') |
| node = tree |
| for index, component in enumerate(components): |
| data = FindNode(node, component) |
| if not data: |
| data = { 'name': component } |
| if index == len(components) - 1: |
| data['size'] = size |
| else: |
| data['children'] = [] |
| node['children'].append(data) |
| node = data |
| |
| |
| def main(): |
| out_dir = os.path.join(BASE_DIR, '..', '..', '..', 'out', 'Release') |
| jsons = [] |
| for dll in ('chrome.dll', 'chrome_child.dll'): |
| dll_path = os.path.normpath(os.path.join(out_dir, dll)) |
| if os.path.exists(dll_path): |
| print 'Tallying %s...' % dll_path |
| json_path = dll_path + '.json' |
| Run(os.path.join(BASE_DIR, 'code_tally.exe'), |
| '--input-image=' + dll_path, |
| '--input-pdb=' + dll_path + '.pdb', |
| '--output-file=' + json_path) |
| jsons.append(json_path) |
| if not jsons: |
| print 'Couldn\'t find binaries, looking in', out_dir |
| return 1 |
| |
| for json_name in jsons: |
| with open(json_name, 'r') as jsonf: |
| all_data = json.load(jsonf) |
| html_path = os.path.splitext(json_name)[0] + '.html' |
| print 'Generating %s...' % html_path |
| by_source = {} |
| for obj_name, obj_data in all_data['objects'].iteritems(): |
| for symbol, symbol_data in obj_data.iteritems(): |
| size = int(symbol_data['size']) |
| # Sometimes there's symbols with no source file, we just ignore those. |
| if 'contribs' in symbol_data: |
| # There may be more than one file in the list, we just assign to the |
| # first source file that contains the symbol, rather than try to |
| # split or duplicate info. |
| src_index = symbol_data['contribs'][0] |
| source = all_data['sources'][int(src_index)] |
| if source not in by_source: |
| by_source[source] = [] |
| by_source[source].append(size) |
| binary_name = all_data['executable']['name'] |
| data = {} |
| data['name'] = binary_name |
| data['children'] = [] |
| for source, sizes in by_source.iteritems(): |
| InsertIntoTree(data, source, sum(sizes)) |
| with open(html_path, 'w') as f: |
| with open(os.path.join(BASE_DIR, 'template.html'), 'r') as templatef: |
| template = templatef.read() |
| f.write(string.Template(template).substitute( |
| {'data': json.dumps(data, indent=2), |
| 'dllname': binary_name + ' ' + all_data['executable']['version']})) |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |