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

Side by Side Diff: runtime/vm/heap_profiler.h

Issue 10452006: Implement a heap profiler for the Dart managed heap. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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 (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef VM_HEAP_PROFILER_H_
6 #define VM_HEAP_PROFILER_H_
7
8 #include <set>
9
10 #include "include/dart_api.h"
11 #include "vm/globals.h"
12 #include "vm/handles.h"
13 #include "vm/object.h"
14 #include "vm/visitor.h"
15
16 namespace dart {
17
turnidge 2012/05/29 17:50:01 Maybe add a top-level comment describing what the
cshapiro 2012/06/01 04:27:02 A great idea. Done.
18 class HeapProfiler {
19 public:
20 HeapProfiler(Dart_HeapProfileWriteCallback callback, void* stream);
21 ~HeapProfiler();
22
23 // Writes a root to the heap dump.
24 void WriteRoot(const RawObject* raw_obj);
25
26 // Writes a object to the heap dump.
27 void WriteObject(const RawObject* raw_obj);
28
29 private:
30 // Record tags describe top-level records.
31 enum Tag {
32 kStringInUtf8 = 0x01,
33 kLoadClass = 0x02,
34 kUnloadClass = 0x03,
35 kStackFrame = 0x04,
36 kStackTrace = 0x05,
37 kAllocSites = 0x06,
38 kHeapSummary = 0x07,
39 kStartThread = 0x0A,
40 kEndThread = 0x0B,
41 kHeapDump = 0x0C,
42 kCpuSamples = 0x0D,
43 kControlSettings = 0x0E,
44 kHeapDumpSummary = 0x1C,
45 kHeapDumpEnd = 0x2C
46 };
47
48 // Sub-record tags describe sub-records within a heap dump.
49 enum Subtag {
50 kRootJniGlobal = 0x01,
51 kRootJniLocal = 0x01,
52 kRootJavaFrame = 0x03,
53 kRootNativeStack = 0x04,
54 kRootStickyClass = 0x05,
55 kRootThreadBlock = 0x06,
56 kRootMonitorUsed = 0x07,
57 kRootThreadObject = 0x08,
58 kClassDump = 0x20,
59 kInstanceDump = 0x21,
60 kObjectArrayDump = 0x22,
61 kPrimitiveArrayDump = 0x23,
62 kRootUnknown = 0xFF
63 };
64
65 // Tags for describing element and field types.
66 enum BasicType {
67 kObject = 2,
68 kBoolean = 4,
69 kChar = 5,
70 kFloat = 6,
71 kDouble = 7,
72 kByte = 8,
73 kShort = 9,
74 kInt = 10,
75 kLong = 11
76 };
77
78 // A growable array of bytes used to build a record body.
79 class Buffer {
80 public:
81 Buffer() : data_(0), size_(0), capacity_(0) {
82 }
83 ~Buffer();
84
85 // Writes an array of bytes to the buffer, increasing the capacity
86 // as needed.
87 void Write(const uint8_t* data, intptr_t length);
88
89 // Returns the underlying element storage.
90 const uint8_t* Data() const {
91 return data_;
92 }
93
94 // Returns the number of elements written to the buffer.
95 intptr_t Size() const {
96 return size_;
97 }
98
99 private:
100 // Resizes the element storage, if needed.
101 void EnsureCapacity(intptr_t size);
102
103 uint8_t* data_;
104
105 intptr_t size_;
106
107 // Size of the element storage.
108 intptr_t capacity_;
109
110 DISALLOW_COPY_AND_ASSIGN(Buffer);
111 };
112
113 // A top-level data record.
114 class Record {
115 public:
116 Record(uint8_t tag, HeapProfiler* profiler)
117 : tag_(tag), profiler_(profiler) {
118 }
119 ~Record() {
120 profiler_->WriteRecord(*this);
121 }
122
123 // Returns the tag describing the record format.
124 uint8_t Tag() const {
125 return tag_;
126 }
127
128 // Returns a millisecond time delta, always 0.
129 uint8_t Time() const {
130 return 0;
131 }
132
133 // Returns the record length in bytes.
134 uint32_t Length() const {
135 return body_.Size();
136 }
137
138 // Returns the record body.
139 const uint8_t* Body() const {
140 return body_.Data();
141 }
142
143 // Appends an array of 8-bit values to the record body.
144 void Write(const uint8_t* value, intptr_t size);
145
146 // Appends an 8-, 16-, 32- or 64-bit value to the body in
147 // big-endian format.
148 void Write8(uint8_t value);
149 void Write16(uint16_t value);
150 void Write32(uint32_t value);
151 void Write64(uint64_t value);
152
153 // Appends an ID to the body.
154 void WritePointer(const void* value);
155
156 private:
157 // A tag value that describes the record format.
158 uint8_t tag_;
159
160 // The payload of the record as described by the tag.
161 Buffer body_;
162
163 // Parent object.
164 HeapProfiler* profiler_;
165
166 DISALLOW_COPY_AND_ASSIGN(Record);
167 };
168
169 // A sub-record within a heap dump record. Write calls are
170 // forwarded to the profilers heap dump record instance.
171 class SubRecord {
172 public:
173 // Starts a new sub-record within the heap dump record.
174 SubRecord(uint8_t sub_tag, HeapProfiler* profiler);
175 ~SubRecord();
176
177 // Appends an array of 8-bit values to the heap dump record.
178 void Write(const uint8_t* value, intptr_t size);
179
180 // Appends an 8-, 16-, 32- or 64-bit value to the heap dump
181 // record.
182 void Write8(uint8_t value);
183 void Write16(uint16_t value);
184 void Write32(uint32_t value);
185 void Write64(uint64_t value);
186
187 // Appends an ID to the current heap dump record.
188 void WritePointer(const void* value);
189
190 private:
191 // The record instance that receives forwarded write calls.
192 Record* record_;
193 };
194
195 // Id canonizers.
196 const RawClass* ClassId(const RawClass* raw_class);
197 const RawObject* ObjectId(const RawObject* raw_obj);
198 const char* StringId(const char* c_string);
199 const RawString* StringId(const RawString* raw_string);
200
201 // Invokes the write callback.
202 void Write(const void* data, intptr_t size);
203
204 // Writes the binary hprof header to the output stream.
205 void WriteHeader();
206
207 // Writes a record to the output stream.
208 void WriteRecord(const Record& record);
209
210
211 // Writes a string in utf-8 record to the output stream.
212 void WriteStringInUtf8(const char* c_string);
213 void WriteStringInUtf8(const RawString* raw_string);
214
215
216 // Writes a load class record to the output stream.
217 void WriteLoadClass(const RawClass* raw_class);
218
219 // Writes an empty stack trace to the output stream.
220 void WriteStackTrace();
221
222 // Writes a heap summary record to the output stream.
223 void WriteHeapSummary(uint32_t total_live_bytes,
224 uint32_t total_live_instances,
225 uint64_t total_bytes_allocated,
226 uint64_t total_instances_allocated);
227
228 // Writes a heap dump record to the output stream.
229 void WriteHeapDump();
230
231 // Writes a sub-record to the heap dump record.
232 void WriteClassDump(const RawClass* raw_class);
233 void WriteInstanceDump(const RawObject* raw_obj);
234 void WriteObjectArrayDump(const RawArray* raw_array);
235 void WritePrimitiveArrayDump(const RawByteArray* raw_byte_array,
236 uint8_t tag,
237 const void* data);
238
239 Dart_HeapProfileWriteCallback write_callback_;
240
241 void* output_stream_;
242
243 Record* heap_dump_record_;
244
245 std::set<const RawSmi*> smi_table_;
246 std::set<const RawClass*> class_table_;
247 std::set<const RawString*> string_table_;
248
249 DISALLOW_COPY_AND_ASSIGN(HeapProfiler);
250 };
251
252
253 // Writes a root sub-record to the heap dump for every strong handle.
254 class HeapProfilerRootVisitor : public ObjectPointerVisitor {
255 public:
256 explicit HeapProfilerRootVisitor(HeapProfiler* profiler)
257 : profiler_(profiler) {
258 }
259
260 virtual void VisitPointers(RawObject** first, RawObject** last);
261
262 private:
263 HeapProfiler* profiler_;
264 DISALLOW_COPY_AND_ASSIGN(HeapProfilerRootVisitor);
265 };
266
267
268 // Writes a root sub-record to the heap dump for every weak handle.
269 class HeapProfilerWeakRootVisitor : public HandleVisitor {
270 public:
271 explicit HeapProfilerWeakRootVisitor(HeapProfilerRootVisitor* visitor)
272 : visitor_(visitor) {
273 }
274
275 virtual void VisitHandle(uword addr);
276
277 private:
278 HeapProfilerRootVisitor* visitor_;
279 DISALLOW_COPY_AND_ASSIGN(HeapProfilerWeakRootVisitor);
280 };
281
282
283 // Writes a sub-record to the heap dump for every object in the heap.
284 class HeapProfilerObjectVisitor : public ObjectVisitor {
285 public:
286 explicit HeapProfilerObjectVisitor(HeapProfiler* profiler)
287 : profiler_(profiler) {
288 }
289
290 virtual void VisitObject(RawObject* obj);
291
292 private:
293 HeapProfiler* profiler_;
294 DISALLOW_COPY_AND_ASSIGN(HeapProfilerObjectVisitor);
295 };
296
297 } // namespace dart
298
299 #endif // VM_HEAP_PROFILER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698