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

Unified Diff: tools/deep_memory_profiler/lib/bucket.py

Issue 19346002: Refactor dmprof: Split dmprof.py into modules. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/deep_memory_profiler/lib/__init__.py ('k') | tools/deep_memory_profiler/lib/dump.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/deep_memory_profiler/lib/bucket.py
diff --git a/tools/deep_memory_profiler/lib/bucket.py b/tools/deep_memory_profiler/lib/bucket.py
new file mode 100644
index 0000000000000000000000000000000000000000..51af5b2ddd82bc18f1420c4202fa80f5f039f754
--- /dev/null
+++ b/tools/deep_memory_profiler/lib/bucket.py
@@ -0,0 +1,191 @@
+# Copyright 2013 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.
+
+import logging
+import os
+
+from lib.symbol import FUNCTION_SYMBOLS, SOURCEFILE_SYMBOLS, TYPEINFO_SYMBOLS
+
+
+LOGGER = logging.getLogger('dmprof')
+
+# Indexes in dumped heap profile dumps.
+VIRTUAL, COMMITTED, ALLOC_COUNT, FREE_COUNT, _, BUCKET_ID = range(6)
+
+
+class Bucket(object):
+ """Represents a bucket, which is a unit of memory block classification."""
+
+ def __init__(self, stacktrace, allocator_type, typeinfo, typeinfo_name):
+ self._stacktrace = stacktrace
+ self._allocator_type = allocator_type
+ self._typeinfo = typeinfo
+ self._typeinfo_name = typeinfo_name
+
+ self._symbolized_stackfunction = stacktrace
+ self._symbolized_joined_stackfunction = ''
+ self._symbolized_stacksourcefile = stacktrace
+ self._symbolized_joined_stacksourcefile = ''
+ self._symbolized_typeinfo = typeinfo_name
+
+ self.component_cache = ''
+
+ def __str__(self):
+ result = []
+ result.append(self._allocator_type)
+ if self._symbolized_typeinfo == 'no typeinfo':
+ result.append('tno_typeinfo')
+ else:
+ result.append('t' + self._symbolized_typeinfo)
+ result.append('n' + self._typeinfo_name)
+ result.extend(['%s(@%s)' % (function, sourcefile)
+ for function, sourcefile
+ in zip(self._symbolized_stackfunction,
+ self._symbolized_stacksourcefile)])
+ return ' '.join(result)
+
+ def symbolize(self, symbol_mapping_cache):
+ """Makes a symbolized stacktrace and typeinfo with |symbol_mapping_cache|.
+
+ Args:
+ symbol_mapping_cache: A SymbolMappingCache object.
+ """
+ # TODO(dmikurube): Fill explicitly with numbers if symbol not found.
+ self._symbolized_stackfunction = [
+ symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address)
+ for address in self._stacktrace]
+ self._symbolized_joined_stackfunction = ' '.join(
+ self._symbolized_stackfunction)
+ self._symbolized_stacksourcefile = [
+ symbol_mapping_cache.lookup(SOURCEFILE_SYMBOLS, address)
+ for address in self._stacktrace]
+ self._symbolized_joined_stacksourcefile = ' '.join(
+ self._symbolized_stacksourcefile)
+ if not self._typeinfo:
+ self._symbolized_typeinfo = 'no typeinfo'
+ else:
+ self._symbolized_typeinfo = symbol_mapping_cache.lookup(
+ TYPEINFO_SYMBOLS, self._typeinfo)
+ if not self._symbolized_typeinfo:
+ self._symbolized_typeinfo = 'no typeinfo'
+
+ def clear_component_cache(self):
+ self.component_cache = ''
+
+ @property
+ def stacktrace(self):
+ return self._stacktrace
+
+ @property
+ def allocator_type(self):
+ return self._allocator_type
+
+ @property
+ def typeinfo(self):
+ return self._typeinfo
+
+ @property
+ def typeinfo_name(self):
+ return self._typeinfo_name
+
+ @property
+ def symbolized_stackfunction(self):
+ return self._symbolized_stackfunction
+
+ @property
+ def symbolized_joined_stackfunction(self):
+ return self._symbolized_joined_stackfunction
+
+ @property
+ def symbolized_stacksourcefile(self):
+ return self._symbolized_stacksourcefile
+
+ @property
+ def symbolized_joined_stacksourcefile(self):
+ return self._symbolized_joined_stacksourcefile
+
+ @property
+ def symbolized_typeinfo(self):
+ return self._symbolized_typeinfo
+
+
+class BucketSet(object):
+ """Represents a set of bucket."""
+ def __init__(self):
+ self._buckets = {}
+ self._code_addresses = set()
+ self._typeinfo_addresses = set()
+
+ def load(self, prefix):
+ """Loads all related bucket files.
+
+ Args:
+ prefix: A prefix string for bucket file names.
+ """
+ LOGGER.info('Loading bucket files.')
+
+ n = 0
+ skipped = 0
+ while True:
+ path = '%s.%04d.buckets' % (prefix, n)
+ if not os.path.exists(path) or not os.stat(path).st_size:
+ if skipped > 10:
+ break
+ n += 1
+ skipped += 1
+ continue
+ LOGGER.info(' %s' % path)
+ with open(path, 'r') as f:
+ self._load_file(f)
+ n += 1
+ skipped = 0
+
+ def _load_file(self, bucket_f):
+ for line in bucket_f:
+ words = line.split()
+ typeinfo = None
+ typeinfo_name = ''
+ stacktrace_begin = 2
+ for index, word in enumerate(words):
+ if index < 2:
+ continue
+ if word[0] == 't':
+ typeinfo = int(word[1:], 16)
+ self._typeinfo_addresses.add(typeinfo)
+ elif word[0] == 'n':
+ typeinfo_name = word[1:]
+ else:
+ stacktrace_begin = index
+ break
+ stacktrace = [int(address, 16) for address in words[stacktrace_begin:]]
+ for frame in stacktrace:
+ self._code_addresses.add(frame)
+ self._buckets[int(words[0])] = Bucket(
+ stacktrace, words[1], typeinfo, typeinfo_name)
+
+ def __iter__(self):
+ for bucket_id, bucket_content in self._buckets.iteritems():
+ yield bucket_id, bucket_content
+
+ def __getitem__(self, bucket_id):
+ return self._buckets[bucket_id]
+
+ def get(self, bucket_id):
+ return self._buckets.get(bucket_id)
+
+ def symbolize(self, symbol_mapping_cache):
+ for bucket_content in self._buckets.itervalues():
+ bucket_content.symbolize(symbol_mapping_cache)
+
+ def clear_component_cache(self):
+ for bucket_content in self._buckets.itervalues():
+ bucket_content.clear_component_cache()
+
+ def iter_addresses(self, symbol_type):
+ if symbol_type in [FUNCTION_SYMBOLS, SOURCEFILE_SYMBOLS]:
+ for function in self._code_addresses:
+ yield function
+ else:
+ for function in self._typeinfo_addresses:
+ yield function
« no previous file with comments | « tools/deep_memory_profiler/lib/__init__.py ('k') | tools/deep_memory_profiler/lib/dump.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698