| Index: tools/win/sizeviewer/sizeviewer.py
|
| diff --git a/tools/win/sizeviewer/sizeviewer.py b/tools/win/sizeviewer/sizeviewer.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..defb00a4b85a5d9cdb60eb2aaf116013eba119b5
|
| --- /dev/null
|
| +++ b/tools/win/sizeviewer/sizeviewer.py
|
| @@ -0,0 +1,95 @@
|
| +# 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())
|
|
|