17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport datetime 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport json 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport logging 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport sys 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom lib.pageframe import PFNCounts 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom lib.policy import PolicySet 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfrom lib.subcommand import SubCommand 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochLOGGER = logging.getLogger('dmprof') 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass PolicyCommands(SubCommand): 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __init__(self, command): 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super(PolicyCommands, self).__init__( 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'Usage: %%prog %s [-p POLICY] <first-dump> [shared-first-dumps...]' % 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch command) 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch self._parser.add_option('-p', '--policy', type='string', dest='policy', 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='profile with POLICY', metavar='POLICY') 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch self._parser.add_option('--alternative-dirs', dest='alternative_dirs', 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch metavar='/path/on/target@/path/on/host[:...]', 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='Read files in /path/on/host/ instead of ' 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'files in /path/on/target/.') 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._parser.add_option('--timestamp', dest='timestamp', 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) action='store_true', help='Use timestamp.') 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._timestamp = False 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def _set_up(self, sys_argv): 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch options, args = self._parse_args(sys_argv, 1) 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump_path = args[1] 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shared_first_dump_paths = args[2:] 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch alternative_dirs_dict = {} 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if options.alternative_dirs: 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for alternative_dir_pair in options.alternative_dirs.split(':'): 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch target_path, host_path = alternative_dir_pair.split('@', 1) 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch alternative_dirs_dict[target_path] = host_path 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (bucket_set, dumps) = SubCommand.load_basic_files( 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump_path, True, alternative_dirs=alternative_dirs_dict) 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) self._timestamp = options.timestamp 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pfn_counts_dict = {} 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for shared_first_dump_path in shared_first_dump_paths: 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shared_dumps = SubCommand._find_all_dumps(shared_first_dump_path) 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for shared_dump in shared_dumps: 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pfn_counts = PFNCounts.load(shared_dump) 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if pfn_counts.pid not in pfn_counts_dict: 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pfn_counts_dict[pfn_counts.pid] = [] 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pfn_counts_dict[pfn_counts.pid].append(pfn_counts) 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set = PolicySet.load(SubCommand._parse_policy_list(options.policy)) 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return policy_set, dumps, pfn_counts_dict, bucket_set 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def _apply_policy(self, dump, pfn_counts_dict, policy, bucket_set, 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) first_dump_time): 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """Aggregates the total memory size of each component. 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Iterate through all stacktraces and attribute them to one of the components 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch based on the policy. It is important to apply policy in right order. 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Args: 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump: A Dump object. 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pfn_counts_dict: A dict mapping a pid to a list of PFNCounts. 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy: A Policy object. 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bucket_set: A BucketSet object. 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch first_dump_time: An integer representing time when the first dump is 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dumped. 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Returns: 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch A dict mapping components and their corresponding sizes. 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """ 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info(' %s' % dump.path) 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch all_pfn_dict = {} 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if pfn_counts_dict: 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info(' shared with...') 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for pid, pfnset_list in pfn_counts_dict.iteritems(): 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_index = None 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_difference = 1024.0 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for index, pfnset in enumerate(pfnset_list): 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch time_difference = pfnset.time - dump.time 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if time_difference >= 3.0: 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif ((time_difference < 0.0 and pfnset.reason != 'Exiting') or 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (0.0 <= time_difference and time_difference < 3.0)): 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_index = index 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_difference = time_difference 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif time_difference < 0.0 and pfnset.reason == 'Exiting': 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_index = None 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if closest_pfnset_index: 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for pfn, count in pfnset_list[closest_pfnset_index].iter_pfn: 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch all_pfn_dict[pfn] = all_pfn_dict.get(pfn, 0) + count 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info(' %s (time difference = %f)' % 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (pfnset_list[closest_pfnset_index].path, 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch closest_pfnset_difference)) 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info(' (no match with pid:%d)' % pid) 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes = dict((c, 0) for c in policy.components) 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PolicyCommands._accumulate_malloc(dump, policy, bucket_set, sizes) 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch verify_global_stats = PolicyCommands._accumulate_maps( 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump, all_pfn_dict, policy, bucket_set, sizes) 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # TODO(dmikurube): Remove the verifying code when GLOBAL_STATS is removed. 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # http://crbug.com/245603. 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for verify_key, verify_value in verify_global_stats.iteritems(): 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump_value = dump.global_stat('%s_committed' % verify_key) 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if dump_value != verify_value: 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.warn('%25s: %12d != %d (%d)' % ( 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch verify_key, dump_value, verify_value, dump_value - verify_value)) 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-no-log'] = ( 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.global_stat('profiled-mmap_committed') - 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-total-log']) 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-total-record'] = dump.global_stat('profiled-mmap_committed') 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-total-record-vm'] = dump.global_stat('profiled-mmap_virtual') 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-no-log'] = ( 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.global_stat('profiled-malloc_committed') - 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-total-log']) 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-total-record'] = dump.global_stat('profiled-malloc_committed') 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-unused'] = ( 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-tcmalloc'] - 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.global_stat('profiled-malloc_committed')) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if sizes['tc-unused'] < 0: 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.warn(' Assuming tc-unused=0 as it is negative: %d (bytes)' % 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-unused']) 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-unused'] = 0 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['tc-total'] = sizes['mmap-tcmalloc'] 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # TODO(dmikurube): global_stat will be deprecated. 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # See http://crbug.com/245603. 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for key, value in { 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'total': 'total_committed', 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'filemapped': 'file_committed', 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'absent': 'absent_committed', 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'file-exec': 'file-exec_committed', 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'file-nonexec': 'file-nonexec_committed', 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'anonymous': 'anonymous_committed', 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'stack': 'stack_committed', 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'other': 'other_committed', 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'unhooked-absent': 'nonprofiled-absent_committed', 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'total-vm': 'total_virtual', 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'filemapped-vm': 'file_virtual', 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'anonymous-vm': 'anonymous_virtual', 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'other-vm': 'other_virtual' }.iteritems(): 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if key in sizes: 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes[key] = dump.global_stat(value) 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'mustbezero' in sizes: 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch removed_list = ( 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'profiled-mmap_committed', 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-absent_committed', 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-anonymous_committed', 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-file-exec_committed', 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-file-nonexec_committed', 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-stack_committed', 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-other_committed') 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mustbezero'] = ( 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.global_stat('total_committed') - 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sum(dump.global_stat(removed) for removed in removed_list)) 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'total-exclude-profiler' in sizes: 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['total-exclude-profiler'] = ( 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.global_stat('total_committed') - 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (sizes['mmap-profiler'] + sizes['mmap-type-profiler'])) 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'hour' in sizes: 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['hour'] = (dump.time - first_dump_time) / 60.0 / 60.0 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'minute' in sizes: 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['minute'] = (dump.time - first_dump_time) / 60.0 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'second' in sizes: 1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if self._timestamp: 1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sizes['second'] = datetime.datetime.fromtimestamp(dump.time).isoformat() 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else: 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) sizes['second'] = dump.time - first_dump_time 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return sizes 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @staticmethod 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def _accumulate_malloc(dump, policy, bucket_set, sizes): 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for bucket_id, _, committed, _, _ in dump.iter_stacktrace: 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bucket = bucket_set.get(bucket_id) 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not bucket or bucket.allocator_type == 'malloc': 1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_match = policy.find_malloc(bucket) 1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif bucket.allocator_type == 'mmap': 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue 1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch assert False 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizes[component_match] += committed 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch assert not component_match.startswith('mmap-') 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if component_match.startswith('tc-'): 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizes['tc-total-log'] += committed 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sizes['other-total-log'] += committed 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @staticmethod 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def _accumulate_maps(dump, pfn_dict, policy, bucket_set, sizes): 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # TODO(dmikurube): Remove the dict when GLOBAL_STATS is removed. 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # http://crbug.com/245603. 2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch global_stats = { 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'total': 0, 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'file-exec': 0, 2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'file-nonexec': 0, 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'anonymous': 0, 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'stack': 0, 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'other': 0, 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-file-exec': 0, 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-file-nonexec': 0, 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-anonymous': 0, 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-stack': 0, 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'nonprofiled-other': 0, 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'profiled-mmap': 0, 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for key, value in dump.iter_map: 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # TODO(dmikurube): Remove the subtotal code when GLOBAL_STATS is removed. 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # It's temporary verification code for transition described in 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch # http://crbug.com/245603. 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch committed = 0 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if 'committed' in value[1]: 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch committed = value[1]['committed'] 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch global_stats['total'] += committed 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key = 'other' 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch name = value[1]['vma']['name'] 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if name.startswith('/'): 2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if value[1]['vma']['executable'] == 'x': 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key = 'file-exec' 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key = 'file-nonexec' 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif name == '[stack]': 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key = 'stack' 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif name == '': 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key = 'anonymous' 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch global_stats[key] += committed 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if value[0] == 'unhooked': 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch global_stats['nonprofiled-' + key] += committed 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if value[0] == 'hooked': 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch global_stats['profiled-mmap'] += committed 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if value[0] == 'unhooked': 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if pfn_dict and dump.pageframe_length: 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for pageframe in value[1]['pageframe']: 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_match = policy.find_unhooked(value, pageframe, pfn_dict) 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes[component_match] += pageframe.size 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_match = policy.find_unhooked(value) 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes[component_match] += int(value[1]['committed']) 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch elif value[0] == 'hooked': 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if pfn_dict and dump.pageframe_length: 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for pageframe in value[1]['pageframe']: 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_match, _ = policy.find_mmap( 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch value, bucket_set, pageframe, pfn_dict) 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes[component_match] += pageframe.size 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch assert not component_match.startswith('tc-') 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if component_match.startswith('mmap-'): 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-total-log'] += pageframe.size 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['other-total-log'] += pageframe.size 2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_match, _ = policy.find_mmap(value, bucket_set) 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes[component_match] += int(value[1]['committed']) 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if component_match.startswith('mmap-'): 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['mmap-total-log'] += int(value[1]['committed']) 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sizes['other-total-log'] += int(value[1]['committed']) 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.error('Unrecognized mapping status: %s' % value[0]) 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return global_stats 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass CSVCommand(PolicyCommands): 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __init__(self): 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super(CSVCommand, self).__init__('csv') 2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def do(self, sys_argv): 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set = self._set_up(sys_argv) 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._output( 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set, sys.stdout) 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def _output(self, policy_set, dumps, pfn_counts_dict, bucket_set, out): 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch max_components = 0 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for label in policy_set: 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch max_components = max(max_components, len(policy_set[label].components)) 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for label in sorted(policy_set): 2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch components = policy_set[label].components 2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if len(policy_set) > 1: 2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%s%s\n' % (label, ',' * (max_components - 1))) 2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%s%s\n' % ( 2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ','.join(components), ',' * (max_components - len(components)))) 2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info('Applying a policy %s to...' % label) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for index, dump in enumerate(dumps): 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if index == 0: 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_dump_time = dump.time 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) component_sizes = self._apply_policy( 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dump, pfn_counts_dict, policy_set[label], bucket_set, 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_dump_time) 3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s = [] 3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for c in components: 3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if c in ('hour', 'minute', 'second'): 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if isinstance(component_sizes[c], str): 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) s.append('%s' % component_sizes[c]) 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) else: 3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) s.append('%05.5f' % (component_sizes[c])) 3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch s.append('%05.5f' % (component_sizes[c] / 1024.0 / 1024.0)) 3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%s%s\n' % ( 3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ','.join(s), ',' * (max_components - len(components)))) 3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bucket_set.clear_component_cache() 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass JSONCommand(PolicyCommands): 3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __init__(self): 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super(JSONCommand, self).__init__('json') 3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def do(self, sys_argv): 3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set = self._set_up(sys_argv) 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._output( 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set, sys.stdout) 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def _output(self, policy_set, dumps, pfn_counts_dict, bucket_set, out): 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch json_base = { 3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'version': 'JSON_DEEP_2', 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'policies': {}, 3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for label in sorted(policy_set): 3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch json_base['policies'][label] = { 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'legends': policy_set[label].components, 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'snapshots': [], 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info('Applying a policy %s to...' % label) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for index, dump in enumerate(dumps): 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if index == 0: 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_dump_time = dump.time 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) component_sizes = self._apply_policy( 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dump, pfn_counts_dict, policy_set[label], bucket_set, 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) first_dump_time) 3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_sizes['dump_path'] = dump.path 3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch component_sizes['dump_time'] = datetime.datetime.fromtimestamp( 3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.time).strftime('%Y-%m-%d %H:%M:%S') 3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch json_base['policies'][label]['snapshots'].append(component_sizes) 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bucket_set.clear_component_cache() 3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch json.dump(json_base, out, indent=2, sort_keys=True) 3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0 3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass ListCommand(PolicyCommands): 3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __init__(self): 3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch super(ListCommand, self).__init__('list') 3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def do(self, sys_argv): 3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set = self._set_up(sys_argv) 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return self._output( 3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch policy_set, dumps, pfn_counts_dict, bucket_set, sys.stdout) 3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) def _output(self, policy_set, dumps, pfn_counts_dict, bucket_set, out): 3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for label in sorted(policy_set): 3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LOGGER.info('Applying a policy %s to...' % label) 3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for dump in dumps: 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) component_sizes = self._apply_policy( 3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump, pfn_counts_dict, policy_set[label], bucket_set, dump.time) 3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%s for %s:\n' % (label, dump.path)) 3797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for c in policy_set[label].components: 3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if c in ['hour', 'minute', 'second']: 3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%40s %12.3f\n' % (c, component_sizes[c])) 3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch out.write('%40s %12d\n' % (c, component_sizes[c])) 3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bucket_set.clear_component_cache() 3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0 388