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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import logging
6 import os
7
8 from lib.symbol import FUNCTION_SYMBOLS, SOURCEFILE_SYMBOLS, TYPEINFO_SYMBOLS
9
10
11 LOGGER = logging.getLogger('dmprof')
12
13 # Indexes in dumped heap profile dumps.
14 BUCKET_ID = 5
peria 2013/07/16 11:50:32 If all constant numbers are indexes, they should b
M-A Ruel 2013/07/16 13:31:32 In general, I use the following idiom: VIRTUAL, C
Dai Mikurube (NOT FULLTIME) 2013/07/17 05:55:06 Good catch. Thanks. The index is applied for resu
15 VIRTUAL = 0
16 COMMITTED = 1
17 ALLOC_COUNT = 2
18 FREE_COUNT = 3
19
20
21 class Bucket(object):
22 """Represents a bucket, which is a unit of memory block classification."""
23
24 def __init__(self, stacktrace, allocator_type, typeinfo, typeinfo_name):
25 self._stacktrace = stacktrace
26 self._allocator_type = allocator_type
27 self._typeinfo = typeinfo
28 self._typeinfo_name = typeinfo_name
29
30 self._symbolized_stackfunction = stacktrace
31 self._symbolized_joined_stackfunction = ''
32 self._symbolized_stacksourcefile = stacktrace
33 self._symbolized_joined_stacksourcefile = ''
34 self._symbolized_typeinfo = typeinfo_name
35
36 self.component_cache = ''
37
38 def __str__(self):
39 result = []
40 result.append(self._allocator_type)
41 if self._symbolized_typeinfo == 'no typeinfo':
42 result.append('tno_typeinfo')
43 else:
44 result.append('t' + self._symbolized_typeinfo)
45 result.append('n' + self._typeinfo_name)
46 result.extend(['%s(@%s)' % (function, sourcefile)
47 for function, sourcefile
48 in zip(self._symbolized_stackfunction,
49 self._symbolized_stacksourcefile)])
50 return ' '.join(result)
51
52 def symbolize(self, symbol_mapping_cache):
53 """Makes a symbolized stacktrace and typeinfo with |symbol_mapping_cache|.
54
55 Args:
56 symbol_mapping_cache: A SymbolMappingCache object.
57 """
58 # TODO(dmikurube): Fill explicitly with numbers if symbol not found.
59 self._symbolized_stackfunction = [
60 symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address)
61 for address in self._stacktrace]
62 self._symbolized_joined_stackfunction = ' '.join(
63 self._symbolized_stackfunction)
64 self._symbolized_stacksourcefile = [
65 symbol_mapping_cache.lookup(SOURCEFILE_SYMBOLS, address)
66 for address in self._stacktrace]
67 self._symbolized_joined_stacksourcefile = ' '.join(
68 self._symbolized_stacksourcefile)
69 if not self._typeinfo:
70 self._symbolized_typeinfo = 'no typeinfo'
71 else:
72 self._symbolized_typeinfo = symbol_mapping_cache.lookup(
73 TYPEINFO_SYMBOLS, self._typeinfo)
74 if not self._symbolized_typeinfo:
75 self._symbolized_typeinfo = 'no typeinfo'
76
77 def clear_component_cache(self):
78 self.component_cache = ''
79
80 @property
81 def stacktrace(self):
82 return self._stacktrace
83
84 @property
85 def allocator_type(self):
86 return self._allocator_type
87
88 @property
89 def typeinfo(self):
90 return self._typeinfo
91
92 @property
93 def typeinfo_name(self):
94 return self._typeinfo_name
95
96 @property
97 def symbolized_stackfunction(self):
98 return self._symbolized_stackfunction
99
100 @property
101 def symbolized_joined_stackfunction(self):
102 return self._symbolized_joined_stackfunction
103
104 @property
105 def symbolized_stacksourcefile(self):
106 return self._symbolized_stacksourcefile
107
108 @property
109 def symbolized_joined_stacksourcefile(self):
110 return self._symbolized_joined_stacksourcefile
111
112 @property
113 def symbolized_typeinfo(self):
114 return self._symbolized_typeinfo
115
116
117 class BucketSet(object):
118 """Represents a set of bucket."""
119 def __init__(self):
120 self._buckets = {}
121 self._code_addresses = set()
122 self._typeinfo_addresses = set()
123
124 def load(self, prefix):
125 """Loads all related bucket files.
126
127 Args:
128 prefix: A prefix string for bucket file names.
129 """
130 LOGGER.info('Loading bucket files.')
131
132 n = 0
133 skipped = 0
134 while True:
135 path = '%s.%04d.buckets' % (prefix, n)
136 if not os.path.exists(path) or not os.stat(path).st_size:
137 if skipped > 10:
138 break
139 n += 1
140 skipped += 1
141 continue
142 LOGGER.info(' %s' % path)
143 with open(path, 'r') as f:
144 self._load_file(f)
145 n += 1
146 skipped = 0
147
148 def _load_file(self, bucket_f):
149 for line in bucket_f:
150 words = line.split()
151 typeinfo = None
152 typeinfo_name = ''
153 stacktrace_begin = 2
154 for index, word in enumerate(words):
155 if index < 2:
156 continue
157 if word[0] == 't':
158 typeinfo = int(word[1:], 16)
159 self._typeinfo_addresses.add(typeinfo)
160 elif word[0] == 'n':
161 typeinfo_name = word[1:]
162 else:
163 stacktrace_begin = index
164 break
165 stacktrace = [int(address, 16) for address in words[stacktrace_begin:]]
166 for frame in stacktrace:
167 self._code_addresses.add(frame)
168 self._buckets[int(words[0])] = Bucket(
169 stacktrace, words[1], typeinfo, typeinfo_name)
170
171 def __iter__(self):
172 for bucket_id, bucket_content in self._buckets.iteritems():
173 yield bucket_id, bucket_content
174
175 def __getitem__(self, bucket_id):
176 return self._buckets[bucket_id]
177
178 def get(self, bucket_id):
179 return self._buckets.get(bucket_id)
180
181 def symbolize(self, symbol_mapping_cache):
182 for bucket_content in self._buckets.itervalues():
183 bucket_content.symbolize(symbol_mapping_cache)
184
185 def clear_component_cache(self):
186 for bucket_content in self._buckets.itervalues():
187 bucket_content.clear_component_cache()
188
189 def iter_addresses(self, symbol_type):
190 if symbol_type in [FUNCTION_SYMBOLS, SOURCEFILE_SYMBOLS]:
191 for function in self._code_addresses:
192 yield function
193 else:
194 for function in self._typeinfo_addresses:
195 yield function
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698