Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: runtime/vm/profiler.h

Issue 1270003002: Chain samples together to collect long stack traces in profiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 timestamp_ = timestamp; 148 timestamp_ = timestamp;
149 tid_ = tid; 149 tid_ = tid;
150 isolate_ = isolate; 150 isolate_ = isolate;
151 } 151 }
152 152
153 // Isolate sample was taken from. 153 // Isolate sample was taken from.
154 Isolate* isolate() const { 154 Isolate* isolate() const {
155 return isolate_; 155 return isolate_;
156 } 156 }
157 157
158 // Thread sample was taken on.
159 ThreadId tid() const {
160 return tid_;
161 }
162
158 void Clear() { 163 void Clear() {
159 isolate_ = NULL; 164 isolate_ = NULL;
160 pc_marker_ = 0; 165 pc_marker_ = 0;
161 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) { 166 for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) {
162 stack_buffer_[i] = 0; 167 stack_buffer_[i] = 0;
163 } 168 }
164 vm_tag_ = VMTag::kInvalidTagId; 169 vm_tag_ = VMTag::kInvalidTagId;
165 user_tag_ = UserTags::kDefaultUserTag; 170 user_tag_ = UserTags::kDefaultUserTag;
166 lr_ = 0; 171 lr_ = 0;
167 metadata_ = 0; 172 metadata_ = 0;
168 state_ = 0; 173 state_ = 0;
174 continuation_index_ = -1;
169 uword* pcs = GetPCArray(); 175 uword* pcs = GetPCArray();
170 for (intptr_t i = 0; i < pcs_length_; i++) { 176 for (intptr_t i = 0; i < pcs_length_; i++) {
171 pcs[i] = 0; 177 pcs[i] = 0;
172 } 178 }
179 set_head_sample(true);
173 } 180 }
174 181
175 // Timestamp sample was taken at. 182 // Timestamp sample was taken at.
176 int64_t timestamp() const { 183 int64_t timestamp() const {
177 return timestamp_; 184 return timestamp_;
178 } 185 }
179 186
180 // Top most pc. 187 // Top most pc.
181 uword pc() const { 188 uword pc() const {
182 return At(0); 189 return At(0);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 } 229 }
223 230
224 uword lr() const { 231 uword lr() const {
225 return lr_; 232 return lr_;
226 } 233 }
227 234
228 void set_lr(uword link_register) { 235 void set_lr(uword link_register) {
229 lr_ = link_register; 236 lr_ = link_register;
230 } 237 }
231 238
232 void InsertCallerForTopFrame(uword pc) {
233 if (pcs_length_ == 1) {
234 // Only sampling top frame.
235 return;
236 }
237 uword* pcs = GetPCArray();
238 // The caller for the top frame is store at index 1.
239 // Shift all entries down by one.
240 for (intptr_t i = pcs_length_ - 1; i >= 2; i--) {
241 pcs[i] = pcs[i - 1];
242 }
243 // Insert caller for top frame.
244 pcs[1] = pc;
245 set_missing_frame_inserted(true);
246 }
247
248 bool processed() const {
249 return ProcessedBit::decode(state_);
250 }
251
252 void set_processed(bool processed) {
253 state_ = ProcessedBit::update(processed, state_);
254 }
255
256 bool leaf_frame_is_dart() const { 239 bool leaf_frame_is_dart() const {
257 return LeafFrameIsDart::decode(state_); 240 return LeafFrameIsDart::decode(state_);
258 } 241 }
259 242
260 void set_leaf_frame_is_dart(bool leaf_frame_is_dart) { 243 void set_leaf_frame_is_dart(bool leaf_frame_is_dart) {
261 state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_); 244 state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_);
262 } 245 }
263 246
264 bool ignore_sample() const { 247 bool ignore_sample() const {
265 return IgnoreBit::decode(state_); 248 return IgnoreBit::decode(state_);
(...skipping 28 matching lines...) Expand all
294 } 277 }
295 278
296 bool is_allocation_sample() const { 279 bool is_allocation_sample() const {
297 return ClassAllocationSampleBit::decode(state_); 280 return ClassAllocationSampleBit::decode(state_);
298 } 281 }
299 282
300 void set_is_allocation_sample(bool allocation_sample) { 283 void set_is_allocation_sample(bool allocation_sample) {
301 state_ = ClassAllocationSampleBit::update(allocation_sample, state_); 284 state_ = ClassAllocationSampleBit::update(allocation_sample, state_);
302 } 285 }
303 286
287 bool is_continuation_sample() const {
288 return ContinuationSampleBit::decode(state_);
289 }
290
291 void SetContinuationIndex(intptr_t index) {
292 ASSERT(!is_continuation_sample());
293 ASSERT(continuation_index_ == -1);
294 state_ = ContinuationSampleBit::update(true, state_);
295 continuation_index_ = index;
296 ASSERT(is_continuation_sample());
297 }
298
299 intptr_t continuation_index() const {
300 ASSERT(is_continuation_sample());
301 return continuation_index_;
302 }
303
304 intptr_t allocation_cid() const { 304 intptr_t allocation_cid() const {
305 ASSERT(is_allocation_sample()); 305 ASSERT(is_allocation_sample());
306 return metadata_; 306 return metadata_;
307 } 307 }
308 308
309 void set_head_sample(bool head_sample) {
310 state_ = HeadSampleBit::update(head_sample, state_);
311 }
312
313 bool head_sample() const {
314 return HeadSampleBit::decode(state_);
315 }
316
309 void set_metadata(intptr_t metadata) { 317 void set_metadata(intptr_t metadata) {
310 metadata_ = metadata; 318 metadata_ = metadata;
311 } 319 }
312 320
313 void SetAllocationCid(intptr_t cid) { 321 void SetAllocationCid(intptr_t cid) {
314 set_is_allocation_sample(true); 322 set_is_allocation_sample(true);
315 set_metadata(cid); 323 set_metadata(cid);
316 } 324 }
317 325
318 static void InitOnce(); 326 static void InitOnce();
319 327
320 static intptr_t instance_size() { 328 static intptr_t instance_size() {
321 return instance_size_; 329 return instance_size_;
322 } 330 }
323 331
324 uword* GetPCArray() const; 332 uword* GetPCArray() const;
325 333
326 static const int kStackBufferSizeInWords = 2; 334 static const int kStackBufferSizeInWords = 2;
327 uword* GetStackBuffer() { 335 uword* GetStackBuffer() {
328 return &stack_buffer_[0]; 336 return &stack_buffer_[0];
329 } 337 }
330 338
331 private: 339 private:
332 static intptr_t instance_size_; 340 static intptr_t instance_size_;
333 static intptr_t pcs_length_; 341 static intptr_t pcs_length_;
334 enum StateBits { 342 enum StateBits {
335 kProcessedBit = 0, 343 kHeadSampleBit = 0,
336 kLeafFrameIsDartBit = 1, 344 kLeafFrameIsDartBit = 1,
337 kIgnoreBit = 2, 345 kIgnoreBit = 2,
338 kExitFrameBit = 3, 346 kExitFrameBit = 3,
339 kMissingFrameInsertedBit = 4, 347 kMissingFrameInsertedBit = 4,
340 kTruncatedTrace = 5, 348 kTruncatedTraceBit = 5,
341 kClassAllocationSample = 6, 349 kClassAllocationSampleBit = 6,
350 kContinuationSampleBit = 7,
342 }; 351 };
343 class ProcessedBit : public BitField<bool, kProcessedBit, 1> {}; 352 class HeadSampleBit : public BitField<bool, kHeadSampleBit, 1> {};
344 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {}; 353 class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {};
345 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {}; 354 class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {};
346 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {}; 355 class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {};
347 class MissingFrameInsertedBit 356 class MissingFrameInsertedBit
348 : public BitField<bool, kMissingFrameInsertedBit, 1> {}; 357 : public BitField<bool, kMissingFrameInsertedBit, 1> {};
349 class TruncatedTraceBit : public BitField<bool, kTruncatedTrace, 1> {}; 358 class TruncatedTraceBit : public BitField<bool, kTruncatedTraceBit, 1> {};
350 class ClassAllocationSampleBit 359 class ClassAllocationSampleBit
351 : public BitField<bool, kClassAllocationSample, 1> {}; 360 : public BitField<bool, kClassAllocationSampleBit, 1> {};
361 class ContinuationSampleBit
362 : public BitField<bool, kContinuationSampleBit, 1> {};
352 363
353 int64_t timestamp_; 364 int64_t timestamp_;
354 ThreadId tid_; 365 ThreadId tid_;
355 Isolate* isolate_; 366 Isolate* isolate_;
356 uword pc_marker_; 367 uword pc_marker_;
357 uword stack_buffer_[kStackBufferSizeInWords]; 368 uword stack_buffer_[kStackBufferSizeInWords];
358 uword vm_tag_; 369 uword vm_tag_;
359 uword user_tag_; 370 uword user_tag_;
360 uword metadata_; 371 uword metadata_;
361 uword lr_; 372 uword lr_;
362 uword state_; 373 uword state_;
374 intptr_t continuation_index_;
363 375
364 /* There are a variable number of words that follow, the words hold the 376 /* There are a variable number of words that follow, the words hold the
365 * sampled pc values. Access via GetPCArray() */ 377 * sampled pc values. Access via GetPCArray() */
366 378
367 DISALLOW_COPY_AND_ASSIGN(Sample); 379 DISALLOW_COPY_AND_ASSIGN(Sample);
368 }; 380 };
369 381
370 382
371 // Ring buffer of Samples that is (usually) shared by many isolates. 383 // Ring buffer of Samples that is (usually) shared by many isolates.
372 class SampleBuffer { 384 class SampleBuffer {
373 public: 385 public:
374 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. 386 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz.
375 387
376 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); 388 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity);
377 389
378 ~SampleBuffer() { 390 ~SampleBuffer() {
379 if (samples_ != NULL) { 391 if (samples_ != NULL) {
380 free(samples_); 392 free(samples_);
381 samples_ = NULL; 393 samples_ = NULL;
382 cursor_ = 0; 394 cursor_ = 0;
383 capacity_ = 0; 395 capacity_ = 0;
384 } 396 }
385 } 397 }
386 398
387 intptr_t capacity() const { return capacity_; } 399 intptr_t capacity() const { return capacity_; }
388 400
389 Sample* At(intptr_t idx) const; 401 Sample* At(intptr_t idx) const;
402 intptr_t ReserveSampleSlot();
390 Sample* ReserveSample(); 403 Sample* ReserveSample();
404 Sample* ReserveSampleAndLink(Sample* previous);
391 405
392 void VisitSamples(SampleVisitor* visitor) { 406 void VisitSamples(SampleVisitor* visitor) {
393 ASSERT(visitor != NULL); 407 ASSERT(visitor != NULL);
394 const intptr_t length = capacity(); 408 const intptr_t length = capacity();
395 for (intptr_t i = 0; i < length; i++) { 409 for (intptr_t i = 0; i < length; i++) {
396 Sample* sample = At(i); 410 Sample* sample = At(i);
411 if (!sample->head_sample()) {
412 // An inner sample in a chain of samples.
413 continue;
414 }
397 if (sample->ignore_sample()) { 415 if (sample->ignore_sample()) {
398 // Bad sample. 416 // Bad sample.
399 continue; 417 continue;
400 } 418 }
401 if (sample->isolate() != visitor->isolate()) { 419 if (sample->isolate() != visitor->isolate()) {
402 // Another isolate. 420 // Another isolate.
403 continue; 421 continue;
404 } 422 }
405 if (sample->timestamp() == 0) { 423 if (sample->timestamp() == 0) {
406 // Empty. 424 // Empty.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 556
539 private: 557 private:
540 ZoneGrowableArray<ProcessedSample*> samples_; 558 ZoneGrowableArray<ProcessedSample*> samples_;
541 559
542 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); 560 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
543 }; 561 };
544 562
545 } // namespace dart 563 } // namespace dart
546 564
547 #endif // VM_PROFILER_H_ 565 #endif // VM_PROFILER_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698