| 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 FixTopFrameVisitor : public SampleVisitor { |
| 111 public: |
| 112 explicit FixTopFrameVisitor(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 |
| 109 // Each Sample holds a stack trace from an isolate. | 131 // Each Sample holds a stack trace from an isolate. |
| 110 class Sample { | 132 class Sample { |
| 111 public: | 133 public: |
| 112 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { | 134 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { |
| 113 timestamp_ = timestamp; | 135 timestamp_ = timestamp; |
| 114 tid_ = tid; | 136 tid_ = tid; |
| 115 isolate_ = isolate; | 137 isolate_ = isolate; |
| 116 pc_marker_ = 0; | 138 pc_marker_ = 0; |
| 117 vm_tag_ = VMTag::kInvalidTagId; | 139 vm_tag_ = VMTag::kInvalidTagId; |
| 118 user_tag_ = UserTags::kDefaultUserTag; | 140 user_tag_ = UserTags::kDefaultUserTag; |
| 119 sp_ = 0; | 141 sp_ = 0; |
| 142 possible_return_address_ = 0; |
| 120 fp_ = 0; | 143 fp_ = 0; |
| 121 state_ = 0; | 144 state_ = 0; |
| 122 uword* pcs = GetPCArray(); | 145 uword* pcs = GetPCArray(); |
| 123 for (intptr_t i = 0; i < pcs_length_; i++) { | 146 for (intptr_t i = 0; i < pcs_length_; i++) { |
| 124 pcs[i] = 0; | 147 pcs[i] = 0; |
| 125 } | 148 } |
| 126 } | 149 } |
| 127 | 150 |
| 128 // Isolate sample was taken from. | 151 // Isolate sample was taken from. |
| 129 Isolate* isolate() const { | 152 Isolate* isolate() const { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 } | 206 } |
| 184 | 207 |
| 185 uword fp() const { | 208 uword fp() const { |
| 186 return fp_; | 209 return fp_; |
| 187 } | 210 } |
| 188 | 211 |
| 189 void set_fp(uword fp) { | 212 void set_fp(uword fp) { |
| 190 fp_ = fp; | 213 fp_ = fp; |
| 191 } | 214 } |
| 192 | 215 |
| 216 uword possible_return_address() const { |
| 217 return possible_return_address_; |
| 218 } |
| 219 |
| 220 void set_possible_return_address(uword possible_return_address) { |
| 221 possible_return_address_ = possible_return_address; |
| 222 } |
| 223 |
| 193 void InsertCallerForTopFrame(uword pc) { | 224 void InsertCallerForTopFrame(uword pc) { |
| 194 if (pcs_length_ == 1) { | 225 if (pcs_length_ == 1) { |
| 195 // Only sampling top frame. | 226 // Only sampling top frame. |
| 196 return; | 227 return; |
| 197 } | 228 } |
| 198 uword* pcs = GetPCArray(); | 229 uword* pcs = GetPCArray(); |
| 199 // The caller for the top frame is store at index 1. | 230 // The caller for the top frame is store at index 1. |
| 200 // Shift all entries down by one. | 231 // Shift all entries down by one. |
| 201 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) { | 232 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) { |
| 202 pcs[i] = pcs[i - 1]; | 233 pcs[i] = pcs[i - 1]; |
| 203 } | 234 } |
| 204 // Insert caller for top frame. | 235 // Insert caller for top frame. |
| 205 pcs[1] = pc; | 236 pcs[1] = pc; |
| 237 set_missing_frame_inserted(true); |
| 206 } | 238 } |
| 207 | 239 |
| 208 bool processed() const { | 240 bool processed() const { |
| 209 return ProcessedBit::decode(state_); | 241 return ProcessedBit::decode(state_); |
| 210 } | 242 } |
| 211 | 243 |
| 212 void set_processed(bool processed) { | 244 void set_processed(bool processed) { |
| 213 state_ = ProcessedBit::update(processed, state_); | 245 state_ = ProcessedBit::update(processed, state_); |
| 214 } | 246 } |
| 215 | 247 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 230 } | 262 } |
| 231 | 263 |
| 232 bool exit_frame_sample() const { | 264 bool exit_frame_sample() const { |
| 233 return ExitFrameBit::decode(state_); | 265 return ExitFrameBit::decode(state_); |
| 234 } | 266 } |
| 235 | 267 |
| 236 void set_exit_frame_sample(bool exit_frame_sample) { | 268 void set_exit_frame_sample(bool exit_frame_sample) { |
| 237 state_ = ExitFrameBit::update(exit_frame_sample, state_); | 269 state_ = ExitFrameBit::update(exit_frame_sample, state_); |
| 238 } | 270 } |
| 239 | 271 |
| 272 bool missing_frame_inserted() const { |
| 273 return MissingFrameInsertedBit::decode(state_); |
| 274 } |
| 275 |
| 276 void set_missing_frame_inserted(bool missing_frame_inserted) { |
| 277 state_ = MissingFrameInsertedBit::update(missing_frame_inserted, state_); |
| 278 } |
| 279 |
| 240 static void InitOnce(); | 280 static void InitOnce(); |
| 241 | 281 |
| 242 static intptr_t instance_size() { | 282 static intptr_t instance_size() { |
| 243 return instance_size_; | 283 return instance_size_; |
| 244 } | 284 } |
| 245 | 285 |
| 246 uword* GetPCArray() const; | 286 uword* GetPCArray() const; |
| 247 | 287 |
| 288 static const int kStackBufferSizeInWords = 3; |
| 289 uword* GetStackBuffer() { |
| 290 return &stack_buffer_[0]; |
| 291 } |
| 292 |
| 248 private: | 293 private: |
| 249 static intptr_t instance_size_; | 294 static intptr_t instance_size_; |
| 250 static intptr_t pcs_length_; | 295 static intptr_t pcs_length_; |
| 251 enum StateBits { | 296 enum StateBits { |
| 252 kProcessedBit = 0, | 297 kProcessedBit = 0, |
| 253 kLeafFrameIsDartBit = 1, | 298 kLeafFrameIsDartBit = 1, |
| 254 kIgnoreBit = 2, | 299 kIgnoreBit = 2, |
| 255 kExitFrameBit = 3, | 300 kExitFrameBit = 3, |
| 301 kMissingFrameInsertedBit = 4, |
| 256 }; | 302 }; |
| 257 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; | 303 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; |
| 258 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; | 304 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; |
| 259 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {}; | 305 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {}; |
| 260 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {}; | 306 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {}; |
| 261 | 307 class MissingFrameInsertedBit |
| 308 : public BitField<bool, kMissingFrameInsertedBit, 1> {}; |
| 262 int64_t timestamp_; | 309 int64_t timestamp_; |
| 263 ThreadId tid_; | 310 ThreadId tid_; |
| 264 Isolate* isolate_; | 311 Isolate* isolate_; |
| 265 uword pc_marker_; | 312 uword pc_marker_; |
| 313 uword stack_buffer_[kStackBufferSizeInWords]; |
| 314 uword possible_return_address_; |
| 266 uword vm_tag_; | 315 uword vm_tag_; |
| 267 uword user_tag_; | 316 uword user_tag_; |
| 268 uword sp_; | 317 uword sp_; |
| 269 uword fp_; | 318 uword fp_; |
| 270 uword state_; | 319 uword state_; |
| 271 | 320 |
| 272 /* There are a variable number of words that follow, the words hold the | 321 /* There are a variable number of words that follow, the words hold the |
| 273 * sampled pc values. Access via GetPCArray() */ | 322 * sampled pc values. Access via GetPCArray() */ |
| 274 | 323 |
| 275 DISALLOW_COPY_AND_ASSIGN(Sample); | 324 DISALLOW_COPY_AND_ASSIGN(Sample); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 intptr_t capacity_; | 377 intptr_t capacity_; |
| 329 uintptr_t cursor_; | 378 uintptr_t cursor_; |
| 330 | 379 |
| 331 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 380 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
| 332 }; | 381 }; |
| 333 | 382 |
| 334 | 383 |
| 335 } // namespace dart | 384 } // namespace dart |
| 336 | 385 |
| 337 #endif // VM_PROFILER_H_ | 386 #endif // VM_PROFILER_H_ |
| OLD | NEW |