| 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 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 char* value; | 81 char* value; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 | 84 |
| 85 // You should get a |TimelineEvent| from a |TimelineStream|. | 85 // You should get a |TimelineEvent| from a |TimelineStream|. |
| 86 class TimelineEvent { | 86 class TimelineEvent { |
| 87 public: | 87 public: |
| 88 // Keep in sync with StateBits below. | 88 // Keep in sync with StateBits below. |
| 89 enum EventType { | 89 enum EventType { |
| 90 kNone, | 90 kNone, |
| 91 kSerializedJSON, // Events from Dart code. |
| 91 kBegin, | 92 kBegin, |
| 92 kEnd, | 93 kEnd, |
| 93 kDuration, | 94 kDuration, |
| 94 kInstant, | 95 kInstant, |
| 95 kAsyncBegin, | 96 kAsyncBegin, |
| 96 kAsyncInstant, | 97 kAsyncInstant, |
| 97 kAsyncEnd, | 98 kAsyncEnd, |
| 98 kNumEventTypes, | 99 kNumEventTypes, |
| 99 }; | 100 }; |
| 100 | 101 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 123 void Duration(const char* label, | 124 void Duration(const char* label, |
| 124 int64_t start_micros, | 125 int64_t start_micros, |
| 125 int64_t end_micros); | 126 int64_t end_micros); |
| 126 | 127 |
| 127 void Begin(const char* label, | 128 void Begin(const char* label, |
| 128 int64_t micros = OS::GetCurrentTraceMicros()); | 129 int64_t micros = OS::GetCurrentTraceMicros()); |
| 129 | 130 |
| 130 void End(const char* label, | 131 void End(const char* label, |
| 131 int64_t micros = OS::GetCurrentTraceMicros()); | 132 int64_t micros = OS::GetCurrentTraceMicros()); |
| 132 | 133 |
| 134 void SerializedJSON(const char* json); |
| 135 |
| 133 // Set the number of arguments in the event. | 136 // Set the number of arguments in the event. |
| 134 void SetNumArguments(intptr_t length); | 137 void SetNumArguments(intptr_t length); |
| 135 // |name| must be a compile time constant. Takes ownership of |argumentp|. | 138 // |name| must be a compile time constant. Takes ownership of |argument|. |
| 136 void SetArgument(intptr_t i, const char* name, char* argument); | 139 void SetArgument(intptr_t i, const char* name, char* argument); |
| 137 // |name| must be a compile time constant. Copies |argument|. | 140 // |name| must be a compile time constant. Copies |argument|. |
| 138 void CopyArgument(intptr_t i, const char* name, const char* argument); | 141 void CopyArgument(intptr_t i, const char* name, const char* argument); |
| 139 // |name| must be a compile time constant. | 142 // |name| must be a compile time constant. |
| 140 void FormatArgument(intptr_t i, | 143 void FormatArgument(intptr_t i, |
| 141 const char* name, | 144 const char* name, |
| 142 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); | 145 const char* fmt, ...) PRINTF_ATTRIBUTE(4, 5); |
| 143 | 146 |
| 144 void StealArguments(intptr_t arguments_length, | 147 void StealArguments(intptr_t arguments_length, |
| 145 TimelineEventArgument* arguments); | 148 TimelineEventArgument* arguments); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 161 ASSERT(IsFinishedDuration()); | 164 ASSERT(IsFinishedDuration()); |
| 162 return timestamp1_; | 165 return timestamp1_; |
| 163 } | 166 } |
| 164 | 167 |
| 165 void PrintJSON(JSONStream* stream) const; | 168 void PrintJSON(JSONStream* stream) const; |
| 166 | 169 |
| 167 ThreadId thread() const { | 170 ThreadId thread() const { |
| 168 return thread_; | 171 return thread_; |
| 169 } | 172 } |
| 170 | 173 |
| 174 Dart_Port isolate_id() const { |
| 175 return isolate_id_; |
| 176 } |
| 177 |
| 171 const char* label() const { | 178 const char* label() const { |
| 172 return label_; | 179 return label_; |
| 173 } | 180 } |
| 174 | 181 |
| 175 // Does this duration end before |micros| ? | 182 // Does this duration end before |micros| ? |
| 176 bool DurationFinishedBefore(int64_t micros) const { | 183 bool DurationFinishedBefore(int64_t micros) const { |
| 177 return TimeEnd() <= micros; | 184 return TimeEnd() <= micros; |
| 178 } | 185 } |
| 179 | 186 |
| 180 bool IsDuration() const { | 187 bool IsDuration() const { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 if (other->TimeOrigin() > TimeEnd()) { | 223 if (other->TimeOrigin() > TimeEnd()) { |
| 217 return false; | 224 return false; |
| 218 } | 225 } |
| 219 if (other->TimeEnd() > TimeEnd()) { | 226 if (other->TimeEnd() > TimeEnd()) { |
| 220 return false; | 227 return false; |
| 221 } | 228 } |
| 222 return true; | 229 return true; |
| 223 } | 230 } |
| 224 } | 231 } |
| 225 | 232 |
| 233 const char* GetSerializedJSON() const; |
| 234 |
| 226 private: | 235 private: |
| 227 int64_t timestamp0_; | 236 int64_t timestamp0_; |
| 228 int64_t timestamp1_; | 237 int64_t timestamp1_; |
| 229 TimelineEventArgument* arguments_; | 238 TimelineEventArgument* arguments_; |
| 230 intptr_t arguments_length_; | 239 intptr_t arguments_length_; |
| 231 uword state_; | 240 uword state_; |
| 232 const char* label_; | 241 const char* label_; |
| 233 const char* category_; | 242 const char* category_; |
| 234 ThreadId thread_; | 243 ThreadId thread_; |
| 235 Isolate* isolate_; | 244 Dart_Port isolate_id_; |
| 236 | 245 |
| 237 void FreeArguments(); | 246 void FreeArguments(); |
| 238 | 247 |
| 239 void StreamInit(TimelineStream* stream); | 248 void StreamInit(TimelineStream* stream); |
| 240 void Init(EventType event_type, const char* label); | 249 void Init(EventType event_type, const char* label); |
| 241 | 250 |
| 242 void set_event_type(EventType event_type) { | 251 void set_event_type(EventType event_type) { |
| 243 // We only reserve 4 bits to hold the event type. | 252 // We only reserve 4 bits to hold the event type. |
| 244 COMPILE_ASSERT(kNumEventTypes < 16); | 253 COMPILE_ASSERT(kNumEventTypes < 16); |
| 245 state_ = EventTypeField::update(event_type, state_); | 254 state_ = EventTypeField::update(event_type, state_); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 ASSERT(index < kBlockSize); | 398 ASSERT(index < kBlockSize); |
| 390 return &events_[index]; | 399 return &events_[index]; |
| 391 } | 400 } |
| 392 | 401 |
| 393 const TimelineEvent* At(intptr_t index) const { | 402 const TimelineEvent* At(intptr_t index) const { |
| 394 ASSERT(index >= 0); | 403 ASSERT(index >= 0); |
| 395 ASSERT(index < kBlockSize); | 404 ASSERT(index < kBlockSize); |
| 396 return &events_[index]; | 405 return &events_[index]; |
| 397 } | 406 } |
| 398 | 407 |
| 399 // Attempt to sniff a thread id from the first event. | |
| 400 ThreadId thread() const; | |
| 401 | |
| 402 // Attempt to sniff the timestamp from the first event. | 408 // Attempt to sniff the timestamp from the first event. |
| 403 int64_t LowerTimeBound() const; | 409 int64_t LowerTimeBound() const; |
| 404 | 410 |
| 405 // Returns false if |this| violates any of the following invariants: | 411 // Returns false if |this| violates any of the following invariants: |
| 406 // - events in the block come from one thread. | 412 // - events in the block come from one thread. |
| 407 // - events have monotonically increasing timestamps. | 413 // - events have monotonically increasing timestamps. |
| 408 bool CheckBlock(); | 414 bool CheckBlock(); |
| 409 | 415 |
| 410 // Call Reset on all events and set length to 0. | 416 // Call Reset on all events and set length to 0. |
| 411 void Reset(); | 417 void Reset(); |
| 412 | 418 |
| 413 // Only safe to access under the recorder's lock. | 419 // Only safe to access under the recorder's lock. |
| 414 bool in_use() const { | 420 bool in_use() const { |
| 415 return in_use_; | 421 return in_use_; |
| 416 } | 422 } |
| 417 | 423 |
| 418 // Only safe to access under the recorder's lock. | 424 // Only safe to access under the recorder's lock. |
| 419 Isolate* isolate() const { | 425 ThreadId thread_id() const { |
| 420 return isolate_; | 426 return thread_id_; |
| 421 } | 427 } |
| 422 | 428 |
| 423 protected: | 429 protected: |
| 424 TimelineEvent* StartEvent(); | 430 TimelineEvent* StartEvent(); |
| 425 | 431 |
| 426 TimelineEvent events_[kBlockSize]; | 432 TimelineEvent events_[kBlockSize]; |
| 427 TimelineEventBlock* next_; | 433 TimelineEventBlock* next_; |
| 428 intptr_t length_; | 434 intptr_t length_; |
| 429 intptr_t block_index_; | 435 intptr_t block_index_; |
| 430 | 436 |
| 431 // Only accessed under the recorder's lock. | 437 // Only accessed under the recorder's lock. |
| 432 Isolate* isolate_; | 438 ThreadId thread_id_; |
| 433 bool in_use_; | 439 bool in_use_; |
| 434 | 440 |
| 435 void Open(Isolate* isolate); | 441 void Open(); |
| 436 void Finish(); | 442 void Finish(); |
| 437 | 443 |
| 438 friend class Thread; | 444 friend class Thread; |
| 439 friend class ThreadRegistry; | 445 friend class ThreadRegistry; |
| 440 friend class TimelineEventRecorder; | 446 friend class TimelineEventRecorder; |
| 441 friend class TimelineEventRingRecorder; | 447 friend class TimelineEventRingRecorder; |
| 442 friend class TimelineEventEndlessRecorder; | 448 friend class TimelineEventEndlessRecorder; |
| 443 friend class TimelineTestHelper; | 449 friend class TimelineTestHelper; |
| 444 | 450 |
| 445 private: | 451 private: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 466 } | 472 } |
| 467 return event->IsValid(); | 473 return event->IsValid(); |
| 468 } | 474 } |
| 469 | 475 |
| 470 private: | 476 private: |
| 471 }; | 477 }; |
| 472 | 478 |
| 473 | 479 |
| 474 class IsolateTimelineEventFilter : public TimelineEventFilter { | 480 class IsolateTimelineEventFilter : public TimelineEventFilter { |
| 475 public: | 481 public: |
| 476 explicit IsolateTimelineEventFilter(Isolate* isolate); | 482 explicit IsolateTimelineEventFilter(Dart_Port isolate_id); |
| 477 | 483 |
| 478 bool IncludeBlock(TimelineEventBlock* block) { | 484 bool IncludeBlock(TimelineEventBlock* block) { |
| 479 if (block == NULL) { | 485 if (block == NULL) { |
| 480 return false; | 486 return false; |
| 481 } | 487 } |
| 482 // Not empty, not in use, and isolate match. | 488 // Not empty, not in use, and isolate match. |
| 483 return !block->IsEmpty() && !block->in_use() && | 489 return !block->IsEmpty() && !block->in_use(); |
| 484 (block->isolate() == isolate_); | 490 } |
| 491 |
| 492 bool IncludeEvent(TimelineEvent* event) { |
| 493 return event->IsValid() && |
| 494 (event->isolate_id() == isolate_id_); |
| 485 } | 495 } |
| 486 | 496 |
| 487 private: | 497 private: |
| 488 Isolate* isolate_; | 498 Dart_Port isolate_id_; |
| 489 }; | 499 }; |
| 490 | 500 |
| 491 | 501 |
| 492 // Timeline events from Dart code are eagerly converted to JSON and stored | |
| 493 // as a C string. | |
| 494 class DartTimelineEvent { | |
| 495 public: | |
| 496 DartTimelineEvent(); | |
| 497 ~DartTimelineEvent(); | |
| 498 | |
| 499 void Clear(); | |
| 500 | |
| 501 // This function makes a copy of |event|. | |
| 502 void Init(Isolate* isolate, const char* event); | |
| 503 | |
| 504 bool IsValid() const { | |
| 505 return (isolate_ != NULL) && | |
| 506 (event_as_json_ != NULL); | |
| 507 } | |
| 508 | |
| 509 Isolate* isolate() const { | |
| 510 return isolate_; | |
| 511 } | |
| 512 | |
| 513 char* event_as_json() const { | |
| 514 return event_as_json_; | |
| 515 } | |
| 516 | |
| 517 private: | |
| 518 Isolate* isolate_; | |
| 519 char* event_as_json_; | |
| 520 | |
| 521 DISALLOW_COPY_AND_ASSIGN(DartTimelineEvent); | |
| 522 }; | |
| 523 | |
| 524 | |
| 525 // Recorder of |TimelineEvent|s. | 502 // Recorder of |TimelineEvent|s. |
| 526 class TimelineEventRecorder { | 503 class TimelineEventRecorder { |
| 527 public: | 504 public: |
| 528 TimelineEventRecorder(); | 505 TimelineEventRecorder(); |
| 529 virtual ~TimelineEventRecorder() {} | 506 virtual ~TimelineEventRecorder() {} |
| 530 | 507 |
| 531 TimelineEventBlock* GetNewBlock(); | 508 TimelineEventBlock* GetNewBlock(); |
| 532 | 509 |
| 533 // Interface method(s) which must be implemented. | 510 // Interface method(s) which must be implemented. |
| 534 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0; | 511 virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0; |
| 535 virtual void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) = 0; | 512 virtual void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) = 0; |
| 536 | 513 |
| 537 int64_t GetNextAsyncId(); | 514 int64_t GetNextAsyncId(); |
| 538 | 515 |
| 539 void FinishBlock(TimelineEventBlock* block); | 516 void FinishBlock(TimelineEventBlock* block); |
| 540 | 517 |
| 541 // Interface method(s) which must be implemented. | |
| 542 virtual void AppendDartEvent(Isolate* isolate, const char* event) = 0; | |
| 543 | |
| 544 protected: | 518 protected: |
| 545 void WriteTo(const char* directory); | 519 void WriteTo(const char* directory); |
| 546 | 520 |
| 547 // Interface method(s) which must be implemented. | 521 // Interface method(s) which must be implemented. |
| 548 virtual TimelineEvent* StartEvent() = 0; | 522 virtual TimelineEvent* StartEvent() = 0; |
| 549 virtual void CompleteEvent(TimelineEvent* event) = 0; | 523 virtual void CompleteEvent(TimelineEvent* event) = 0; |
| 550 virtual TimelineEventBlock* GetHeadBlockLocked() = 0; | 524 virtual TimelineEventBlock* GetHeadBlockLocked() = 0; |
| 551 virtual TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) = 0; | 525 virtual TimelineEventBlock* GetNewBlockLocked() = 0; |
| 552 virtual intptr_t NumDartEventsLocked() = 0; | |
| 553 virtual DartTimelineEvent* DartEventAtLocked(intptr_t i) = 0; | |
| 554 | 526 |
| 555 // Utility method(s). | 527 // Utility method(s). |
| 556 void PrintJSONMeta(JSONArray* array) const; | 528 void PrintJSONMeta(JSONArray* array) const; |
| 557 TimelineEvent* ThreadBlockStartEvent(); | 529 TimelineEvent* ThreadBlockStartEvent(); |
| 558 void ThreadBlockCompleteEvent(TimelineEvent* event); | 530 void ThreadBlockCompleteEvent(TimelineEvent* event); |
| 559 | 531 |
| 560 Mutex lock_; | 532 Mutex lock_; |
| 561 uintptr_t async_id_; | 533 uintptr_t async_id_; |
| 562 | 534 |
| 563 friend class DartTimelineEventIterator; | |
| 564 friend class TimelineEvent; | 535 friend class TimelineEvent; |
| 565 friend class TimelineEventBlockIterator; | 536 friend class TimelineEventBlockIterator; |
| 566 friend class TimelineStream; | 537 friend class TimelineStream; |
| 567 friend class TimelineTestHelper; | 538 friend class TimelineTestHelper; |
| 568 friend class Timeline; | 539 friend class Timeline; |
| 569 | 540 |
| 570 private: | 541 private: |
| 571 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); | 542 DISALLOW_COPY_AND_ASSIGN(TimelineEventRecorder); |
| 572 }; | 543 }; |
| 573 | 544 |
| 574 | 545 |
| 575 // A recorder that stores events in a ring buffer of fixed capacity. | 546 // A recorder that stores events in a ring buffer of fixed capacity. |
| 576 class TimelineEventRingRecorder : public TimelineEventRecorder { | 547 class TimelineEventRingRecorder : public TimelineEventRecorder { |
| 577 public: | 548 public: |
| 578 static const intptr_t kDefaultCapacity = 8192; | 549 static const intptr_t kDefaultCapacity = 8192; |
| 579 | 550 |
| 580 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); | 551 explicit TimelineEventRingRecorder(intptr_t capacity = kDefaultCapacity); |
| 581 ~TimelineEventRingRecorder(); | 552 ~TimelineEventRingRecorder(); |
| 582 | 553 |
| 583 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); | 554 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 584 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); | 555 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); |
| 585 | 556 |
| 586 void AppendDartEvent(Isolate* isolate, const char* event); | |
| 587 | |
| 588 protected: | 557 protected: |
| 589 TimelineEvent* StartEvent(); | 558 TimelineEvent* StartEvent(); |
| 590 void CompleteEvent(TimelineEvent* event); | 559 void CompleteEvent(TimelineEvent* event); |
| 591 TimelineEventBlock* GetHeadBlockLocked(); | 560 TimelineEventBlock* GetHeadBlockLocked(); |
| 592 intptr_t FindOldestBlockIndex() const; | 561 intptr_t FindOldestBlockIndex() const; |
| 593 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate); | 562 TimelineEventBlock* GetNewBlockLocked(); |
| 594 intptr_t NumDartEventsLocked(); | |
| 595 DartTimelineEvent* DartEventAtLocked(intptr_t i); | |
| 596 | 563 |
| 597 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; | 564 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; |
| 598 | 565 |
| 599 TimelineEventBlock** blocks_; | 566 TimelineEventBlock** blocks_; |
| 600 intptr_t capacity_; | 567 intptr_t capacity_; |
| 601 intptr_t num_blocks_; | 568 intptr_t num_blocks_; |
| 602 intptr_t block_cursor_; | 569 intptr_t block_cursor_; |
| 603 | |
| 604 DartTimelineEvent** dart_events_; | |
| 605 intptr_t dart_events_capacity_; | |
| 606 intptr_t dart_events_cursor_; | |
| 607 }; | 570 }; |
| 608 | 571 |
| 609 | 572 |
| 610 // An abstract recorder that calls |StreamEvent| whenever an event is complete. | 573 // An abstract recorder that calls |StreamEvent| whenever an event is complete. |
| 611 class TimelineEventStreamingRecorder : public TimelineEventRecorder { | 574 class TimelineEventStreamingRecorder : public TimelineEventRecorder { |
| 612 public: | 575 public: |
| 613 TimelineEventStreamingRecorder(); | 576 TimelineEventStreamingRecorder(); |
| 614 ~TimelineEventStreamingRecorder(); | 577 ~TimelineEventStreamingRecorder(); |
| 615 | 578 |
| 616 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); | 579 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 617 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); | 580 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); |
| 618 | 581 |
| 619 void AppendDartEvent(Isolate* isolate, const char* event); | |
| 620 | |
| 621 // Called when |event| is ready to be streamed. It is unsafe to keep a | 582 // Called when |event| is ready to be streamed. It is unsafe to keep a |
| 622 // reference to |event| as it may be freed as soon as this function returns. | 583 // reference to |event| as it may be freed as soon as this function returns. |
| 623 virtual void StreamEvent(TimelineEvent* event) = 0; | 584 virtual void StreamEvent(TimelineEvent* event) = 0; |
| 624 virtual void StreamDartEvent(const char* event) = 0; | |
| 625 | 585 |
| 626 protected: | 586 protected: |
| 627 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate) { | 587 TimelineEventBlock* GetNewBlockLocked() { |
| 628 return NULL; | 588 return NULL; |
| 629 } | 589 } |
| 630 TimelineEventBlock* GetHeadBlockLocked() { | 590 TimelineEventBlock* GetHeadBlockLocked() { |
| 631 return NULL; | 591 return NULL; |
| 632 } | 592 } |
| 633 intptr_t NumDartEventsLocked(); | |
| 634 DartTimelineEvent* DartEventAtLocked(intptr_t i); | |
| 635 TimelineEvent* StartEvent(); | 593 TimelineEvent* StartEvent(); |
| 636 void CompleteEvent(TimelineEvent* event); | 594 void CompleteEvent(TimelineEvent* event); |
| 637 }; | 595 }; |
| 638 | 596 |
| 639 | 597 |
| 640 // A recorder that stores events in chains of blocks of events. | 598 // A recorder that stores events in chains of blocks of events. |
| 641 // NOTE: This recorder will continue to allocate blocks until it exhausts | 599 // NOTE: This recorder will continue to allocate blocks until it exhausts |
| 642 // memory. | 600 // memory. |
| 643 class TimelineEventEndlessRecorder : public TimelineEventRecorder { | 601 class TimelineEventEndlessRecorder : public TimelineEventRecorder { |
| 644 public: | 602 public: |
| 645 TimelineEventEndlessRecorder(); | 603 TimelineEventEndlessRecorder(); |
| 646 | 604 |
| 647 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); | 605 void PrintJSON(JSONStream* js, TimelineEventFilter* filter); |
| 648 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); | 606 void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter); |
| 649 | 607 |
| 650 void AppendDartEvent(Isolate* isolate, const char* event); | |
| 651 | |
| 652 protected: | 608 protected: |
| 653 TimelineEvent* StartEvent(); | 609 TimelineEvent* StartEvent(); |
| 654 void CompleteEvent(TimelineEvent* event); | 610 void CompleteEvent(TimelineEvent* event); |
| 655 TimelineEventBlock* GetNewBlockLocked(Isolate* isolate); | 611 TimelineEventBlock* GetNewBlockLocked(); |
| 656 TimelineEventBlock* GetHeadBlockLocked(); | 612 TimelineEventBlock* GetHeadBlockLocked(); |
| 657 intptr_t NumDartEventsLocked(); | |
| 658 DartTimelineEvent* DartEventAtLocked(intptr_t i); | |
| 659 | 613 |
| 660 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; | 614 void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter) const; |
| 661 | 615 |
| 662 // Useful only for testing. Only works for one thread. | 616 // Useful only for testing. Only works for one thread. |
| 663 void Clear(); | 617 void Clear(); |
| 664 | 618 |
| 665 TimelineEventBlock* head_; | 619 TimelineEventBlock* head_; |
| 666 intptr_t block_index_; | 620 intptr_t block_index_; |
| 667 | 621 |
| 668 DartTimelineEvent** dart_events_; | |
| 669 intptr_t dart_events_capacity_; | |
| 670 intptr_t dart_events_cursor_; | |
| 671 | |
| 672 friend class TimelineTestHelper; | 622 friend class TimelineTestHelper; |
| 673 }; | 623 }; |
| 674 | 624 |
| 675 | 625 |
| 676 // An iterator for blocks. | 626 // An iterator for blocks. |
| 677 class TimelineEventBlockIterator { | 627 class TimelineEventBlockIterator { |
| 678 public: | 628 public: |
| 679 explicit TimelineEventBlockIterator(TimelineEventRecorder* recorder); | 629 explicit TimelineEventBlockIterator(TimelineEventRecorder* recorder); |
| 680 ~TimelineEventBlockIterator(); | 630 ~TimelineEventBlockIterator(); |
| 681 | 631 |
| 682 void Reset(TimelineEventRecorder* recorder); | 632 void Reset(TimelineEventRecorder* recorder); |
| 683 | 633 |
| 684 // Returns false when there are no more blocks. | 634 // Returns false when there are no more blocks. |
| 685 bool HasNext() const; | 635 bool HasNext() const; |
| 686 | 636 |
| 687 // Returns the next block and moves forward. | 637 // Returns the next block and moves forward. |
| 688 TimelineEventBlock* Next(); | 638 TimelineEventBlock* Next(); |
| 689 | 639 |
| 690 private: | 640 private: |
| 691 TimelineEventBlock* current_; | 641 TimelineEventBlock* current_; |
| 692 TimelineEventRecorder* recorder_; | 642 TimelineEventRecorder* recorder_; |
| 693 }; | 643 }; |
| 694 | 644 |
| 695 | 645 |
| 696 // An iterator for timeline events. | |
| 697 class DartTimelineEventIterator { | |
| 698 public: | |
| 699 explicit DartTimelineEventIterator(TimelineEventRecorder* recorder); | |
| 700 ~DartTimelineEventIterator(); | |
| 701 | |
| 702 void Reset(TimelineEventRecorder* recorder); | |
| 703 | |
| 704 // Returns true if there is another event. | |
| 705 bool HasNext() const; | |
| 706 | |
| 707 // Returns the next event and moves forward. | |
| 708 DartTimelineEvent* Next(); | |
| 709 | |
| 710 // Returns a zone allocated string of all trace events for isolate. | |
| 711 // If isolate is NULL, all isolates' events will be included. | |
| 712 static const char* PrintTraceEvents(TimelineEventRecorder* recorder, | |
| 713 Zone* zone, | |
| 714 Isolate* isolate); | |
| 715 | |
| 716 private: | |
| 717 intptr_t cursor_; | |
| 718 intptr_t num_events_; | |
| 719 TimelineEventRecorder* recorder_; | |
| 720 }; | |
| 721 | |
| 722 } // namespace dart | 646 } // namespace dart |
| 723 | 647 |
| 724 #endif // VM_TIMELINE_H_ | 648 #endif // VM_TIMELINE_H_ |
| OLD | NEW |