OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_PROFILER_H_ | 5 #ifndef VM_PROFILER_H_ |
6 #define VM_PROFILER_H_ | 6 #define VM_PROFILER_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/bitfield.h" | 9 #include "vm/bitfield.h" |
10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 return isolate_; | 99 return isolate_; |
100 } | 100 } |
101 | 101 |
102 private: | 102 private: |
103 Isolate* isolate_; | 103 Isolate* isolate_; |
104 intptr_t visited_; | 104 intptr_t visited_; |
105 | 105 |
106 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); | 106 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); |
107 }; | 107 }; |
108 | 108 |
| 109 |
| 110 class PreprocessVisitor : public SampleVisitor { |
| 111 public: |
| 112 explicit PreprocessVisitor(Isolate* isolate); |
| 113 |
| 114 virtual void VisitSample(Sample* sample); |
| 115 |
| 116 private: |
| 117 void CheckForMissingDartFrame(const Code& code, Sample* sample) const; |
| 118 |
| 119 bool ContainedInDartCodeHeaps(uword pc) const; |
| 120 |
| 121 Isolate* vm_isolate() const { |
| 122 return vm_isolate_; |
| 123 } |
| 124 |
| 125 RawCode* FindCodeForPC(uword pc) const; |
| 126 |
| 127 Isolate* vm_isolate_; |
| 128 }; |
| 129 |
| 130 |
| 131 class ClearProfileVisitor : public SampleVisitor { |
| 132 public: |
| 133 explicit ClearProfileVisitor(Isolate* isolate); |
| 134 |
| 135 virtual void VisitSample(Sample* sample); |
| 136 }; |
| 137 |
| 138 |
109 // Each Sample holds a stack trace from an isolate. | 139 // Each Sample holds a stack trace from an isolate. |
110 class Sample { | 140 class Sample { |
111 public: | 141 public: |
112 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { | 142 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { |
| 143 Clear(); |
113 timestamp_ = timestamp; | 144 timestamp_ = timestamp; |
114 tid_ = tid; | 145 tid_ = tid; |
115 isolate_ = isolate; | 146 isolate_ = isolate; |
| 147 } |
| 148 |
| 149 // Isolate sample was taken from. |
| 150 Isolate* isolate() const { |
| 151 return isolate_; |
| 152 } |
| 153 |
| 154 void Clear() { |
| 155 isolate_ = NULL; |
116 pc_marker_ = 0; | 156 pc_marker_ = 0; |
| 157 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) { |
| 158 stack_buffer_[i] = 0; |
| 159 } |
117 vm_tag_ = VMTag::kInvalidTagId; | 160 vm_tag_ = VMTag::kInvalidTagId; |
118 user_tag_ = UserTags::kDefaultUserTag; | 161 user_tag_ = UserTags::kDefaultUserTag; |
119 sp_ = 0; | 162 sp_ = 0; |
| 163 lr_ = 0; |
120 fp_ = 0; | 164 fp_ = 0; |
121 state_ = 0; | 165 state_ = 0; |
122 uword* pcs = GetPCArray(); | 166 uword* pcs = GetPCArray(); |
123 for (intptr_t i = 0; i < pcs_length_; i++) { | 167 for (intptr_t i = 0; i < pcs_length_; i++) { |
124 pcs[i] = 0; | 168 pcs[i] = 0; |
125 } | 169 } |
126 } | 170 } |
127 | 171 |
128 // Isolate sample was taken from. | |
129 Isolate* isolate() const { | |
130 return isolate_; | |
131 } | |
132 | |
133 // Timestamp sample was taken at. | 172 // Timestamp sample was taken at. |
134 int64_t timestamp() const { | 173 int64_t timestamp() const { |
135 return timestamp_; | 174 return timestamp_; |
136 } | 175 } |
137 | 176 |
| 177 // Top most pc. |
| 178 uword pc() const { |
| 179 return At(0); |
| 180 } |
| 181 |
138 // Get stack trace entry. | 182 // Get stack trace entry. |
139 uword At(intptr_t i) const { | 183 uword At(intptr_t i) const { |
140 ASSERT(i >= 0); | 184 ASSERT(i >= 0); |
141 ASSERT(i < pcs_length_); | 185 ASSERT(i < pcs_length_); |
142 uword* pcs = GetPCArray(); | 186 uword* pcs = GetPCArray(); |
143 return pcs[i]; | 187 return pcs[i]; |
144 } | 188 } |
145 | 189 |
146 // Set stack trace entry. | 190 // Set stack trace entry. |
147 void SetAt(intptr_t i, uword pc) { | 191 void SetAt(intptr_t i, uword pc) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 227 } |
184 | 228 |
185 uword fp() const { | 229 uword fp() const { |
186 return fp_; | 230 return fp_; |
187 } | 231 } |
188 | 232 |
189 void set_fp(uword fp) { | 233 void set_fp(uword fp) { |
190 fp_ = fp; | 234 fp_ = fp; |
191 } | 235 } |
192 | 236 |
| 237 uword lr() const { |
| 238 return lr_; |
| 239 } |
| 240 |
| 241 void set_lr(uword link_register) { |
| 242 lr_ = link_register; |
| 243 } |
| 244 |
193 void InsertCallerForTopFrame(uword pc) { | 245 void InsertCallerForTopFrame(uword pc) { |
194 if (pcs_length_ == 1) { | 246 if (pcs_length_ == 1) { |
195 // Only sampling top frame. | 247 // Only sampling top frame. |
196 return; | 248 return; |
197 } | 249 } |
198 uword* pcs = GetPCArray(); | 250 uword* pcs = GetPCArray(); |
199 // The caller for the top frame is store at index 1. | 251 // The caller for the top frame is store at index 1. |
200 // Shift all entries down by one. | 252 // Shift all entries down by one. |
201 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) { | 253 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) { |
202 pcs[i] = pcs[i - 1]; | 254 pcs[i] = pcs[i - 1]; |
203 } | 255 } |
204 // Insert caller for top frame. | 256 // Insert caller for top frame. |
205 pcs[1] = pc; | 257 pcs[1] = pc; |
| 258 set_missing_frame_inserted(true); |
206 } | 259 } |
207 | 260 |
208 bool processed() const { | 261 bool processed() const { |
209 return ProcessedBit::decode(state_); | 262 return ProcessedBit::decode(state_); |
210 } | 263 } |
211 | 264 |
212 void set_processed(bool processed) { | 265 void set_processed(bool processed) { |
213 state_ = ProcessedBit::update(processed, state_); | 266 state_ = ProcessedBit::update(processed, state_); |
214 } | 267 } |
215 | 268 |
(...skipping 14 matching lines...) Expand all Loading... |
230 } | 283 } |
231 | 284 |
232 bool exit_frame_sample() const { | 285 bool exit_frame_sample() const { |
233 return ExitFrameBit::decode(state_); | 286 return ExitFrameBit::decode(state_); |
234 } | 287 } |
235 | 288 |
236 void set_exit_frame_sample(bool exit_frame_sample) { | 289 void set_exit_frame_sample(bool exit_frame_sample) { |
237 state_ = ExitFrameBit::update(exit_frame_sample, state_); | 290 state_ = ExitFrameBit::update(exit_frame_sample, state_); |
238 } | 291 } |
239 | 292 |
| 293 bool missing_frame_inserted() const { |
| 294 return MissingFrameInsertedBit::decode(state_); |
| 295 } |
| 296 |
| 297 void set_missing_frame_inserted(bool missing_frame_inserted) { |
| 298 state_ = MissingFrameInsertedBit::update(missing_frame_inserted, state_); |
| 299 } |
| 300 |
240 static void InitOnce(); | 301 static void InitOnce(); |
241 | 302 |
242 static intptr_t instance_size() { | 303 static intptr_t instance_size() { |
243 return instance_size_; | 304 return instance_size_; |
244 } | 305 } |
245 | 306 |
246 uword* GetPCArray() const; | 307 uword* GetPCArray() const; |
247 | 308 |
| 309 static const int kStackBufferSizeInWords = 2; |
| 310 uword* GetStackBuffer() { |
| 311 return &stack_buffer_[0]; |
| 312 } |
| 313 |
248 private: | 314 private: |
249 static intptr_t instance_size_; | 315 static intptr_t instance_size_; |
250 static intptr_t pcs_length_; | 316 static intptr_t pcs_length_; |
251 enum StateBits { | 317 enum StateBits { |
252 kProcessedBit = 0, | 318 kProcessedBit = 0, |
253 kLeafFrameIsDartBit = 1, | 319 kLeafFrameIsDartBit = 1, |
254 kIgnoreBit = 2, | 320 kIgnoreBit = 2, |
255 kExitFrameBit = 3, | 321 kExitFrameBit = 3, |
| 322 kMissingFrameInsertedBit = 4, |
256 }; | 323 }; |
257 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; | 324 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; |
258 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; | 325 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; |
259 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {}; | 326 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {}; |
260 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {}; | 327 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {}; |
261 | 328 class MissingFrameInsertedBit |
| 329 : public BitField<bool, kMissingFrameInsertedBit, 1> {}; |
262 int64_t timestamp_; | 330 int64_t timestamp_; |
263 ThreadId tid_; | 331 ThreadId tid_; |
264 Isolate* isolate_; | 332 Isolate* isolate_; |
265 uword pc_marker_; | 333 uword pc_marker_; |
| 334 uword stack_buffer_[kStackBufferSizeInWords]; |
266 uword vm_tag_; | 335 uword vm_tag_; |
267 uword user_tag_; | 336 uword user_tag_; |
268 uword sp_; | 337 uword sp_; |
269 uword fp_; | 338 uword fp_; |
| 339 uword lr_; |
270 uword state_; | 340 uword state_; |
271 | 341 |
272 /* There are a variable number of words that follow, the words hold the | 342 /* There are a variable number of words that follow, the words hold the |
273 * sampled pc values. Access via GetPCArray() */ | 343 * sampled pc values. Access via GetPCArray() */ |
274 | 344 |
275 DISALLOW_COPY_AND_ASSIGN(Sample); | 345 DISALLOW_COPY_AND_ASSIGN(Sample); |
276 }; | 346 }; |
277 | 347 |
278 | 348 |
279 // Ring buffer of Samples that is (usually) shared by many isolates. | 349 // Ring buffer of Samples that is (usually) shared by many isolates. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 intptr_t capacity_; | 398 intptr_t capacity_; |
329 uintptr_t cursor_; | 399 uintptr_t cursor_; |
330 | 400 |
331 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 401 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
332 }; | 402 }; |
333 | 403 |
334 | 404 |
335 } // namespace dart | 405 } // namespace dart |
336 | 406 |
337 #endif // VM_PROFILER_H_ | 407 #endif // VM_PROFILER_H_ |
OLD | NEW |