Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / tools / win / sizeviewer / sizeviewer.py
blobdefb00a4b85a5d9cdb60eb2aaf116013eba119b5
1 # Copyright 2013 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.
5 import json
6 import os
7 import string
8 import subprocess
9 import sys
12 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
15 def Run(*args):
16 with open(os.devnull, 'w') as null:
17 subprocess.check_call(args, stdout=null, stderr=null)
20 def FindNode(node, component):
21 for child in node['children']:
22 if child['name'] == component:
23 return child
24 return None
27 def InsertIntoTree(tree, source_name, size):
28 components = source_name.replace(':', '').split('\\')
29 node = tree
30 for index, component in enumerate(components):
31 data = FindNode(node, component)
32 if not data:
33 data = { 'name': component }
34 if index == len(components) - 1:
35 data['size'] = size
36 else:
37 data['children'] = []
38 node['children'].append(data)
39 node = data
42 def main():
43 out_dir = os.path.join(BASE_DIR, '..', '..', '..', 'out', 'Release')
44 jsons = []
45 for dll in ('chrome.dll', 'chrome_child.dll'):
46 dll_path = os.path.normpath(os.path.join(out_dir, dll))
47 if os.path.exists(dll_path):
48 print 'Tallying %s...' % dll_path
49 json_path = dll_path + '.json'
50 Run(os.path.join(BASE_DIR, 'code_tally.exe'),
51 '--input-image=' + dll_path,
52 '--input-pdb=' + dll_path + '.pdb',
53 '--output-file=' + json_path)
54 jsons.append(json_path)
55 if not jsons:
56 print 'Couldn\'t find binaries, looking in', out_dir
57 return 1
59 for json_name in jsons:
60 with open(json_name, 'r') as jsonf:
61 all_data = json.load(jsonf)
62 html_path = os.path.splitext(json_name)[0] + '.html'
63 print 'Generating %s...' % html_path
64 by_source = {}
65 for obj_name, obj_data in all_data['objects'].iteritems():
66 for symbol, symbol_data in obj_data.iteritems():
67 size = int(symbol_data['size'])
68 # Sometimes there's symbols with no source file, we just ignore those.
69 if 'contribs' in symbol_data:
70 # There may be more than one file in the list, we just assign to the
71 # first source file that contains the symbol, rather than try to
72 # split or duplicate info.
73 src_index = symbol_data['contribs'][0]
74 source = all_data['sources'][int(src_index)]
75 if source not in by_source:
76 by_source[source] = []
77 by_source[source].append(size)
78 binary_name = all_data['executable']['name']
79 data = {}
80 data['name'] = binary_name
81 data['children'] = []
82 for source, sizes in by_source.iteritems():
83 InsertIntoTree(data, source, sum(sizes))
84 with open(html_path, 'w') as f:
85 with open(os.path.join(BASE_DIR, 'template.html'), 'r') as templatef:
86 template = templatef.read()
87 f.write(string.Template(template).substitute(
88 {'data': json.dumps(data, indent=2),
89 'dllname': binary_name + ' ' + all_data['executable']['version']}))
91 return 0
94 if __name__ == '__main__':
95 sys.exit(main())