OLD | NEW |
| (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_TRACE_H_ | |
6 #define VM_HEAP_TRACE_H_ | |
7 | |
8 #include "include/dart_api.h" | |
9 #include "vm/globals.h" | |
10 #include "vm/object_set.h" | |
11 | |
12 namespace dart { | |
13 | |
14 // Forward declarations. | |
15 class HeapTraceVisitor; | |
16 class Isolate; | |
17 class RawClass; | |
18 class RawObject; | |
19 class RawString; | |
20 class BaseZone; | |
21 | |
22 class HeapTrace { | |
23 public: | |
24 enum RecordSize { | |
25 kRootSize = 5, | |
26 kAllocSize = 9, | |
27 kSnapshotAllocSize = 9, | |
28 kCopySize = 9, | |
29 kStoreSize = 13, | |
30 kSweepSize = 5, | |
31 kDeathRangeSize = 9, | |
32 kPromotionSize = 9, | |
33 kAllocZoneHandleSize = 9, | |
34 kDeleteZoneSize = 5, | |
35 kRegisterClassSize = 5, | |
36 kAllocScopedHandleSize = 5, | |
37 kDeleteScopedHandlesSize = 1, | |
38 kMarkSweepStartSize = 1, | |
39 kMarkSweepFinishSize = 1, | |
40 kObjectStoreSize = 5 | |
41 }; | |
42 | |
43 enum RecordType { | |
44 kRootType = 'R', | |
45 kAllocType = 'A', | |
46 kSnapshotAllocType = 'B', | |
47 kCopyType = 'C', | |
48 kStoreType = 'U', | |
49 kSweepType = 'S', | |
50 kDeathRangeType = 'L', | |
51 kPromotionType = 'P', | |
52 kAllocZoneHandleType = 'Z', | |
53 kDeleteZoneType = 'z', | |
54 kRegisterClassType = 'K', | |
55 kAllocScopedHandleType = 'H', | |
56 kDeleteScopedHandlesType = 'h', | |
57 kMarkSweepStartType = '{', | |
58 kMarkSweepFinishType = '}', | |
59 kObjectStoreType = 'O' | |
60 }; | |
61 | |
62 template <RecordType T, RecordSize N> | |
63 class Record { | |
64 public: | |
65 explicit Record(HeapTrace* trace): cursor_(0), trace_(trace) { | |
66 ASSERT(N >= 1); | |
67 buffer_[0] = T; | |
68 ++cursor_; | |
69 } | |
70 ~Record() { | |
71 (*trace_->write_callback_)(Buffer(), Length(), trace_->output_stream_); | |
72 } | |
73 | |
74 void Write(uword word) { | |
75 ASSERT(cursor_ + sizeof(word) <= N); | |
76 memmove(&buffer_[cursor_], &word, sizeof(word)); | |
77 cursor_ += sizeof(word); | |
78 } | |
79 | |
80 intptr_t Length() const { return cursor_; } | |
81 | |
82 const uint8_t* Buffer() const { | |
83 ASSERT(cursor_ == N); | |
84 return buffer_; | |
85 } | |
86 | |
87 private: | |
88 uint8_t buffer_[N]; | |
89 intptr_t cursor_; | |
90 HeapTrace* trace_; | |
91 DISALLOW_COPY_AND_ASSIGN(Record); | |
92 }; | |
93 | |
94 typedef Record<kRootType, kRootSize> RootRecord; | |
95 typedef Record<kAllocType, kAllocSize> AllocationRecord; | |
96 typedef Record<kSnapshotAllocType, kSnapshotAllocSize> | |
97 SnapshotAllocationRecord; | |
98 typedef Record<kCopyType, kCopySize> CopyRecord; | |
99 typedef Record<kStoreType, kStoreSize> StoreRecord; | |
100 typedef Record<kSweepType, kSweepSize> SweepRecord; | |
101 typedef Record<kDeathRangeType, kDeathRangeSize> DeathRangeRecord; | |
102 typedef Record<kPromotionType, kPromotionSize> PromotionRecord; | |
103 typedef Record<kAllocZoneHandleType, kAllocZoneHandleSize> | |
104 AllocZoneHandleRecord; | |
105 typedef Record<kDeleteZoneType, kDeleteZoneSize> | |
106 DeleteZoneRecord; | |
107 typedef Record<kRegisterClassType, kRegisterClassSize> RegisterClassRecord; | |
108 typedef Record<kAllocScopedHandleType, kAllocScopedHandleSize> | |
109 AllocScopedHandleRecord; | |
110 typedef Record<kDeleteScopedHandlesType, kDeleteScopedHandlesSize> | |
111 DeleteScopedHandlesRecord; | |
112 typedef Record<kMarkSweepStartType, kMarkSweepStartSize> MarkSweepStartRecord; | |
113 typedef Record<kMarkSweepFinishType, kMarkSweepFinishSize> | |
114 MarkSweepFinishRecord; | |
115 typedef Record<kObjectStoreType, kObjectStoreSize> ObjectStoreRecord; | |
116 | |
117 HeapTrace(); | |
118 ~HeapTrace(); | |
119 | |
120 // Called by the isolate just before EnableGrowthControl. Indicates | |
121 // the Isolate is initialized and enables tracing. | |
122 void Init(Isolate* isolate); | |
123 | |
124 // Called when an object is allocated in the heap. | |
125 void TraceAllocation(uword addr, intptr_t size); | |
126 | |
127 // Invoked after the snapshot is loaded at Isolate startup time. | |
128 void TraceSnapshotAlloc(RawObject* obj, intptr_t size); | |
129 | |
130 // Rename to something like TraceAllocateZoneHandle (or whatever) | |
131 void TraceAllocateZoneHandle(uword handle, uword zone_addr); | |
132 | |
133 // Invoked when a Zone block is deleted. | |
134 void TraceDeleteZone(Zone* zone); | |
135 | |
136 // Invoked whenever the scoped handles are delelted. | |
137 void TraceDeleteScopedHandles(); | |
138 | |
139 // Invoked when objects are coped from the from space to the to space | |
140 // by the scavenger. | |
141 void TraceCopy(uword from_addr, uword to_addr); | |
142 | |
143 // Invoked on each pointer in the object store. | |
144 void TraceObjectStorePointer(uword addr); | |
145 | |
146 // Invoked when an object is promoted from the new space to the old space. | |
147 void TracePromotion(uword old_addr, uword promoted_addr); | |
148 | |
149 // Invoked after a scavenge with the addressed range of from-space | |
150 void TraceDeathRange(uword inclusive_start, uword exclusive_end); | |
151 | |
152 // Invoked whenever a class is registered in the class table. | |
153 void TraceRegisterClass(const Class& cls); | |
154 | |
155 // Invoked when an address is swept. | |
156 void TraceSweep(uword sweept_addr); | |
157 | |
158 // Invoked when storing value into origin, and value is an object. | |
159 void TraceStoreIntoObject(uword origin_object_addr, | |
160 uword slot_addr, | |
161 uword value); | |
162 | |
163 // Invoked when starting a mark-sweep collection on old space | |
164 void TraceMarkSweepStart(); | |
165 | |
166 // Invoked after finishing a mark sweep collection on old space. | |
167 void TraceMarkSweepFinish(); | |
168 | |
169 // Initialize tracing globablly across the VM. Invidual isolates | |
170 // will still have to initialized themselves when they are started. | |
171 static void InitOnce(Dart_FileOpenCallback open_callback, | |
172 Dart_FileWriteCallback write_callback, | |
173 Dart_FileCloseCallback close_callback); | |
174 | |
175 // Returns true if tracign is enabled for the VM. | |
176 static bool is_enabled() { return is_enabled_; } | |
177 | |
178 private: | |
179 ObjectSet* CreateEmptyObjectSet() const; | |
180 void ResizeObjectSet(); | |
181 | |
182 void TraceScopedHandle(uword handle); | |
183 | |
184 // A helper for PutRoots, called by HeapTraceVisitor. | |
185 void TraceSingleRoot(uword root); | |
186 | |
187 // Invoked while tracing an allocation. | |
188 void TraceRoots(Isolate* isolate); | |
189 | |
190 // Is the isolate we are tracing initialized? | |
191 bool isolate_initialized_; | |
192 | |
193 void* output_stream_; | |
194 | |
195 ObjectSet object_set_; | |
196 | |
197 static Dart_FileOpenCallback open_callback_; | |
198 static Dart_FileWriteCallback write_callback_; | |
199 static Dart_FileCloseCallback close_callback_; | |
200 | |
201 static bool is_enabled_; | |
202 | |
203 friend class HeapTraceVisitor; | |
204 friend class HeapTraceScopedHandleVisitor; | |
205 friend class HeapTraceObjectStoreVisitor; | |
206 friend class HeapTraceDebugObjectVisitor; | |
207 | |
208 DISALLOW_COPY_AND_ASSIGN(HeapTrace); | |
209 }; | |
210 | |
211 } // namespace dart | |
212 | |
213 #endif // VM_HEAP_TRACE_H_ | |
OLD | NEW |