| Index: tools/memory_inspector/memory_inspector/classification/native_heap_classifier.py
|
| diff --git a/tools/memory_inspector/memory_inspector/classification/native_heap_classifier.py b/tools/memory_inspector/memory_inspector/classification/native_heap_classifier.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4cdc3b0d3ba1c41522e6c193c920eb75d97fc47e
|
| --- /dev/null
|
| +++ b/tools/memory_inspector/memory_inspector/classification/native_heap_classifier.py
|
| @@ -0,0 +1,89 @@
|
| +# Copyright 2014 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.
|
| +
|
| +"""This module classifies NativeHeap objects filtering their allocations.
|
| +
|
| +The only filter currently available is 'stacktrace', which works as follows:
|
| +
|
| +{'name': 'rule-1', 'stacktrace': 'foo' }
|
| +{'name': 'rule-2', 'stacktrace': ['foo', r'bar\s+baz']}
|
| +
|
| +rule-1 will match any allocation that has 'foo' in one of its stack frames.
|
| +rule-2 will match any allocation that has a stack frame matching 'foo' AND a
|
| +followed by a stack frame matching 'bar baz'. Note that order matters, so rule-2
|
| +will not match a stacktrace like ['bar baz', 'foo'].
|
| +
|
| +TODO(primiano): introduce more filters after the first prototype with UI, for
|
| +instance, filter by source file path, library file name or by allocation size.
|
| +"""
|
| +
|
| +import re
|
| +
|
| +from memory_inspector.classification import results
|
| +from memory_inspector.classification import rules
|
| +from memory_inspector.core import exceptions
|
| +from memory_inspector.core import native_heap
|
| +
|
| +
|
| +_RESULT_KEYS = ['bytes_allocated']
|
| +
|
| +
|
| +def LoadRules(content):
|
| + """Loads and parses a native-heap rule tree from a content (string).
|
| +
|
| + Returns:
|
| + An instance of |rules.Rule|, which nodes are |_NHeapRule| instances.
|
| + """
|
| + return rules.Load(content, _NHeapRule)
|
| +
|
| +
|
| +def Classify(nativeheap, rule_tree):
|
| + """Create aggregated results of native heaps using the provided rules.
|
| +
|
| + Args:
|
| + nativeheap: the heap dump being processed (a |NativeHeap| instance).
|
| + rule_tree: the user-defined rules that define the filtering categories.
|
| +
|
| + Returns:
|
| + An instance of |AggreatedResults|.
|
| + """
|
| + assert(isinstance(nativeheap, native_heap.NativeHeap))
|
| + assert(isinstance(rule_tree, rules.Rule))
|
| +
|
| + res = results.AggreatedResults(rule_tree, _RESULT_KEYS)
|
| + for allocation in nativeheap.allocations:
|
| + res.AddToMatchingNodes(allocation, [allocation.total_size])
|
| + return res
|
| +
|
| +
|
| +class _NHeapRule(rules.Rule):
|
| + def __init__(self, name, filters):
|
| + super(_NHeapRule, self).__init__(name)
|
| + stacktrace_regexs = filters.get('stacktrace', [])
|
| + # The 'stacktrace' filter can be either a string (simple case, one regex) or
|
| + # a list of strings (complex case, see doc in the header of this file).
|
| + if isinstance(stacktrace_regexs, basestring):
|
| + stacktrace_regexs = [stacktrace_regexs]
|
| + self._stacktrace_regexs = []
|
| + for regex in stacktrace_regexs:
|
| + try:
|
| + self._stacktrace_regexs.append(re.compile(regex))
|
| + except re.error, descr:
|
| + raise exceptions.MemoryInspectorException(
|
| + 'Regex parse error "%s" : %s' % (regex, descr))
|
| +
|
| + def Match(self, allocation):
|
| + if not self._stacktrace_regexs:
|
| + return True
|
| + cur_regex_idx = 0
|
| + cur_regex = self._stacktrace_regexs[0]
|
| + for frame in allocation.stack_trace.frames:
|
| + if frame.symbol and cur_regex.search(frame.symbol.name):
|
| + # The current regex has been matched.
|
| + if cur_regex_idx == len(self._stacktrace_regexs) - 1:
|
| + return True # All the provided regexs have been matched, we're happy.
|
| + cur_regex_idx += 1
|
| + cur_regex = self._stacktrace_regexs[cur_regex_idx]
|
| +
|
| + return False # Not all the provided regexs have been matched.
|
|
|