| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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_TIMELINE_H_ | 5 #ifndef VM_TIMELINE_H_ |
| 6 #define VM_TIMELINE_H_ | 6 #define VM_TIMELINE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/bitfield.h" | 9 #include "vm/bitfield.h" |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // Shutdown timeline system. Not thread safe. | 38 // Shutdown timeline system. Not thread safe. |
| 39 static void Shutdown(); | 39 static void Shutdown(); |
| 40 | 40 |
| 41 // Access the global recorder. Not thread safe. | 41 // Access the global recorder. Not thread safe. |
| 42 static TimelineEventRecorder* recorder(); | 42 static TimelineEventRecorder* recorder(); |
| 43 | 43 |
| 44 static bool EnableStreamByDefault(const char* stream_name); | 44 static bool EnableStreamByDefault(const char* stream_name); |
| 45 | 45 |
| 46 static TimelineStream* GetVMStream(); | 46 static TimelineStream* GetVMStream(); |
| 47 | 47 |
| 48 // Reclaim all |TimelineEventBlock|s that are owned by the current isolate. |
| 49 static void ReclaimIsolateBlocks(); |
| 50 |
| 51 // Reclaim all |TimelineEventBlocks|s that are owned by all isolates and |
| 52 // the global block owned by the VM. |
| 53 static void ReclaimAllBlocks(); |
| 54 |
| 48 #define ISOLATE_TIMELINE_STREAM_FLAGS(name, not_used) \ | 55 #define ISOLATE_TIMELINE_STREAM_FLAGS(name, not_used) \ |
| 49 static const bool* Stream##name##EnabledFlag() { \ | 56 static const bool* Stream##name##EnabledFlag() { \ |
| 50 return &stream_##name##_enabled_; \ | 57 return &stream_##name##_enabled_; \ |
| 51 } \ | 58 } \ |
| 52 static void SetStream##name##Enabled(bool enabled) { \ | 59 static void SetStream##name##Enabled(bool enabled) { \ |
| 53 stream_##name##_enabled_ = enabled; \ | 60 stream_##name##_enabled_ = enabled; \ |
| 54 } | 61 } |
| 55 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAGS) | 62 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAGS) |
| 56 #undef ISOLATE_TIMELINE_STREAM_FLAGS | 63 #undef ISOLATE_TIMELINE_STREAM_FLAGS |
| 57 | 64 |
| 58 private: | 65 private: |
| 66 static void ReclaimBlocksForIsolate(Isolate* isolate); |
| 67 |
| 59 static TimelineEventRecorder* recorder_; | 68 static TimelineEventRecorder* recorder_; |
| 60 static TimelineStream* vm_stream_; | 69 static TimelineStream* vm_stream_; |
| 61 | 70 |
| 62 #define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used) \ | 71 #define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used) \ |
| 63 static bool stream_##name##_enabled_; | 72 static bool stream_##name##_enabled_; |
| 64 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DECLARE_FLAG) | 73 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DECLARE_FLAG) |
| 65 #undef ISOLATE_TIMELINE_STREAM_DECLARE_FLAG | 74 #undef ISOLATE_TIMELINE_STREAM_DECLARE_FLAG |
| 66 | 75 |
| 67 friend class TimelineRecorderOverride; | 76 friend class TimelineRecorderOverride; |
| 77 friend class ReclaimBlocksIsolateVisitor; |
| 68 }; | 78 }; |
| 69 | 79 |
| 70 | 80 |
| 71 // You should get a |TimelineEvent| from a |TimelineStream|. | 81 // You should get a |TimelineEvent| from a |TimelineStream|. |
| 72 class TimelineEvent { | 82 class TimelineEvent { |
| 73 public: | 83 public: |
| 74 // Keep in sync with StateBits below. | 84 // Keep in sync with StateBits below. |
| 75 enum EventType { | 85 enum EventType { |
| 76 kNone, | 86 kNone, |
| 77 kDuration, | 87 kDuration, |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 | 395 |
| 386 // Returns false if |this| violates any of the following invariants: | 396 // Returns false if |this| violates any of the following invariants: |
| 387 // - events in the block come from one thread. | 397 // - events in the block come from one thread. |
| 388 // - events have monotonically increasing timestamps. | 398 // - events have monotonically increasing timestamps. |
| 389 bool CheckBlock(); | 399 bool CheckBlock(); |
| 390 | 400 |
| 391 // Call Reset on all events and set length to 0. | 401 // Call Reset on all events and set length to 0. |
| 392 void Reset(); | 402 void Reset(); |
| 393 | 403 |
| 394 // Only safe to access under the recorder's lock. | 404 // Only safe to access under the recorder's lock. |
| 395 bool open() const { | 405 bool in_use() const { |
| 396 return open_; | 406 return in_use_; |
| 397 } | 407 } |
| 398 | 408 |
| 399 // Only safe to access under the recorder's lock. | 409 // Only safe to access under the recorder's lock. |
| 400 Isolate* isolate() const { | 410 Isolate* isolate() const { |
| 401 return isolate_; | 411 return isolate_; |
| 402 } | 412 } |
| 403 | 413 |
| 404 protected: | 414 protected: |
| 405 TimelineEvent* StartEvent(); | 415 TimelineEvent* StartEvent(); |
| 406 | 416 |
| 407 TimelineEvent events_[kBlockSize]; | 417 TimelineEvent events_[kBlockSize]; |
| 408 TimelineEventBlock* next_; | 418 TimelineEventBlock* next_; |
| 409 intptr_t length_; | 419 intptr_t length_; |
| 410 intptr_t block_index_; | 420 intptr_t block_index_; |
| 411 | 421 |
| 412 // Only accessed under the recorder's lock. | 422 // Only accessed under the recorder's lock. |
| 413 Isolate* isolate_; | 423 Isolate* isolate_; |
| 414 bool open_; | 424 bool in_use_; |
| 415 | 425 |
| 416 void Open(Isolate* isolate); | 426 void Open(Isolate* isolate); |
| 417 void Finish(); | 427 void Finish(); |
| 418 | 428 |
| 419 friend class Thread; | 429 friend class Thread; |
| 420 friend class ThreadRegistry; | 430 friend class ThreadRegistry; |
| 421 friend class TimelineEventRecorder; | 431 friend class TimelineEventRecorder; |
| 422 friend class TimelineEventRingRecorder; | 432 friend class TimelineEventRingRecorder; |
| 423 friend class TimelineEventEndlessRecorder; | 433 friend class TimelineEventEndlessRecorder; |
| 424 friend class TimelineTestHelper; | 434 friend class TimelineTestHelper; |
| 425 | 435 |
| 426 private: | 436 private: |
| 427 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); | 437 DISALLOW_COPY_AND_ASSIGN(TimelineEventBlock); |
| 428 }; | 438 }; |
| 429 | 439 |
| 430 | 440 |
| 431 class TimelineEventFilter : public ValueObject { | 441 class TimelineEventFilter : public ValueObject { |
| 432 public: | 442 public: |
| 433 TimelineEventFilter(); | 443 TimelineEventFilter(); |
| 434 virtual ~TimelineEventFilter(); | 444 virtual ~TimelineEventFilter(); |
| 435 | 445 |
| 436 virtual bool IncludeBlock(TimelineEventBlock* block) { | 446 virtual bool IncludeBlock(TimelineEventBlock* block) { |
| 437 if (block == NULL) { | 447 if (block == NULL) { |
| 438 return false; | 448 return false; |
| 439 } | 449 } |
| 440 // Not empty and not open. | 450 // Not empty and not in use. |
| 441 return !block->IsEmpty() && !block->open(); | 451 return !block->IsEmpty() && !block->in_use(); |
| 442 } | 452 } |
| 443 | 453 |
| 444 virtual bool IncludeEvent(TimelineEvent* event) { | 454 virtual bool IncludeEvent(TimelineEvent* event) { |
| 445 if (event == NULL) { | 455 if (event == NULL) { |
| 446 return false; | 456 return false; |
| 447 } | 457 } |
| 448 return event->IsValid(); | 458 return event->IsValid(); |
| 449 } | 459 } |
| 450 | 460 |
| 451 private: | 461 private: |
| 452 }; | 462 }; |
| 453 | 463 |
| 454 | 464 |
| 455 class IsolateTimelineEventFilter : public TimelineEventFilter { | 465 class IsolateTimelineEventFilter : public TimelineEventFilter { |
| 456 public: | 466 public: |
| 457 explicit IsolateTimelineEventFilter(Isolate* isolate); | 467 explicit IsolateTimelineEventFilter(Isolate* isolate); |
| 458 | 468 |
| 459 bool IncludeBlock(TimelineEventBlock* block) { | 469 bool IncludeBlock(TimelineEventBlock* block) { |
| 460 if (block == NULL) { | 470 if (block == NULL) { |
| 461 return false; | 471 return false; |
| 462 } | 472 } |
| 463 // Not empty, not open, and isolate match. | 473 // Not empty, not in use, and isolate match. |
| 464 return !block->IsEmpty() && | 474 return !block->IsEmpty() && !block->in_use() && |
| 465 (block->isolate() == isolate_); | 475 (block->isolate() == isolate_); |
| 466 } | 476 } |
| 467 | 477 |
| 468 private: | 478 private: |
| 469 Isolate* isolate_; | 479 Isolate* isolate_; |
| 470 }; | 480 }; |
| 471 | 481 |
| 472 | 482 |
| 473 // Recorder of |TimelineEvent|s. | 483 // Recorder of |TimelineEvent|s. |
| 474 class TimelineEventRecorder { | 484 class TimelineEventRecorder { |
| 475 public: | 485 public: |
| 476 TimelineEventRecorder(); | 486 TimelineEventRecorder(); |
| 477 virtual ~TimelineEventRecorder() {} | 487 virtual ~TimelineEventRecorder() {} |
| 478 | 488 |
| 479 TimelineEventBlock* GetNewBlock(); | 489 TimelineEventBlock* GetNewBlock(); |
| 480 | 490 |
| 481 // Interface method(s) which must be implemented. | 491 // Interface method(s) which must be implemented. |
| 482 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0; | 492 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0; |
| 483 | 493 |
| 484 int64_t GetNextAsyncId(); | 494 int64_t GetNextAsyncId(); |
| 485 | 495 |
| 496 void FinishBlock(TimelineEventBlock* block); |
| 497 |
| 486 protected: | 498 protected: |
| 487 void WriteTo(const char* directory); | 499 void WriteTo(const char* directory); |
| 488 | 500 |
| 489 // Interface method(s) which must be implemented. | 501 // Interface method(s) which must be implemented. |
| 490 virtual TimelineEvent* StartEvent() = 0; | 502 virtual TimelineEvent* StartEvent() = 0; |
| 491 virtual void CompleteEvent(TimelineEvent* event) = 0; | 503 virtual void CompleteEvent(TimelineEvent* event) = 0; |
| 492 virtual TimelineEventBlock* GetHeadBlockLocked() = 0; | 504 virtual TimelineEventBlock* GetHeadBlockLocked() = 0; |
| 493 virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0; | 505 virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0; |
| 494 | 506 |
| 495 // Utility method(s). | 507 // Utility method(s). |
| 496 void PrintJSONMeta(JSONArray* array) const; | 508 void PrintJSONMeta(JSONArray* array) const; |
| 497 TimelineEvent* ThreadBlockStartEvent(); | 509 TimelineEvent* ThreadBlockStartEvent(); |
| 498 TimelineEvent* GlobalBlockStartEvent(); | 510 TimelineEvent* GlobalBlockStartEvent(); |
| 499 | 511 |
| 500 Mutex lock_; | 512 Mutex lock_; |
| 501 // Only accessed under |lock_|. | 513 // Only accessed under |lock_|. |
| 502 TimelineEventBlock* global_block_; | 514 TimelineEventBlock* global_block_; |
| 503 void FinishGlobalBlock(); | 515 void ReclaimGlobalBlock(); |
| 504 | 516 |
| 505 uintptr_t async_id_; | 517 uintptr_t async_id_; |
| 506 | 518 |
| 507 friend class ThreadRegistry; | |
| 508 friend class TimelineEvent; | 519 friend class TimelineEvent; |
| 509 friend class TimelineEventBlockIterator; | 520 friend class TimelineEventBlockIterator; |
| 510 friend class TimelineStream; | 521 friend class TimelineStream; |
| 511 friend class TimelineTestHelper; | 522 friend class TimelineTestHelper; |
| 512 friend class Timeline; | 523 friend class Timeline; |
| 513 friend class Isolate; | |
| 514 | 524 |
| 515 private: | 525 private: |
| 516 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 526 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
| 517 }; | 527 }; |
| 518 | 528 |
| 519 | 529 |
| 520 // A recorder that stores events in a ring buffer of fixed capacity. | 530 // A recorder that stores events in a ring buffer of fixed capacity. |
| 521 class TimelineEventRingRecorder : public TimelineEventRecorder { | 531 class TimelineEventRingRecorder : public TimelineEventRecorder { |
| 522 public: | 532 public: |
| 523 static const intptr_t kDefaultCapacity = 8192; | 533 static const intptr_t kDefaultCapacity = 8192; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 TimelineEventBlock* Next(); | 622 TimelineEventBlock* Next(); |
| 613 | 623 |
| 614 private: | 624 private: |
| 615 TimelineEventBlock* current_; | 625 TimelineEventBlock* current_; |
| 616 TimelineEventRecorder* recorder_; | 626 TimelineEventRecorder* recorder_; |
| 617 }; | 627 }; |
| 618 | 628 |
| 619 } // namespace dart | 629 } // namespace dart |
| 620 | 630 |
| 621 #endif // VM_TIMELINE_H_ | 631 #endif // VM_TIMELINE_H_ |
| OLD | NEW |