1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch# found in the LICENSE file. 4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochimport json 6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochimport os 7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochimport string 8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochimport subprocess 9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochimport sys 10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 12558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochBASE_DIR = os.path.dirname(os.path.abspath(__file__)) 13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochdef Run(*args): 16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch with open(os.devnull, 'w') as null: 17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch subprocess.check_call(args, stdout=null, stderr=null) 18558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochdef FindNode(node, component): 21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for child in node['children']: 22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if child['name'] == component: 23558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return child 24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return None 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochdef InsertIntoTree(tree, source_name, size): 28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch components = source_name.replace(':', '').split('\\') 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch node = tree 30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for index, component in enumerate(components): 31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = FindNode(node, component) 32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if not data: 33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = { 'name': component } 34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if index == len(components) - 1: 35558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data['size'] = size 36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch else: 37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data['children'] = [] 38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch node['children'].append(data) 39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch node = data 40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochdef main(): 43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch out_dir = os.path.join(BASE_DIR, '..', '..', '..', 'out', 'Release') 44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch jsons = [] 45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for dll in ('chrome.dll', 'chrome_child.dll'): 46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch dll_path = os.path.normpath(os.path.join(out_dir, dll)) 47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if os.path.exists(dll_path): 48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch print 'Tallying %s...' % dll_path 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch json_path = dll_path + '.json' 50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Run(os.path.join(BASE_DIR, 'code_tally.exe'), 51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch '--input-image=' + dll_path, 52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch '--input-pdb=' + dll_path + '.pdb', 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch '--output-file=' + json_path) 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch jsons.append(json_path) 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if not jsons: 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch print 'Couldn\'t find binaries, looking in', out_dir 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return 1 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for json_name in jsons: 60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch with open(json_name, 'r') as jsonf: 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch all_data = json.load(jsonf) 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch html_path = os.path.splitext(json_name)[0] + '.html' 63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch print 'Generating %s...' % html_path 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch by_source = {} 65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for obj_name, obj_data in all_data['objects'].iteritems(): 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for symbol, symbol_data in obj_data.iteritems(): 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch size = int(symbol_data['size']) 68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch # Sometimes there's symbols with no source file, we just ignore those. 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if 'contribs' in symbol_data: 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch # There may be more than one file in the list, we just assign to the 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch # first source file that contains the symbol, rather than try to 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch # split or duplicate info. 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch src_index = symbol_data['contribs'][0] 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch source = all_data['sources'][int(src_index)] 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if source not in by_source: 76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch by_source[source] = [] 77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch by_source[source].append(size) 78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch binary_name = all_data['executable']['name'] 79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = {} 80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data['name'] = binary_name 81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data['children'] = [] 82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for source, sizes in by_source.iteritems(): 83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch InsertIntoTree(data, source, sum(sizes)) 84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch with open(html_path, 'w') as f: 85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch with open(os.path.join(BASE_DIR, 'template.html'), 'r') as templatef: 86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch template = templatef.read() 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch f.write(string.Template(template).substitute( 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch {'data': json.dumps(data, indent=2), 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 'dllname': binary_name + ' ' + all_data['executable']['version']})) 90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return 0 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochif __name__ == '__main__': 95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch sys.exit(main()) 96