Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: tools/deep_memory_profiler/lib/sorter.py

Issue 22352005: Add supports for nested breakdown in 'dmprof cat'. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/deep_memory_profiler/sorter.vm-map.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 cStringIO 5 import cStringIO
6 import json 6 import json
7 import logging 7 import logging
8 import os 8 import os
9 import re 9 import re
10 10
11 11
12 LOGGER = logging.getLogger('dmprof') 12 LOGGER = logging.getLogger('dmprof')
13 13
14 BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15 15
16 DEFAULT_SORTERS = [ 16 DEFAULT_SORTERS = [
17 os.path.join(BASE_PATH, 'sorter.malloc-component.json'), 17 os.path.join(BASE_PATH, 'sorter.malloc-component.json'),
18 os.path.join(BASE_PATH, 'sorter.malloc-type.json'), 18 os.path.join(BASE_PATH, 'sorter.malloc-type.json'),
19 os.path.join(BASE_PATH, 'sorter.vm-map.json'), 19 os.path.join(BASE_PATH, 'sorter.vm-map.json'),
20 os.path.join(BASE_PATH, 'sorter.vm-sharing.json'), 20 os.path.join(BASE_PATH, 'sorter.vm-sharing.json'),
21 ] 21 ]
22 22
23 DEFAULT_TEMPLATES = os.path.join(BASE_PATH, 'templates.json')
24
23 25
24 class Unit(object): 26 class Unit(object):
25 """Represents a minimum unit of memory usage categorization. 27 """Represents a minimum unit of memory usage categorization.
26 28
27 It is supposed to be inherited for some different spaces like the entire 29 It is supposed to be inherited for some different spaces like the entire
28 virtual memory and malloc arena. Such different spaces are called "worlds" 30 virtual memory and malloc arena. Such different spaces are called "worlds"
29 in dmprof. (For example, the "vm" world and the "malloc" world.) 31 in dmprof. (For example, the "vm" world and the "malloc" world.)
30 """ 32 """
31 def __init__(self, unit_id, size): 33 def __init__(self, unit_id, size):
32 self._unit_id = unit_id 34 self._unit_id = unit_id
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 if not overwrite and unit.unit_id in self._units: 147 if not overwrite and unit.unit_id in self._units:
146 LOGGER.error('The unit id=%s already exists.' % str(unit.unit_id)) 148 LOGGER.error('The unit id=%s already exists.' % str(unit.unit_id))
147 self._units[unit.unit_id] = unit 149 self._units[unit.unit_id] = unit
148 150
149 151
150 class AbstractRule(object): 152 class AbstractRule(object):
151 """An abstract class for rules to be matched with units.""" 153 """An abstract class for rules to be matched with units."""
152 def __init__(self, dct): 154 def __init__(self, dct):
153 self._name = dct['name'] 155 self._name = dct['name']
154 self._hidden = dct.get('hidden', False) 156 self._hidden = dct.get('hidden', False)
155 self._subworlds = dct.get('subworlds', []) 157 self._subs = dct.get('subs', [])
156 158
157 def match(self, unit): 159 def match(self, unit):
158 raise NotImplementedError() 160 raise NotImplementedError()
159 161
160 @property 162 @property
161 def name(self): 163 def name(self):
162 return self._name 164 return self._name
163 165
164 @property 166 @property
165 def hidden(self): 167 def hidden(self):
166 return self._hidden 168 return self._hidden
167 169
168 def iter_subworld(self): 170 def iter_subs(self):
169 for subworld in self._subworlds: 171 for sub in self._subs:
170 yield subworld 172 yield sub
171 173
172 174
173 class VMRule(AbstractRule): 175 class VMRule(AbstractRule):
174 """Represents a Rule to match with virtual memory regions.""" 176 """Represents a Rule to match with virtual memory regions."""
175 def __init__(self, dct): 177 def __init__(self, dct):
176 super(VMRule, self).__init__(dct) 178 super(VMRule, self).__init__(dct)
177 self._backtrace_function = dct.get('backtrace_function', None) 179 self._backtrace_function = dct.get('backtrace_function', None)
178 if self._backtrace_function: 180 if self._backtrace_function:
179 self._backtrace_function = re.compile(self._backtrace_function) 181 self._backtrace_function = re.compile(self._backtrace_function)
180 self._backtrace_sourcefile = dct.get('backtrace_sourcefile', None) 182 self._backtrace_sourcefile = dct.get('backtrace_sourcefile', None)
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 return self._no_bucket 323 return self._no_bucket
322 324
323 325
324 class AbstractSorter(object): 326 class AbstractSorter(object):
325 """An abstract class for classifying Units with a set of Rules.""" 327 """An abstract class for classifying Units with a set of Rules."""
326 def __init__(self, dct): 328 def __init__(self, dct):
327 self._type = 'sorter' 329 self._type = 'sorter'
328 self._version = dct['version'] 330 self._version = dct['version']
329 self._world = dct['world'] 331 self._world = dct['world']
330 self._name = dct['name'] 332 self._name = dct['name']
333 self._root = dct.get('root', False)
331 self._order = dct['order'] 334 self._order = dct['order']
332 335
333 self._rules = [] 336 self._rules = []
334 for rule in dct['rules']: 337 for rule in dct['rules']:
335 if dct['world'] == 'vm': 338 if dct['world'] == 'vm':
336 self._rules.append(VMRule(rule)) 339 self._rules.append(VMRule(rule))
337 elif dct['world'] == 'malloc': 340 elif dct['world'] == 'malloc':
338 self._rules.append(MallocRule(rule)) 341 self._rules.append(MallocRule(rule))
339 else: 342 else:
340 LOGGER.error('Unknown sorter world type') 343 LOGGER.error('Unknown sorter world type')
(...skipping 20 matching lines...) Expand all
361 return None 364 return None
362 365
363 @property 366 @property
364 def world(self): 367 def world(self):
365 return self._world 368 return self._world
366 369
367 @property 370 @property
368 def name(self): 371 def name(self):
369 return self._name 372 return self._name
370 373
374 @property
375 def root(self):
376 return self._root
377
371 def find(self, unit): 378 def find(self, unit):
372 raise NotImplementedError() 379 raise NotImplementedError()
373 380
374 def find_rule(self, name): 381 def find_rule(self, name):
375 """Finds a rule whose name is |name|. """ 382 """Finds a rule whose name is |name|. """
376 for rule in self._rules: 383 for rule in self._rules:
377 if rule.name == name: 384 if rule.name == name:
378 return rule 385 return rule
379 return None 386 return None
380 387
(...skipping 26 matching lines...) Expand all
407 if unit.bucket.component_cache: 414 if unit.bucket.component_cache:
408 return unit.bucket.component_cache 415 return unit.bucket.component_cache
409 416
410 for rule in self._rules: 417 for rule in self._rules:
411 if rule.match(unit): 418 if rule.match(unit):
412 unit.bucket.component_cache = rule 419 unit.bucket.component_cache = rule
413 return rule 420 return rule
414 assert False 421 assert False
415 422
416 423
424 class SorterTemplates(object):
425 """Represents a template for sorters."""
426 def __init__(self, dct):
427 self._dict = dct
428
429 def as_dict(self):
430 return self._dict
431
432 @staticmethod
433 def load(filename):
434 with open(filename) as templates_f:
435 templates_dict = json.load(templates_f)
436 return SorterTemplates(templates_dict)
437
438
417 class SorterSet(object): 439 class SorterSet(object):
418 """Represents an iterable set of Sorters.""" 440 """Represents an iterable set of Sorters."""
419 def __init__(self, additional=None, default=None): 441 def __init__(self, additional=None, default=None):
420 if not additional: 442 if not additional:
421 additional = [] 443 additional = []
422 if not default: 444 if not default:
423 default = DEFAULT_SORTERS 445 default = DEFAULT_SORTERS
424 self._sorters = {} 446 self._sorters = {}
425 for filename in default + additional: 447 for filename in default + additional:
426 sorter = AbstractSorter.load(filename) 448 sorter = AbstractSorter.load(filename)
427 if sorter.world not in self._sorters: 449 if sorter.world not in self._sorters:
428 self._sorters[sorter.world] = [] 450 self._sorters[sorter.world] = []
429 self._sorters[sorter.world].append(sorter) 451 self._sorters[sorter.world].append(sorter)
452 self._templates = SorterTemplates.load(DEFAULT_TEMPLATES)
430 453
431 def __repr__(self): 454 def __repr__(self):
432 result = cStringIO.StringIO() 455 result = cStringIO.StringIO()
433 result.write(self._sorters) 456 result.write(self._sorters)
434 return result.getvalue() 457 return result.getvalue()
435 458
436 def __iter__(self): 459 def __iter__(self):
437 for sorters in self._sorters.itervalues(): 460 for sorters in self._sorters.itervalues():
438 for sorter in sorters: 461 for sorter in sorters:
439 yield sorter 462 yield sorter
440 463
441 def iter_world(self, world): 464 def iter_world(self, world):
442 for sorter in self._sorters.get(world, []): 465 for sorter in self._sorters.get(world, []):
443 yield sorter 466 yield sorter
467
468 @property
469 def templates(self):
470 return self._templates
OLDNEW
« no previous file with comments | « no previous file | tools/deep_memory_profiler/sorter.vm-map.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698