| 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 |