OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import json | 5 import json |
6 import logging | 6 import logging |
7 import sys | 7 import sys |
8 | 8 |
9 from lib.bucket import BUCKET_ID, COMMITTED, ALLOC_COUNT, FREE_COUNT | 9 from lib.bucket import BUCKET_ID, COMMITTED, ALLOC_COUNT, FREE_COUNT |
10 from lib.ordered_dict import OrderedDict | 10 from lib.ordered_dict import OrderedDict |
(...skipping 19 matching lines...) Expand all Loading... |
30 dump_path = args[1] | 30 dump_path = args[1] |
31 # TODO(dmikurube): Support shared memory. | 31 # TODO(dmikurube): Support shared memory. |
32 alternative_dirs_dict = {} | 32 alternative_dirs_dict = {} |
33 if options.alternative_dirs: | 33 if options.alternative_dirs: |
34 for alternative_dir_pair in options.alternative_dirs.split(':'): | 34 for alternative_dir_pair in options.alternative_dirs.split(':'): |
35 target_path, host_path = alternative_dir_pair.split('@', 1) | 35 target_path, host_path = alternative_dir_pair.split('@', 1) |
36 alternative_dirs_dict[target_path] = host_path | 36 alternative_dirs_dict[target_path] = host_path |
37 (bucket_set, dumps) = SubCommand.load_basic_files( | 37 (bucket_set, dumps) = SubCommand.load_basic_files( |
38 dump_path, True, alternative_dirs=alternative_dirs_dict) | 38 dump_path, True, alternative_dirs=alternative_dirs_dict) |
39 | 39 |
| 40 # Load all sorters. |
| 41 sorters = SorterSet() |
| 42 |
40 json_root = OrderedDict() | 43 json_root = OrderedDict() |
41 json_root['version'] = 1 | 44 json_root['version'] = 1 |
42 json_root['run_id'] = None | 45 json_root['run_id'] = None |
43 for dump in dumps: | 46 for dump in dumps: |
44 if json_root['run_id'] and json_root['run_id'] != dump.run_id: | 47 if json_root['run_id'] and json_root['run_id'] != dump.run_id: |
45 LOGGER.error('Inconsistent heap profile dumps.') | 48 LOGGER.error('Inconsistent heap profile dumps.') |
46 json_root['run_id'] = '' | 49 json_root['run_id'] = '' |
47 break | 50 break |
48 json_root['run_id'] = dump.run_id | 51 json_root['run_id'] = dump.run_id |
| 52 json_root['roots'] = [] |
| 53 for sorter in sorters: |
| 54 if sorter.root: |
| 55 json_root['roots'].append([sorter.world, sorter.name]) |
| 56 json_root['default_template'] = 'l2' |
| 57 json_root['templates'] = sorters.templates.as_dict() |
| 58 |
49 json_root['snapshots'] = [] | 59 json_root['snapshots'] = [] |
50 | 60 |
51 # Load all sorters. | |
52 sorters = SorterSet() | |
53 | |
54 for dump in dumps: | 61 for dump in dumps: |
55 json_root['snapshots'].append( | 62 json_root['snapshots'].append( |
56 self._fill_snapshot(dump, bucket_set, sorters)) | 63 self._fill_snapshot(dump, bucket_set, sorters)) |
57 | 64 |
58 if options.indent: | 65 if options.indent: |
59 json.dump(json_root, sys.stdout, indent=2) | 66 json.dump(json_root, sys.stdout, indent=2) |
60 else: | 67 else: |
61 json.dump(json_root, sys.stdout) | 68 json.dump(json_root, sys.stdout) |
62 print '' | 69 print '' |
63 | 70 |
64 @staticmethod | 71 @staticmethod |
65 def _fill_snapshot(dump, bucket_set, sorters): | 72 def _fill_snapshot(dump, bucket_set, sorters): |
66 root = OrderedDict() | 73 root = OrderedDict() |
67 root['time'] = dump.time | 74 root['time'] = dump.time |
68 root['worlds'] = OrderedDict() | 75 root['worlds'] = OrderedDict() |
69 root['worlds']['vm'] = CatCommand._fill_world( | 76 root['worlds']['vm'] = CatCommand._fill_world( |
70 dump, bucket_set, sorters, 'vm') | 77 dump, bucket_set, sorters, 'vm') |
71 root['worlds']['malloc'] = CatCommand._fill_world( | 78 root['worlds']['malloc'] = CatCommand._fill_world( |
72 dump, bucket_set, sorters, 'malloc') | 79 dump, bucket_set, sorters, 'malloc') |
73 return root | 80 return root |
74 | 81 |
75 @staticmethod | 82 @staticmethod |
76 def _fill_world(dump, bucket_set, sorters, world): | 83 def _fill_world(dump, bucket_set, sorters, world): |
77 root = OrderedDict() | 84 root = OrderedDict() |
78 | 85 |
79 root['name'] = 'world' | 86 root['name'] = world |
80 if world == 'vm': | 87 if world == 'vm': |
81 root['unit_fields'] = ['committed', 'reserved'] | 88 root['unit_fields'] = ['size', 'reserved'] |
82 elif world == 'malloc': | 89 elif world == 'malloc': |
83 root['unit_fields'] = ['size', 'alloc_count', 'free_count'] | 90 root['unit_fields'] = ['size', 'alloc_count', 'free_count'] |
84 | 91 |
85 # Make { vm | malloc } units with their sizes. | 92 # Make { vm | malloc } units with their sizes. |
86 root['units'] = OrderedDict() | 93 root['units'] = OrderedDict() |
87 unit_set = UnitSet(world) | 94 unit_set = UnitSet(world) |
88 if world == 'vm': | 95 if world == 'vm': |
89 for unit in CatCommand._iterate_vm_unit(dump, None, bucket_set): | 96 for unit in CatCommand._iterate_vm_unit(dump, None, bucket_set): |
90 unit_set.append(unit) | 97 unit_set.append(unit) |
91 for unit in unit_set: | 98 for unit in unit_set: |
92 root['units'][unit.unit_id] = [unit.committed, unit.reserved] | 99 root['units'][unit.unit_id] = [unit.committed, unit.reserved] |
93 elif world == 'malloc': | 100 elif world == 'malloc': |
94 for unit in CatCommand._iterate_malloc_unit(dump, bucket_set): | 101 for unit in CatCommand._iterate_malloc_unit(dump, bucket_set): |
95 unit_set.append(unit) | 102 unit_set.append(unit) |
96 for unit in unit_set: | 103 for unit in unit_set: |
97 root['units'][unit.unit_id] = [ | 104 root['units'][unit.unit_id] = [ |
98 unit.size, unit.alloc_count, unit.free_count] | 105 unit.size, unit.alloc_count, unit.free_count] |
99 | 106 |
100 # Iterate for { vm | malloc } sorters. | 107 # Iterate for { vm | malloc } sorters. |
101 root['breakdown'] = OrderedDict() | 108 root['breakdown'] = OrderedDict() |
102 for sorter in sorters.iter_world(world): | 109 for sorter in sorters.iter_world(world): |
103 breakdown = OrderedDict() | 110 breakdown = OrderedDict() |
104 for unit in unit_set: | 111 for unit in unit_set: |
105 found = sorter.find(unit) | 112 found = sorter.find(unit) |
106 if found.name not in breakdown: | 113 if found.name not in breakdown: |
107 category = OrderedDict() | 114 category = OrderedDict() |
108 category['name'] = found.name | 115 category['name'] = found.name |
109 category['color'] = 'random' | 116 category['color'] = 'random' |
110 subworlds = {} | 117 subs = [] |
111 for subworld in found.iter_subworld(): | 118 for sub_world, sub_breakdown in found.iter_subs(): |
112 subworlds[subworld] = False | 119 subs.append([sub_world, sub_breakdown]) |
113 if subworlds: | 120 if subs: |
114 category['subworlds'] = subworlds | 121 category['subs'] = subs |
115 if found.hidden: | 122 if found.hidden: |
116 category['hidden'] = True | 123 category['hidden'] = True |
117 category['units'] = [] | 124 category['units'] = [] |
118 breakdown[found.name] = category | 125 breakdown[found.name] = category |
119 breakdown[found.name]['units'].append(unit.unit_id) | 126 breakdown[found.name]['units'].append(unit.unit_id) |
120 root['breakdown'][sorter.name] = breakdown | 127 root['breakdown'][sorter.name] = breakdown |
121 | 128 |
122 return root | 129 return root |
123 | 130 |
124 @staticmethod | 131 @staticmethod |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 int(words[ALLOC_COUNT]), | 170 int(words[ALLOC_COUNT]), |
164 int(words[FREE_COUNT]), | 171 int(words[FREE_COUNT]), |
165 bucket) | 172 bucket) |
166 elif not bucket: | 173 elif not bucket: |
167 # 'Not-found' buckets are all assumed as malloc buckets. | 174 # 'Not-found' buckets are all assumed as malloc buckets. |
168 yield MallocUnit(int(words[BUCKET_ID]), | 175 yield MallocUnit(int(words[BUCKET_ID]), |
169 int(words[COMMITTED]), | 176 int(words[COMMITTED]), |
170 int(words[ALLOC_COUNT]), | 177 int(words[ALLOC_COUNT]), |
171 int(words[FREE_COUNT]), | 178 int(words[FREE_COUNT]), |
172 None) | 179 None) |
OLD | NEW |