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.
8 from lib
.symbol
import FUNCTION_SYMBOLS
, SOURCEFILE_SYMBOLS
, TYPEINFO_SYMBOLS
11 LOGGER
= logging
.getLogger('dmprof')
15 """Represents a bucket, which is a unit of memory block classification."""
17 def __init__(self
, stacktrace
, allocator_type
, typeinfo
, typeinfo_name
):
18 self
._stacktrace
= stacktrace
19 self
._allocator
_type
= allocator_type
20 self
._typeinfo
= typeinfo
21 self
._typeinfo
_name
= typeinfo_name
23 self
._symbolized
_stackfunction
= stacktrace
24 self
._symbolized
_joined
_stackfunction
= ''
25 self
._symbolized
_stacksourcefile
= stacktrace
26 self
._symbolized
_joined
_stacksourcefile
= ''
27 self
._symbolized
_typeinfo
= typeinfo_name
29 self
.component_cache
= ''
33 result
.append(self
._allocator
_type
)
34 if self
._symbolized
_typeinfo
== 'no typeinfo':
35 result
.append('tno_typeinfo')
37 result
.append('t' + self
._symbolized
_typeinfo
)
38 result
.append('n' + self
._typeinfo
_name
)
39 result
.extend(['%s(@%s)' % (function
, sourcefile
)
40 for function
, sourcefile
41 in zip(self
._symbolized
_stackfunction
,
42 self
._symbolized
_stacksourcefile
)])
43 return ' '.join(result
)
45 def symbolize(self
, symbol_mapping_cache
):
46 """Makes a symbolized stacktrace and typeinfo with |symbol_mapping_cache|.
49 symbol_mapping_cache: A SymbolMappingCache object.
51 # TODO(dmikurube): Fill explicitly with numbers if symbol not found.
52 self
._symbolized
_stackfunction
= [
53 symbol_mapping_cache
.lookup(FUNCTION_SYMBOLS
, address
)
54 for address
in self
._stacktrace
]
55 self
._symbolized
_joined
_stackfunction
= ' '.join(
56 self
._symbolized
_stackfunction
)
57 self
._symbolized
_stacksourcefile
= [
58 symbol_mapping_cache
.lookup(SOURCEFILE_SYMBOLS
, address
)
59 for address
in self
._stacktrace
]
60 self
._symbolized
_joined
_stacksourcefile
= ' '.join(
61 self
._symbolized
_stacksourcefile
)
62 if not self
._typeinfo
:
63 self
._symbolized
_typeinfo
= 'no typeinfo'
65 self
._symbolized
_typeinfo
= symbol_mapping_cache
.lookup(
66 TYPEINFO_SYMBOLS
, self
._typeinfo
)
67 if not self
._symbolized
_typeinfo
:
68 self
._symbolized
_typeinfo
= 'no typeinfo'
70 def clear_component_cache(self
):
71 self
.component_cache
= ''
75 return self
._stacktrace
78 def allocator_type(self
):
79 return self
._allocator
_type
86 def typeinfo_name(self
):
87 return self
._typeinfo
_name
90 def symbolized_stackfunction(self
):
91 return self
._symbolized
_stackfunction
94 def symbolized_joined_stackfunction(self
):
95 return self
._symbolized
_joined
_stackfunction
98 def symbolized_stacksourcefile(self
):
99 return self
._symbolized
_stacksourcefile
102 def symbolized_joined_stacksourcefile(self
):
103 return self
._symbolized
_joined
_stacksourcefile
106 def symbolized_typeinfo(self
):
107 return self
._symbolized
_typeinfo
110 class BucketSet(object):
111 """Represents a set of bucket."""
114 self
._code
_addresses
= set()
115 self
._typeinfo
_addresses
= set()
117 def load(self
, prefix
):
118 """Loads all related bucket files.
121 prefix: A prefix string for bucket file names.
123 LOGGER
.info('Loading bucket files.')
128 path
= '%s.%04d.buckets' % (prefix
, n
)
129 if not os
.path
.exists(path
) or not os
.stat(path
).st_size
:
135 LOGGER
.info(' %s' % path
)
136 with
open(path
, 'r') as f
:
141 def _load_file(self
, bucket_f
):
142 for line
in bucket_f
:
147 for index
, word
in enumerate(words
):
151 typeinfo
= int(word
[1:], 16)
152 self
._typeinfo
_addresses
.add(typeinfo
)
154 typeinfo_name
= word
[1:]
156 stacktrace_begin
= index
158 stacktrace
= [int(address
, 16) for address
in words
[stacktrace_begin
:]]
159 for frame
in stacktrace
:
160 self
._code
_addresses
.add(frame
)
161 self
._buckets
[int(words
[0])] = Bucket(
162 stacktrace
, words
[1], typeinfo
, typeinfo_name
)
165 for bucket_id
, bucket_content
in self
._buckets
.iteritems():
166 yield bucket_id
, bucket_content
168 def __getitem__(self
, bucket_id
):
169 return self
._buckets
[bucket_id
]
171 def get(self
, bucket_id
):
172 return self
._buckets
.get(bucket_id
)
174 def symbolize(self
, symbol_mapping_cache
):
175 for bucket_content
in self
._buckets
.itervalues():
176 bucket_content
.symbolize(symbol_mapping_cache
)
178 def clear_component_cache(self
):
179 for bucket_content
in self
._buckets
.itervalues():
180 bucket_content
.clear_component_cache()
182 def iter_addresses(self
, symbol_type
):
183 if symbol_type
in [FUNCTION_SYMBOLS
, SOURCEFILE_SYMBOLS
]:
184 for function
in self
._code
_addresses
:
187 for function
in self
._typeinfo
_addresses
: