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/bitfield.h" | 9 #include "vm/bitfield.h" |
| 10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
| 11 #include "vm/globals.h" | 11 #include "vm/globals.h" |
| 12 #include "vm/growable_array.h" | |
| 12 #include "vm/tags.h" | 13 #include "vm/tags.h" |
| 13 #include "vm/thread_interrupter.h" | 14 #include "vm/thread_interrupter.h" |
| 14 | 15 |
| 15 // Profiler sampling and stack walking support. | 16 // Profiler sampling and stack walking support. |
| 16 // NOTE: For service related code, see profile_service.h. | 17 // NOTE: For service related code, see profile_service.h. |
| 17 | 18 |
| 18 namespace dart { | 19 namespace dart { |
| 19 | 20 |
| 20 // Forward declarations. | 21 // Forward declarations. |
| 22 class ProcessedSample; | |
| 23 class ProcessedSampleBuffer; | |
| 24 | |
| 21 class Sample; | 25 class Sample; |
| 22 class SampleBuffer; | 26 class SampleBuffer; |
| 23 | 27 |
| 24 | |
| 25 class Profiler : public AllStatic { | 28 class Profiler : public AllStatic { |
| 26 public: | 29 public: |
| 27 static void InitOnce(); | 30 static void InitOnce(); |
| 28 static void Shutdown(); | 31 static void Shutdown(); |
| 29 | 32 |
| 30 static void SetSampleDepth(intptr_t depth); | 33 static void SetSampleDepth(intptr_t depth); |
| 31 static void SetSamplePeriod(intptr_t period); | 34 static void SetSamplePeriod(intptr_t period); |
| 32 | 35 |
| 33 static void InitProfilingForIsolate(Isolate* isolate, | 36 static void InitProfilingForIsolate(Isolate* isolate, |
| 34 bool shared_buffer = true); | 37 bool shared_buffer = true); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 } | 103 } |
| 101 | 104 |
| 102 private: | 105 private: |
| 103 Isolate* isolate_; | 106 Isolate* isolate_; |
| 104 intptr_t visited_; | 107 intptr_t visited_; |
| 105 | 108 |
| 106 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); | 109 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); |
| 107 }; | 110 }; |
| 108 | 111 |
| 109 | 112 |
| 110 class PreprocessVisitor : public SampleVisitor { | 113 class SampleFilter : public ValueObject { |
| 111 public: | 114 public: |
| 112 explicit PreprocessVisitor(Isolate* isolate); | 115 explicit SampleFilter(Isolate* isolate) : isolate_(isolate) { } |
| 116 virtual ~SampleFilter() { } | |
| 113 | 117 |
| 114 virtual void VisitSample(Sample* sample); | 118 // Override this function. |
| 119 // Return |true| if |sample| passes the filter. | |
| 120 virtual bool FilterSample(Sample* sample) { | |
| 121 return true; | |
| 122 } | |
| 123 | |
| 124 Isolate* isolate() const { | |
| 125 return isolate_; | |
| 126 } | |
| 115 | 127 |
| 116 private: | 128 private: |
| 117 void CheckForMissingDartFrame(const Code& code, Sample* sample) const; | 129 Isolate* isolate_; |
| 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 }; | 130 }; |
| 129 | 131 |
| 130 | 132 |
| 131 class ClearProfileVisitor : public SampleVisitor { | 133 class ClearProfileVisitor : public SampleVisitor { |
| 132 public: | 134 public: |
| 133 explicit ClearProfileVisitor(Isolate* isolate); | 135 explicit ClearProfileVisitor(Isolate* isolate); |
| 134 | 136 |
| 135 virtual void VisitSample(Sample* sample); | 137 virtual void VisitSample(Sample* sample); |
| 136 }; | 138 }; |
| 137 | 139 |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 } | 401 } |
| 400 if (sample->At(0) == 0) { | 402 if (sample->At(0) == 0) { |
| 401 // No frames. | 403 // No frames. |
| 402 continue; | 404 continue; |
| 403 } | 405 } |
| 404 visitor->IncrementVisited(); | 406 visitor->IncrementVisited(); |
| 405 visitor->VisitSample(sample); | 407 visitor->VisitSample(sample); |
| 406 } | 408 } |
| 407 } | 409 } |
| 408 | 410 |
| 411 ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter); | |
| 412 | |
| 409 private: | 413 private: |
| 414 ProcessedSample* BuildProcessedSample(Sample* sample); | |
| 415 Sample* Next(Sample* sample); | |
| 416 | |
| 410 Sample* samples_; | 417 Sample* samples_; |
| 411 intptr_t capacity_; | 418 intptr_t capacity_; |
| 412 uintptr_t cursor_; | 419 uintptr_t cursor_; |
| 413 | 420 |
| 414 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 421 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
| 415 }; | 422 }; |
| 416 | 423 |
| 417 | 424 |
| 425 // A |ProcessedSample| is a combination of 1 (or more) |Sample|(s) that have | |
| 426 // been merged into a logical sample. The raw data may have been processed to | |
| 427 // improve the quality of the stack trace. | |
| 428 class ProcessedSample : public ZoneAllocated { | |
| 429 public: | |
| 430 ProcessedSample(); | |
| 431 | |
| 432 // Add |pc| to stack trace. | |
| 433 void Add(uword pc) { | |
| 434 pcs_.Add(pc); | |
| 435 } | |
| 436 | |
| 437 // Insert |pc| at |index|. | |
| 438 void InsertAt(intptr_t index, uword pc) { | |
| 439 pcs_.InsertAt(index, pc); | |
| 440 } | |
| 441 | |
| 442 // Number of pcs in stack trace. | |
| 443 intptr_t length() const { return pcs_.length(); } | |
| 444 | |
| 445 // Get |pc| at |index|. | |
| 446 uword At(intptr_t index) const { | |
| 447 ASSERT(index >= 0); | |
| 448 ASSERT(index < length()); | |
| 449 return pcs_[index]; | |
| 450 } | |
| 451 | |
| 452 // Timestamp sample was taken at. | |
| 453 int64_t timestamp() const { return timestamp_; } | |
| 454 void set_timestamp(int64_t timestamp) { timestamp_ = timestamp; } | |
| 455 | |
| 456 // The VM tag. | |
| 457 uword vm_tag() const { return vm_tag_; } | |
| 458 void set_vm_tag(uword tag) { vm_tag_ = tag; } | |
| 459 | |
| 460 // The user tag. | |
| 461 uword user_tag() const { return user_tag_; } | |
| 462 void set_user_tag(uword tag) { user_tag_ = tag; } | |
| 463 | |
| 464 // The class id if this is an allocation profile sample. -1 otherwise. | |
| 465 intptr_t cid() const { return cid_; } | |
|
rmacnak
2015/06/23 22:38:54
Consider 'allocation_cid'
Cutch
2015/06/24 13:54:34
Done.
| |
| 466 void set_cid(intptr_t cid) { cid_ = cid; } | |
| 467 | |
| 468 // Was the stack trace truncated? | |
| 469 bool truncated() const { return truncated_; } | |
| 470 void set_truncated(bool truncated) { truncated_ = truncated; } | |
| 471 | |
| 472 // Was the first frame in the stack trace executing? | |
| 473 bool first_frame_executing() const { return first_frame_executing_; } | |
| 474 void set_first_frame_executing(bool first_frame_executing) { | |
| 475 first_frame_executing_ = first_frame_executing; | |
| 476 } | |
| 477 | |
| 478 private: | |
| 479 void FixupCaller(Isolate* isolate, | |
| 480 Isolate* vm_isolate, | |
| 481 uword pc_marker, | |
| 482 uword* stack_buffer); | |
| 483 | |
| 484 void CheckForMissingDartFrame(Isolate* isolate, | |
| 485 Isolate* vm_isolate, | |
| 486 const Code& code, | |
| 487 uword pc_marker, | |
| 488 uword* stack_buffer); | |
| 489 | |
| 490 static RawCode* FindCodeForPC(Isolate* isolate, | |
| 491 Isolate* vm_isolate, | |
| 492 uword pc); | |
| 493 | |
| 494 static bool ContainedInDartCodeHeaps(Isolate* isolate, | |
| 495 Isolate* vm_isolate, | |
| 496 uword pc); | |
| 497 | |
| 498 ZoneGrowableArray<uword> pcs_; | |
| 499 int64_t timestamp_; | |
| 500 uword vm_tag_; | |
| 501 uword user_tag_; | |
| 502 intptr_t cid_; | |
| 503 bool truncated_; | |
| 504 bool first_frame_executing_; | |
| 505 | |
| 506 friend class SampleBuffer; | |
| 507 DISALLOW_COPY_AND_ASSIGN(ProcessedSample); | |
| 508 }; | |
| 509 | |
| 510 | |
| 511 // A collection of |ProcessedSample|s. | |
| 512 class ProcessedSampleBuffer : public ZoneAllocated { | |
| 513 public: | |
| 514 ProcessedSampleBuffer(); | |
| 515 | |
| 516 void Add(ProcessedSample* sample) { | |
| 517 samples_.Add(sample); | |
| 518 } | |
| 519 | |
| 520 intptr_t length() const { | |
| 521 return samples_.length(); | |
| 522 } | |
| 523 | |
| 524 ProcessedSample* At(intptr_t index) { | |
| 525 return samples_.At(index); | |
| 526 } | |
| 527 | |
| 528 private: | |
| 529 ZoneGrowableArray<ProcessedSample*> samples_; | |
| 530 | |
| 531 DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer); | |
| 532 }; | |
| 533 | |
| 418 } // namespace dart | 534 } // namespace dart |
| 419 | 535 |
| 420 #endif // VM_PROFILER_H_ | 536 #endif // VM_PROFILER_H_ |
| OLD | NEW |