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

Side by Side Diff: third_party/tcmalloc/chromium/src/deep-heap-profile.h

Issue 8632007: A deeper heap profile dumper in third_party/tcmalloc/chromium. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: reflected the comments. Created 8 years, 9 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
« no previous file with comments | « base/allocator/allocator.gyp ('k') | third_party/tcmalloc/chromium/src/deep-heap-profile.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // ---
6 // Author: Sainbayar Sukhbaatar
7 // Dai Mikurube
8 //
9 // This file contains a class DeepHeapProfile and its public function
10 // DeepHeapProfile::FillOrderedProfile() which works as an alternative of
11 // HeapProfileTable::FillOrderedProfile().
12 //
13 // DeepHeapProfile::FillOrderedProfile() dumps more detailed information about
14 // heap usage, which includes OS-level information such as whether the memory
15 // block is actually in memory, or not. DeepHeapProfile::FillOrderedProfile()
16 // uses logged data in HeapProfileTable as one of its data sources.
17 // DeepHeapProfile works only when its FillOrderedProfile() is called. It has
18 // overhead when dumping, but no overhead when logging.
19 //
20 // It currently works only on Linux. It just delegates to HeapProfileTable in
21 // non-Linux environments.
22
23
24 #ifndef BASE_DEEP_HEAP_PROFILE_H_
25 #define BASE_DEEP_HEAP_PROFILE_H_
26
27 #include "config.h"
28
29 #if defined(__linux__)
30 #define DEEP_HEAP_PROFILE 1
31 #endif
32
33 #include "addressmap-inl.h"
34 #include "heap-profile-table.h"
35
36 class DeepHeapProfile {
37 public:
38 typedef HeapProfileTable::Bucket Bucket;
39 typedef HeapProfileTable::AllocationMap AllocationMap;
40 typedef HeapProfileTable::AllocValue AllocValue;
41 typedef HeapProfileTable::Stats Stats;
42
43 // Construct a DeepHeapProfile instance. It works as a wrapper of
44 // HeapProfileTable.
45 //
46 // |heap_profile| is a pointer to HeapProfileTable. DeepHeapProfile reads
47 // data in |heap_profile| and forwards operations to |heap_profile| if
48 // DeepHeapProfile is not available (non-Linux).
49 // |prefix| is a prefix of dumped file names.
50 DeepHeapProfile(HeapProfileTable* heap_profile, const char* prefix);
51 ~DeepHeapProfile();
52
53 // Fill deep profile data into |buffer| of |size|, and return the actual
54 // size occupied by the dump in |buffer|. It works as an alternative
55 // of HeapProfileTable::FillOrderedProfile.
56 //
57 // The profile buckets are dumped in the decreasing order of currently
58 // allocated bytes. We do not provision for 0-terminating |buffer|.
59 int FillOrderedProfile(char buffer[], int buffer_size);
60
61 private:
62 #ifdef DEEP_HEAP_PROFILE
63 struct DeepBucket {
64 Bucket* bucket;
65 size_t committed_size;
66 int id; // Unique ID of the bucket.
67 bool is_logged; // True if the stracktrace is logged to a file.
68 };
69
70 typedef AddressMap<DeepBucket> DeepBucketMap;
71
72 struct PageState {
73 bool is_committed; // Currently, we use only this
74 bool is_present;
75 bool is_swapped;
76 bool is_shared;
77 bool is_mmap;
78 };
79
80 class RegionStats {
81 public:
82 RegionStats() {}
83 ~RegionStats() {}
84
85 // Initialize virtual_bytes and committed_bytes.
86 void Initialize();
87
88 // Update the RegionStats to include the tallies of virtual_bytes and
89 // committed_bytes in the region from |first_adress| to |last_address|
90 // inclusive.
91 void Record(int pagemap_fd, uint64 first_address, uint64 last_address);
92
93 size_t virtual_bytes() const { return virtual_bytes_; }
94 size_t committed_bytes() const { return committed_bytes_; }
95 void set_virtual_bytes(size_t virtual_bytes) {
96 virtual_bytes_ = virtual_bytes;
97 }
98 void set_committed_bytes(size_t committed_bytes) {
99 committed_bytes_ = committed_bytes;
100 }
101 void AddToVirtualBytes(size_t additional_virtual_bytes) {
102 virtual_bytes_ += additional_virtual_bytes;
103 }
104 void AddToCommittedBytes(size_t additional_committed_bytes) {
105 committed_bytes_ += additional_committed_bytes;
106 }
107
108 private:
109 size_t virtual_bytes_;
110 size_t committed_bytes_;
111 DISALLOW_COPY_AND_ASSIGN(RegionStats);
112 };
113
114 struct GlobalStats {
115 // All RegionStats members in this class contain the bytes of virtual
116 // memory and committed memory.
117 // TODO(dmikurube): These regions should be classified more precisely later
118 // for more detailed analysis.
119
120 // Total bytes of the process memory.
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
136 // Total bytes of mmap'ed regions.
137 RegionStats record_mmap;
138
139 // Total bytes of malloc'ed regions.
140 RegionStats record_malloc;
141 };
142
143 // Checks if the length of |printed| characters by snprintf is valid.
144 static bool IsPrintedStringValid(int printed,
145 int buffer_size,
146 int used_in_buffer);
147
148 // Clear the is_logged flag in a DeepBucket object as a callback function
149 // for DeepBucketMap::Iterate().
150 static void ClearIsLogged(const void* pointer,
151 DeepBucket* db,
152 DeepHeapProfile* deep_profile);
153
154 // Open /proc/pid/pagemap and return its file descriptor.
155 // File descriptors need to be refreshed after each fork.
156 static int OpenProcPagemap();
157
158 // Seek to the offset of the open pagemap file pagemap_fd.
159 // It returns true if succeeded. Otherwise, it returns false.
160 static bool SeekProcPagemap(int pagemap_fd, uint64 address);
161
162 // Read a pagemap state from the current pagemap_fd offset.
163 // It returns true if succeeded. Otherwise, it returns false.
164 static bool ReadProcPagemap(int pagemap_fd, PageState* state);
165
166 // Returns the number of resident (including swapped) bytes of the memory
167 // region starting at |first_address| and ending at |last_address| inclusive.
168 static size_t GetCommittedSize(int pagemap_fd,
169 uint64 first_address,
170 uint64 last_address);
171
172 // Write re-formatted /proc/self/maps into a file which has |filename_prefix|
173 // with using |buffer| of size |buffer_size|.
174 static void WriteMapsToFile(const char* filename_prefix,
175 int buffer_size,
176 char buffer[]);
177
178 // Compute the global statistics from /proc/self/maps and |pagemap_fd|, and
179 // store the statistics in |stats|.
180 static void SnapshotGlobalStatsWithoutMalloc(int pagemap_fd,
181 GlobalStats* stats);
182
183 // Get the DeepBucket object corresponding to the given |bucket|.
184 // DeepBucket is an extension to Bucket which is declared above.
185 DeepBucket* GetDeepBucket(Bucket* bucket);
186
187 // Reset committed_size member variables in DeepBucket objects to 0.
188 void ResetCommittedSize(Bucket** bucket_table);
189
190 // Fill bucket data in |bucket_table| into buffer |buffer| of size
191 // |buffer_size|, and return the size occupied by the bucket data in
192 // |buffer|. |bucket_length| is the offset for |buffer| to start filling.
193 int SnapshotBucketTableWithoutMalloc(Bucket** bucket_table,
194 int used_in_buffer,
195 int buffer_size,
196 char buffer[]);
197
198 // Record both virtual and committed byte counts of malloc and mmap regions
199 // as callback functions for AllocationMap::Iterate().
200 static void RecordAlloc(const void* pointer,
201 AllocValue* alloc_value,
202 DeepHeapProfile* deep_profile);
203 static void RecordMMap(const void* pointer,
204 AllocValue* alloc_value,
205 DeepHeapProfile* deep_profile);
206 void SnapshotAllAllocsWithoutMalloc();
207
208 // Fill a bucket (a bucket id and its corresponding calling stack) into
209 // |buffer| of size |buffer_size|.
210 int FillBucketForBucketFile(const DeepBucket* deep_bucket,
211 int buffer_size,
212 char buffer[]);
213
214 // Write a |bucket_table| into a file of |bucket_fd|.
215 void WriteBucketsTableToBucketFile(Bucket** bucket_table, RawFD bucket_fd);
216
217 // Write both malloc and mmap bucket tables into a "bucket file".
218 void WriteBucketsToBucketFile();
219
220 // Fill a |deep_bucket| and its corresponding bucket into |buffer| from the
221 // offset |used_in_buffer|. Add the sizes to |profile_stats| if it's not
222 // NULL.
223 static int UnparseBucket(const DeepBucket& deep_bucket,
224 const char* extra,
225 int used_in_buffer,
226 int buffer_size,
227 char* buffer,
228 Stats* profile_stats);
229
230 // Fill statistics of a region into |buffer|.
231 static int UnparseRegionStats(const RegionStats* stats,
232 const char* name,
233 int used_in_buffer,
234 int buffer_size,
235 char* buffer);
236
237 // Fill global statistics into |buffer|.
238 int UnparseGlobalStats(int used_in_buffer, int buffer_size, char* buffer);
239
240 int pagemap_fd_; // File descriptor of /proc/self/pagemap.
241
242 // Process ID of the last dump. This could change by fork.
243 pid_t most_recent_pid_;
244 GlobalStats stats_; // Stats about total memory.
245 int dump_count_; // The number of dumps.
246 char* filename_prefix_; // Output file prefix.
247 char* profiler_buffer_; // Buffer we use many times.
248
249 int bucket_id_;
250 DeepBucketMap* deep_bucket_map_;
251 #endif // DEEP_HEAP_PROFILE
252
253 HeapProfileTable* heap_profile_;
254
255 DISALLOW_COPY_AND_ASSIGN(DeepHeapProfile);
256 };
257
258 #endif // BASE_DEEP_HEAP_PROFILE_H_
OLDNEW
« no previous file with comments | « base/allocator/allocator.gyp ('k') | third_party/tcmalloc/chromium/src/deep-heap-profile.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698