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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 } | 76 } |
77 | 77 |
78 private: | 78 private: |
79 SampleBuffer* sample_buffer_; | 79 SampleBuffer* sample_buffer_; |
80 bool own_sample_buffer_; | 80 bool own_sample_buffer_; |
81 | 81 |
82 DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData); | 82 DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData); |
83 }; | 83 }; |
84 | 84 |
85 | 85 |
86 class SampleVisitor { | 86 class SampleVisitor : public ValueObject { |
87 public: | 87 public: |
88 explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) { } | 88 explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) { } |
89 virtual ~SampleVisitor() {} | 89 virtual ~SampleVisitor() {} |
90 | 90 |
91 virtual void VisitSample(Sample* sample) = 0; | 91 virtual void VisitSample(Sample* sample) = 0; |
92 | 92 |
93 intptr_t visited() const { | 93 intptr_t visited() const { |
94 return visited_; | 94 return visited_; |
95 } | 95 } |
96 | 96 |
(...skipping 15 matching lines...) Expand all Loading... |
112 // The maximum number of stack frames a sample can hold. | 112 // The maximum number of stack frames a sample can hold. |
113 #define kSampleFramesSize 256 | 113 #define kSampleFramesSize 256 |
114 | 114 |
115 // Each Sample holds a stack trace from an isolate. | 115 // Each Sample holds a stack trace from an isolate. |
116 class Sample { | 116 class Sample { |
117 public: | 117 public: |
118 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { | 118 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { |
119 timestamp_ = timestamp; | 119 timestamp_ = timestamp; |
120 tid_ = tid; | 120 tid_ = tid; |
121 isolate_ = isolate; | 121 isolate_ = isolate; |
| 122 pc_marker_ = 0; |
122 vm_tag_ = VMTag::kInvalidTagId; | 123 vm_tag_ = VMTag::kInvalidTagId; |
123 user_tag_ = UserTags::kNoUserTag; | 124 user_tag_ = UserTags::kNoUserTag; |
| 125 sp_ = 0; |
| 126 fp_ = 0; |
| 127 state_ = 0; |
124 for (intptr_t i = 0; i < kSampleFramesSize; i++) { | 128 for (intptr_t i = 0; i < kSampleFramesSize; i++) { |
125 pcs_[i] = 0; | 129 pcs_[i] = 0; |
126 } | 130 } |
127 } | 131 } |
128 | 132 |
129 // Isolate sample was taken from. | 133 // Isolate sample was taken from. |
130 Isolate* isolate() const { | 134 Isolate* isolate() const { |
131 return isolate_; | 135 return isolate_; |
132 } | 136 } |
133 | 137 |
(...skipping 24 matching lines...) Expand all Loading... |
158 vm_tag_ = tag; | 162 vm_tag_ = tag; |
159 } | 163 } |
160 | 164 |
161 uword user_tag() const { | 165 uword user_tag() const { |
162 return user_tag_; | 166 return user_tag_; |
163 } | 167 } |
164 void set_user_tag(uword tag) { | 168 void set_user_tag(uword tag) { |
165 user_tag_ = tag; | 169 user_tag_ = tag; |
166 } | 170 } |
167 | 171 |
| 172 uword pc_marker() const { |
| 173 return pc_marker_; |
| 174 } |
| 175 |
| 176 void set_pc_marker(uword pc_marker) { |
| 177 pc_marker_ = pc_marker; |
| 178 } |
| 179 |
| 180 uword sp() const { |
| 181 return sp_; |
| 182 } |
| 183 |
| 184 void set_sp(uword sp) { |
| 185 sp_ = sp; |
| 186 } |
| 187 |
| 188 uword fp() const { |
| 189 return fp_; |
| 190 } |
| 191 |
| 192 void set_fp(uword fp) { |
| 193 fp_ = fp; |
| 194 } |
| 195 |
| 196 void InsertCallerForTopFrame(uword pc) { |
| 197 // The caller for the top frame is store at index 1. |
| 198 // Shift all entries down by one. |
| 199 for (intptr_t i = kSampleFramesSize - 1; i >= 2; i--) { |
| 200 pcs_[i] = pcs_[i - 1]; |
| 201 } |
| 202 // Insert caller for top frame. |
| 203 pcs_[1] = pc; |
| 204 } |
| 205 |
| 206 bool processed() const { |
| 207 return ProcessedBit::decode(state_); |
| 208 } |
| 209 |
| 210 void set_processed(bool processed) { |
| 211 state_ = ProcessedBit::update(processed, state_); |
| 212 } |
| 213 |
| 214 bool leaf_frame_is_dart() const { |
| 215 return LeafFrameIsDart::decode(state_); |
| 216 } |
| 217 |
| 218 void set_leaf_frame_is_dart(bool leaf_frame_is_dart) { |
| 219 state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_); |
| 220 } |
| 221 |
168 private: | 222 private: |
| 223 enum StateBits { |
| 224 kProcessedBit = 0, |
| 225 kLeafFrameIsDartBit = 1, |
| 226 }; |
| 227 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; |
| 228 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; |
| 229 |
169 int64_t timestamp_; | 230 int64_t timestamp_; |
170 ThreadId tid_; | 231 ThreadId tid_; |
171 Isolate* isolate_; | 232 Isolate* isolate_; |
| 233 uword pc_marker_; |
172 uword vm_tag_; | 234 uword vm_tag_; |
173 uword user_tag_; | 235 uword user_tag_; |
| 236 uword sp_; |
| 237 uword fp_; |
| 238 uword state_; |
174 uword pcs_[kSampleFramesSize]; | 239 uword pcs_[kSampleFramesSize]; |
175 }; | 240 }; |
176 | 241 |
177 | 242 |
178 // Ring buffer of Samples that is (usually) shared by many isolates. | 243 // Ring buffer of Samples that is (usually) shared by many isolates. |
179 class SampleBuffer { | 244 class SampleBuffer { |
180 public: | 245 public: |
181 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. | 246 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. |
182 | 247 |
183 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity) { | 248 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity) { |
(...skipping 16 matching lines...) Expand all Loading... |
200 Sample* ReserveSample(); | 265 Sample* ReserveSample(); |
201 | 266 |
202 Sample* At(intptr_t idx) const { | 267 Sample* At(intptr_t idx) const { |
203 ASSERT(idx >= 0); | 268 ASSERT(idx >= 0); |
204 ASSERT(idx < capacity_); | 269 ASSERT(idx < capacity_); |
205 return &samples_[idx]; | 270 return &samples_[idx]; |
206 } | 271 } |
207 | 272 |
208 void VisitSamples(SampleVisitor* visitor) { | 273 void VisitSamples(SampleVisitor* visitor) { |
209 ASSERT(visitor != NULL); | 274 ASSERT(visitor != NULL); |
210 Sample sample; | |
211 const intptr_t length = capacity(); | 275 const intptr_t length = capacity(); |
212 for (intptr_t i = 0; i < length; i++) { | 276 for (intptr_t i = 0; i < length; i++) { |
213 // Copy the sample. | 277 Sample* sample = At(i); |
214 sample = *At(i); | 278 if (sample->isolate() != visitor->isolate()) { |
215 if (sample.isolate() != visitor->isolate()) { | |
216 // Another isolate. | 279 // Another isolate. |
217 continue; | 280 continue; |
218 } | 281 } |
219 if (sample.timestamp() == 0) { | 282 if (sample->timestamp() == 0) { |
220 // Empty. | 283 // Empty. |
221 continue; | 284 continue; |
222 } | 285 } |
223 if (sample.At(0) == 0) { | 286 if (sample->At(0) == 0) { |
224 // No frames. | 287 // No frames. |
225 continue; | 288 continue; |
226 } | 289 } |
227 visitor->IncrementVisited(); | 290 visitor->IncrementVisited(); |
228 visitor->VisitSample(&sample); | 291 visitor->VisitSample(sample); |
229 } | 292 } |
230 } | 293 } |
231 | 294 |
232 private: | 295 private: |
233 Sample* samples_; | 296 Sample* samples_; |
234 intptr_t capacity_; | 297 intptr_t capacity_; |
235 uintptr_t cursor_; | 298 uintptr_t cursor_; |
236 | 299 |
237 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 300 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
238 }; | 301 }; |
239 | 302 |
240 | 303 |
241 } // namespace dart | 304 } // namespace dart |
242 | 305 |
243 #endif // VM_PROFILER_H_ | 306 #endif // VM_PROFILER_H_ |
OLD | NEW |