OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // --- | 5 // --- |
6 // Author: Sainbayar Sukhbaatar | 6 // Author: Sainbayar Sukhbaatar |
7 // Dai Mikurube | 7 // Dai Mikurube |
8 // | 8 // |
9 // This file contains a class DeepHeapProfile and its public function | 9 // This file contains a class DeepHeapProfile and its public function |
10 // DeepHeapProfile::FillOrderedProfile() which works as an alternative of | 10 // DeepHeapProfile::FillOrderedProfile() which works as an alternative of |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "addressmap-inl.h" | 33 #include "addressmap-inl.h" |
34 #include "heap-profile-table.h" | 34 #include "heap-profile-table.h" |
35 | 35 |
36 class DeepHeapProfile { | 36 class DeepHeapProfile { |
37 public: | 37 public: |
38 typedef HeapProfileTable::Bucket Bucket; | 38 typedef HeapProfileTable::Bucket Bucket; |
39 typedef HeapProfileTable::AllocationMap AllocationMap; | 39 typedef HeapProfileTable::AllocationMap AllocationMap; |
40 typedef HeapProfileTable::AllocValue AllocValue; | 40 typedef HeapProfileTable::AllocValue AllocValue; |
41 typedef HeapProfileTable::Stats Stats; | 41 typedef HeapProfileTable::Stats Stats; |
42 | 42 |
| 43 enum MapsRegionType { |
| 44 // Bytes of memory which were not recognized with /proc/<pid>/maps. |
| 45 // This size should be 0. |
| 46 ABSENT, |
| 47 |
| 48 // Bytes of memory which is mapped anonymously. |
| 49 // Regions which contain nothing in the last column of /proc/<pid>/maps. |
| 50 ANONYMOUS, |
| 51 |
| 52 // Bytes of memory which is mapped to a executable/non-executable file. |
| 53 // Regions which contain file paths in the last column of /proc/<pid>/maps. |
| 54 FILE_EXEC, |
| 55 FILE_NONEXEC, |
| 56 |
| 57 // Bytes of memory which is labeled [stack] in /proc/<pid>/maps. |
| 58 STACK, |
| 59 |
| 60 // Bytes of memory which is labeled, but not mapped to any file. |
| 61 // Regions which contain non-path strings in the last column of |
| 62 // /proc/<pid>/maps. |
| 63 OTHER, |
| 64 |
| 65 NUMBER_OF_MAPS_REGION_TYPES |
| 66 }; |
| 67 |
43 // Construct a DeepHeapProfile instance. It works as a wrapper of | 68 // Construct a DeepHeapProfile instance. It works as a wrapper of |
44 // HeapProfileTable. | 69 // HeapProfileTable. |
45 // | 70 // |
46 // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads | 71 // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads |
47 // data in |heap_profile| and forwards operations to |heap_profile| if | 72 // data in |heap_profile| and forwards operations to |heap_profile| if |
48 // DeepHeapProfile is not available (non-Linux). | 73 // DeepHeapProfile is not available (non-Linux). |
49 // |prefix| is a prefix of dumped file names. | 74 // |prefix| is a prefix of dumped file names. |
50 DeepHeapProfile(HeapProfileTable* heap_profile, const char* prefix); | 75 DeepHeapProfile(HeapProfileTable* heap_profile, const char* prefix); |
51 ~DeepHeapProfile(); | 76 ~DeepHeapProfile(); |
52 | 77 |
(...skipping 19 matching lines...) Expand all Loading... |
72 struct PageState { | 97 struct PageState { |
73 bool is_committed; // Currently, we use only this | 98 bool is_committed; // Currently, we use only this |
74 bool is_present; | 99 bool is_present; |
75 bool is_swapped; | 100 bool is_swapped; |
76 bool is_shared; | 101 bool is_shared; |
77 bool is_mmap; | 102 bool is_mmap; |
78 }; | 103 }; |
79 | 104 |
80 class RegionStats { | 105 class RegionStats { |
81 public: | 106 public: |
82 RegionStats() {} | 107 RegionStats(): virtual_bytes_(0), committed_bytes_(0) {} |
83 ~RegionStats() {} | 108 ~RegionStats() {} |
84 | 109 |
85 // Initialize virtual_bytes and committed_bytes. | 110 // Initialize virtual_bytes and committed_bytes. |
86 void Initialize(); | 111 void Initialize(); |
87 | 112 |
88 // Update the RegionStats to include the tallies of virtual_bytes and | 113 // Update the RegionStats to include the tallies of virtual_bytes and |
89 // committed_bytes in the region from |first_adress| to |last_address| | 114 // committed_bytes in the region from |first_adress| to |last_address| |
90 // inclusive. | 115 // inclusive. |
91 void Record(int pagemap_fd, uint64 first_address, uint64 last_address); | 116 void Record(int pagemap_fd, uint64 first_address, uint64 last_address); |
92 | 117 |
93 size_t virtual_bytes() const { return virtual_bytes_; } | 118 size_t virtual_bytes() const { return virtual_bytes_; } |
94 size_t committed_bytes() const { return committed_bytes_; } | 119 size_t committed_bytes() const { return committed_bytes_; } |
95 void set_virtual_bytes(size_t virtual_bytes) { | 120 void set_virtual_bytes(size_t virtual_bytes) { |
96 virtual_bytes_ = virtual_bytes; | 121 virtual_bytes_ = virtual_bytes; |
97 } | 122 } |
98 void set_committed_bytes(size_t committed_bytes) { | 123 void set_committed_bytes(size_t committed_bytes) { |
99 committed_bytes_ = committed_bytes; | 124 committed_bytes_ = committed_bytes; |
100 } | 125 } |
101 void AddToVirtualBytes(size_t additional_virtual_bytes) { | 126 void AddToVirtualBytes(size_t additional_virtual_bytes) { |
102 virtual_bytes_ += additional_virtual_bytes; | 127 virtual_bytes_ += additional_virtual_bytes; |
103 } | 128 } |
104 void AddToCommittedBytes(size_t additional_committed_bytes) { | 129 void AddToCommittedBytes(size_t additional_committed_bytes) { |
105 committed_bytes_ += additional_committed_bytes; | 130 committed_bytes_ += additional_committed_bytes; |
106 } | 131 } |
| 132 void AddAnotherRegionStat(const RegionStats& other) { |
| 133 virtual_bytes_ += other.virtual_bytes_; |
| 134 committed_bytes_ += other.committed_bytes_; |
| 135 } |
107 | 136 |
108 private: | 137 private: |
109 size_t virtual_bytes_; | 138 size_t virtual_bytes_; |
110 size_t committed_bytes_; | 139 size_t committed_bytes_; |
111 DISALLOW_COPY_AND_ASSIGN(RegionStats); | 140 DISALLOW_COPY_AND_ASSIGN(RegionStats); |
112 }; | 141 }; |
113 | 142 |
114 struct GlobalStats { | 143 struct GlobalStats { |
115 // All RegionStats members in this class contain the bytes of virtual | 144 // All RegionStats members in this class contain the bytes of virtual |
116 // memory and committed memory. | 145 // memory and committed memory. |
117 // TODO(dmikurube): These regions should be classified more precisely later | 146 // TODO(dmikurube): These regions should be classified more precisely later |
118 // for more detailed analysis. | 147 // for more detailed analysis. |
119 | 148 RegionStats all[NUMBER_OF_MAPS_REGION_TYPES]; |
120 // Total bytes of the process memory. | 149 RegionStats nonprofiled[NUMBER_OF_MAPS_REGION_TYPES]; |
121 RegionStats total; | |
122 | |
123 // Total bytes of memory which is mapped to a file. | |
124 // Regions which contain file paths in the last column of /proc/<pid>/maps. | |
125 RegionStats file_mapped; | |
126 | |
127 // Total bytes of memory which is mapped anonymously. | |
128 // Regions which contain nothing in the last column of /proc/<pid>/maps. | |
129 RegionStats anonymous; | |
130 | |
131 // Total bytes of memory which is labeled, but not mapped to any file. | |
132 // Regions which contain non-path strings in the last column of | |
133 // /proc/<pid>/maps. | |
134 RegionStats other; | |
135 | 150 |
136 // Total bytes of mmap'ed regions. | 151 // Total bytes of mmap'ed regions. |
137 RegionStats record_mmap; | 152 RegionStats profiled_mmap; |
138 | 153 |
139 // Total bytes of malloc'ed regions. | 154 // Total bytes of malloc'ed regions. |
140 RegionStats record_malloc; | 155 RegionStats profiled_malloc; |
| 156 }; |
| 157 |
| 158 struct MMapListEntry { |
| 159 uint64 first_address; |
| 160 uint64 last_address; |
| 161 MapsRegionType type; |
141 }; | 162 }; |
142 | 163 |
143 // Checks if the length of |printed| characters by snprintf is valid. | 164 // Checks if the length of |printed| characters by snprintf is valid. |
144 static bool IsPrintedStringValid(int printed, | 165 static bool IsPrintedStringValid(int printed, |
145 int buffer_size, | 166 int buffer_size, |
146 int used_in_buffer); | 167 int used_in_buffer); |
147 | 168 |
148 // Clear the is_logged flag in a DeepBucket object as a callback function | 169 // Clear the is_logged flag in a DeepBucket object as a callback function |
149 // for DeepBucketMap::Iterate(). | 170 // for DeepBucketMap::Iterate(). |
150 static void ClearIsLogged(const void* pointer, | 171 static void ClearIsLogged(const void* pointer, |
(...skipping 20 matching lines...) Expand all Loading... |
171 | 192 |
172 // Write re-formatted /proc/self/maps into a file which has |filename_prefix| | 193 // Write re-formatted /proc/self/maps into a file which has |filename_prefix| |
173 // with using |buffer| of size |buffer_size|. | 194 // with using |buffer| of size |buffer_size|. |
174 static void WriteMapsToFile(const char* filename_prefix, | 195 static void WriteMapsToFile(const char* filename_prefix, |
175 int buffer_size, | 196 int buffer_size, |
176 char buffer[]); | 197 char buffer[]); |
177 | 198 |
178 // Compute the global statistics from /proc/self/maps and |pagemap_fd|, and | 199 // Compute the global statistics from /proc/self/maps and |pagemap_fd|, and |
179 // store the statistics in |stats|. | 200 // store the statistics in |stats|. |
180 static void SnapshotGlobalStatsWithoutMalloc(int pagemap_fd, | 201 static void SnapshotGlobalStatsWithoutMalloc(int pagemap_fd, |
181 GlobalStats* stats); | 202 GlobalStats* stats, |
| 203 MMapListEntry* mmap_list, |
| 204 int mmap_list_length); |
182 | 205 |
183 // Get the DeepBucket object corresponding to the given |bucket|. | 206 // Get the DeepBucket object corresponding to the given |bucket|. |
184 // DeepBucket is an extension to Bucket which is declared above. | 207 // DeepBucket is an extension to Bucket which is declared above. |
185 DeepBucket* GetDeepBucket(Bucket* bucket); | 208 DeepBucket* GetDeepBucket(Bucket* bucket); |
186 | 209 |
187 // Reset committed_size member variables in DeepBucket objects to 0. | 210 // Reset committed_size member variables in DeepBucket objects to 0. |
188 void ResetCommittedSize(Bucket** bucket_table); | 211 void ResetCommittedSize(Bucket** bucket_table); |
189 | 212 |
190 // Fill bucket data in |bucket_table| into buffer |buffer| of size | 213 // Fill bucket data in |bucket_table| into buffer |buffer| of size |
191 // |buffer_size|, and return the size occupied by the bucket data in | 214 // |buffer_size|, and return the size occupied by the bucket data in |
192 // |buffer|. |bucket_length| is the offset for |buffer| to start filling. | 215 // |buffer|. |bucket_length| is the offset for |buffer| to start filling. |
193 int SnapshotBucketTableWithoutMalloc(Bucket** bucket_table, | 216 int SnapshotBucketTableWithoutMalloc(Bucket** bucket_table, |
194 int used_in_buffer, | 217 int used_in_buffer, |
195 int buffer_size, | 218 int buffer_size, |
196 char buffer[]); | 219 char buffer[]); |
197 | 220 |
| 221 static bool ByFirstAddress(const MMapListEntry& a, |
| 222 const MMapListEntry& b); |
| 223 |
| 224 // Count mmap allocations in deep_profile->num_mmap_allocations_. |
| 225 static void CountMMap(const void* pointer, |
| 226 AllocValue* alloc_value, |
| 227 DeepHeapProfile* deep_profile); |
| 228 |
198 // Record both virtual and committed byte counts of malloc and mmap regions | 229 // Record both virtual and committed byte counts of malloc and mmap regions |
199 // as callback functions for AllocationMap::Iterate(). | 230 // as callback functions for AllocationMap::Iterate(). |
200 static void RecordAlloc(const void* pointer, | 231 static void RecordAlloc(const void* pointer, |
201 AllocValue* alloc_value, | 232 AllocValue* alloc_value, |
202 DeepHeapProfile* deep_profile); | 233 DeepHeapProfile* deep_profile); |
203 static void RecordMMap(const void* pointer, | 234 static void RecordMMap(const void* pointer, |
204 AllocValue* alloc_value, | 235 AllocValue* alloc_value, |
205 DeepHeapProfile* deep_profile); | 236 DeepHeapProfile* deep_profile); |
206 void SnapshotAllAllocsWithoutMalloc(); | 237 void SnapshotAllAllocsWithoutMalloc(); |
207 | 238 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 272 |
242 // Process ID of the last dump. This could change by fork. | 273 // Process ID of the last dump. This could change by fork. |
243 pid_t most_recent_pid_; | 274 pid_t most_recent_pid_; |
244 GlobalStats stats_; // Stats about total memory. | 275 GlobalStats stats_; // Stats about total memory. |
245 int dump_count_; // The number of dumps. | 276 int dump_count_; // The number of dumps. |
246 char* filename_prefix_; // Output file prefix. | 277 char* filename_prefix_; // Output file prefix. |
247 char* profiler_buffer_; // Buffer we use many times. | 278 char* profiler_buffer_; // Buffer we use many times. |
248 | 279 |
249 int bucket_id_; | 280 int bucket_id_; |
250 DeepBucketMap* deep_bucket_map_; | 281 DeepBucketMap* deep_bucket_map_; |
| 282 MMapListEntry* mmap_list_; |
| 283 int mmap_list_length_; |
| 284 int num_mmap_allocations_; |
251 #endif // DEEP_HEAP_PROFILE | 285 #endif // DEEP_HEAP_PROFILE |
252 | 286 |
253 HeapProfileTable* heap_profile_; | 287 HeapProfileTable* heap_profile_; |
254 | 288 |
255 DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile); | 289 DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile); |
256 }; | 290 }; |
257 | 291 |
258 #endif // BASE_DEEP_HEAP_PROFILE_H_ | 292 #endif // BASE_DEEP_HEAP_PROFILE_H_ |
OLD | NEW |