Chromium Code Reviews| 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/code_observers.h" | 9 #include "vm/code_observers.h" |
| 10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 return isolate_; | 111 return isolate_; |
| 112 } | 112 } |
| 113 | 113 |
| 114 private: | 114 private: |
| 115 Isolate* isolate_; | 115 Isolate* isolate_; |
| 116 intptr_t visited_; | 116 intptr_t visited_; |
| 117 | 117 |
| 118 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); | 118 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); |
| 119 }; | 119 }; |
| 120 | 120 |
| 121 // The maximum number of stack frames a sample can hold. | |
| 122 #define kSampleFramesSize 256 | |
| 123 | |
| 124 // Each Sample holds a stack trace from an isolate. | 121 // Each Sample holds a stack trace from an isolate. |
| 125 class Sample { | 122 class Sample { |
| 126 public: | 123 public: |
| 127 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { | 124 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { |
| 128 timestamp_ = timestamp; | 125 timestamp_ = timestamp; |
| 129 tid_ = tid; | 126 tid_ = tid; |
| 130 isolate_ = isolate; | 127 isolate_ = isolate; |
| 131 pc_marker_ = 0; | 128 pc_marker_ = 0; |
| 132 vm_tag_ = VMTag::kInvalidTagId; | 129 vm_tag_ = VMTag::kInvalidTagId; |
| 133 user_tag_ = UserTags::kDefaultUserTag; | 130 user_tag_ = UserTags::kDefaultUserTag; |
| 134 sp_ = 0; | 131 sp_ = 0; |
| 135 fp_ = 0; | 132 fp_ = 0; |
| 136 state_ = 0; | 133 state_ = 0; |
| 137 for (intptr_t i = 0; i < kSampleFramesSize; i++) { | 134 uword* pcs = GetPCArray(); |
| 138 pcs_[i] = 0; | 135 for (intptr_t i = 0; i < pcs_length_; i++) { |
| 136 pcs[i] = 0; | |
| 139 } | 137 } |
| 140 } | 138 } |
| 141 | 139 |
| 142 // Isolate sample was taken from. | 140 // Isolate sample was taken from. |
| 143 Isolate* isolate() const { | 141 Isolate* isolate() const { |
| 144 return isolate_; | 142 return isolate_; |
| 145 } | 143 } |
| 146 | 144 |
| 147 // Timestamp sample was taken at. | 145 // Timestamp sample was taken at. |
| 148 int64_t timestamp() const { | 146 int64_t timestamp() const { |
| 149 return timestamp_; | 147 return timestamp_; |
| 150 } | 148 } |
| 151 | 149 |
| 152 // Get stack trace entry. | 150 uword At(intptr_t i) const; |
|
Ivan Posva
2014/06/20 00:06:49
Why have these been moved to the cc file?
Cutch
2014/06/20 14:39:12
Moved back to header.
| |
| 153 uword At(intptr_t i) const { | |
| 154 ASSERT(i >= 0); | |
| 155 ASSERT(i < kSampleFramesSize); | |
| 156 return pcs_[i]; | |
| 157 } | |
| 158 | 151 |
| 159 // Set stack trace entry. | 152 void SetAt(intptr_t i, uword pc); |
| 160 void SetAt(intptr_t i, uword pc) { | |
| 161 ASSERT(i >= 0); | |
| 162 ASSERT(i < kSampleFramesSize); | |
| 163 pcs_[i] = pc; | |
| 164 } | |
| 165 | 153 |
| 166 uword vm_tag() const { | 154 uword vm_tag() const { |
| 167 return vm_tag_; | 155 return vm_tag_; |
| 168 } | 156 } |
| 169 void set_vm_tag(uword tag) { | 157 void set_vm_tag(uword tag) { |
| 170 ASSERT(tag != VMTag::kInvalidTagId); | 158 ASSERT(tag != VMTag::kInvalidTagId); |
| 171 vm_tag_ = tag; | 159 vm_tag_ = tag; |
| 172 } | 160 } |
| 173 | 161 |
| 174 uword user_tag() const { | 162 uword user_tag() const { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 196 | 184 |
| 197 uword fp() const { | 185 uword fp() const { |
| 198 return fp_; | 186 return fp_; |
| 199 } | 187 } |
| 200 | 188 |
| 201 void set_fp(uword fp) { | 189 void set_fp(uword fp) { |
| 202 fp_ = fp; | 190 fp_ = fp; |
| 203 } | 191 } |
| 204 | 192 |
| 205 void InsertCallerForTopFrame(uword pc) { | 193 void InsertCallerForTopFrame(uword pc) { |
| 194 if (pcs_length_ <= 1) { | |
|
Ivan Posva
2014/06/20 00:06:49
pcs_length less than zero should be illegal in all
Cutch
2014/06/20 14:39:12
Done.
| |
| 195 // Only sampling top frame. | |
| 196 return; | |
| 197 } | |
| 198 uword* pcs = GetPCArray(); | |
| 206 // The caller for the top frame is store at index 1. | 199 // The caller for the top frame is store at index 1. |
| 207 // Shift all entries down by one. | 200 // Shift all entries down by one. |
| 208 for (intptr_t i = kSampleFramesSize - 1; i >= 2; i--) { | 201 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) { |
| 209 pcs_[i] = pcs_[i - 1]; | 202 pcs[i] = pcs[i - 1]; |
| 210 } | 203 } |
| 211 // Insert caller for top frame. | 204 // Insert caller for top frame. |
| 212 pcs_[1] = pc; | 205 pcs[1] = pc; |
| 213 } | 206 } |
| 214 | 207 |
| 215 bool processed() const { | 208 bool processed() const { |
| 216 return ProcessedBit::decode(state_); | 209 return ProcessedBit::decode(state_); |
| 217 } | 210 } |
| 218 | 211 |
| 219 void set_processed(bool processed) { | 212 void set_processed(bool processed) { |
| 220 state_ = ProcessedBit::update(processed, state_); | 213 state_ = ProcessedBit::update(processed, state_); |
| 221 } | 214 } |
| 222 | 215 |
| 223 bool leaf_frame_is_dart() const { | 216 bool leaf_frame_is_dart() const { |
| 224 return LeafFrameIsDart::decode(state_); | 217 return LeafFrameIsDart::decode(state_); |
| 225 } | 218 } |
| 226 | 219 |
| 227 void set_leaf_frame_is_dart(bool leaf_frame_is_dart) { | 220 void set_leaf_frame_is_dart(bool leaf_frame_is_dart) { |
| 228 state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_); | 221 state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_); |
| 229 } | 222 } |
| 230 | 223 |
| 224 static void InitOnce(); | |
| 225 | |
| 226 static intptr_t instance_size() { | |
| 227 return instance_size_; | |
| 228 } | |
| 229 | |
| 230 uword* GetPCArray() const; | |
| 231 | |
| 231 private: | 232 private: |
| 233 static intptr_t instance_size_; | |
| 234 static intptr_t pcs_length_; | |
| 232 enum StateBits { | 235 enum StateBits { |
| 233 kProcessedBit = 0, | 236 kProcessedBit = 0, |
| 234 kLeafFrameIsDartBit = 1, | 237 kLeafFrameIsDartBit = 1, |
| 235 }; | 238 }; |
| 236 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; | 239 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; |
| 237 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; | 240 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; |
| 238 | 241 |
| 239 int64_t timestamp_; | 242 int64_t timestamp_; |
| 240 ThreadId tid_; | 243 ThreadId tid_; |
| 241 Isolate* isolate_; | 244 Isolate* isolate_; |
| 242 uword pc_marker_; | 245 uword pc_marker_; |
| 243 uword vm_tag_; | 246 uword vm_tag_; |
| 244 uword user_tag_; | 247 uword user_tag_; |
| 245 uword sp_; | 248 uword sp_; |
| 246 uword fp_; | 249 uword fp_; |
| 247 uword state_; | 250 uword state_; |
| 248 uword pcs_[kSampleFramesSize]; | 251 |
| 252 /* There are a variable number of words that follow, the words hold the | |
| 253 * sampled pc values. Access via GetPCArray() */ | |
| 254 | |
| 255 DISALLOW_COPY_AND_ASSIGN(Sample); | |
| 249 }; | 256 }; |
| 250 | 257 |
| 251 | 258 |
| 252 // Ring buffer of Samples that is (usually) shared by many isolates. | 259 // Ring buffer of Samples that is (usually) shared by many isolates. |
| 253 class SampleBuffer { | 260 class SampleBuffer { |
| 254 public: | 261 public: |
| 255 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. | 262 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. |
| 256 | 263 |
| 257 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity) { | 264 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); |
| 258 samples_ = reinterpret_cast<Sample*>(calloc(capacity, sizeof(*samples_))); | |
| 259 capacity_ = capacity; | |
| 260 cursor_ = 0; | |
| 261 } | |
| 262 | 265 |
| 263 ~SampleBuffer() { | 266 ~SampleBuffer() { |
| 264 if (samples_ != NULL) { | 267 if (samples_ != NULL) { |
| 265 free(samples_); | 268 free(samples_); |
| 266 samples_ = NULL; | 269 samples_ = NULL; |
| 267 cursor_ = 0; | 270 cursor_ = 0; |
| 268 capacity_ = 0; | 271 capacity_ = 0; |
| 269 } | 272 } |
| 270 } | 273 } |
| 271 | 274 |
| 272 intptr_t capacity() const { return capacity_; } | 275 intptr_t capacity() const { return capacity_; } |
| 273 | 276 |
| 277 Sample* At(intptr_t idx) const; | |
| 274 Sample* ReserveSample(); | 278 Sample* ReserveSample(); |
| 275 | 279 |
| 276 Sample* At(intptr_t idx) const { | |
| 277 ASSERT(idx >= 0); | |
| 278 ASSERT(idx < capacity_); | |
| 279 return &samples_[idx]; | |
| 280 } | |
| 281 | |
| 282 void VisitSamples(SampleVisitor* visitor) { | 280 void VisitSamples(SampleVisitor* visitor) { |
| 283 ASSERT(visitor != NULL); | 281 ASSERT(visitor != NULL); |
| 284 const intptr_t length = capacity(); | 282 const intptr_t length = capacity(); |
| 285 for (intptr_t i = 0; i < length; i++) { | 283 for (intptr_t i = 0; i < length; i++) { |
| 286 Sample* sample = At(i); | 284 Sample* sample = At(i); |
| 287 if (sample->isolate() != visitor->isolate()) { | 285 if (sample->isolate() != visitor->isolate()) { |
| 288 // Another isolate. | 286 // Another isolate. |
| 289 continue; | 287 continue; |
| 290 } | 288 } |
| 291 if (sample->timestamp() == 0) { | 289 if (sample->timestamp() == 0) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 306 intptr_t capacity_; | 304 intptr_t capacity_; |
| 307 uintptr_t cursor_; | 305 uintptr_t cursor_; |
| 308 | 306 |
| 309 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 307 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
| 310 }; | 308 }; |
| 311 | 309 |
| 312 | 310 |
| 313 } // namespace dart | 311 } // namespace dart |
| 314 | 312 |
| 315 #endif // VM_PROFILER_H_ | 313 #endif // VM_PROFILER_H_ |
| OLD | NEW |