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

Side by Side Diff: runtime/vm/timeline.cc

Issue 1411783004: More timeline cleanups (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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 | « runtime/vm/timeline.h ('k') | runtime/vm/timeline_analysis.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) 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 #include <cstdlib> 5 #include <cstdlib>
6 6
7 #include "vm/atomic.h" 7 #include "vm/atomic.h"
8 #include "vm/isolate.h" 8 #include "vm/isolate.h"
9 #include "vm/json_stream.h" 9 #include "vm/json_stream.h"
10 #include "vm/lockers.h" 10 #include "vm/lockers.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG 150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG
151 151
152 TimelineEvent::TimelineEvent() 152 TimelineEvent::TimelineEvent()
153 : timestamp0_(0), 153 : timestamp0_(0),
154 timestamp1_(0), 154 timestamp1_(0),
155 arguments_(NULL), 155 arguments_(NULL),
156 arguments_length_(0), 156 arguments_length_(0),
157 state_(0), 157 state_(0),
158 label_(NULL), 158 label_(NULL),
159 category_(""), 159 category_(""),
160 thread_(OSThread::kInvalidThreadId) { 160 thread_(OSThread::kInvalidThreadId),
161 isolate_id_(ILLEGAL_PORT) {
161 } 162 }
162 163
163 164
164 TimelineEvent::~TimelineEvent() { 165 TimelineEvent::~TimelineEvent() {
165 Reset(); 166 Reset();
166 } 167 }
167 168
168 169
169 void TimelineEvent::Reset() { 170 void TimelineEvent::Reset() {
170 set_event_type(kNone); 171 set_event_type(kNone);
171 thread_ = OSThread::kInvalidThreadId; 172 thread_ = OSThread::kInvalidThreadId;
172 isolate_ = NULL; 173 isolate_id_ = ILLEGAL_PORT;
173 category_ = ""; 174 category_ = "";
174 label_ = NULL; 175 label_ = NULL;
175 FreeArguments(); 176 FreeArguments();
176 } 177 }
177 178
178 179
179 void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) { 180 void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) {
180 Init(kAsyncBegin, label); 181 Init(kAsyncBegin, label);
181 timestamp0_ = OS::GetCurrentTraceMicros(); 182 timestamp0_ = OS::GetCurrentTraceMicros();
182 // Overload timestamp1_ with the async_id. 183 // Overload timestamp1_ with the async_id.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 } 236 }
236 237
237 238
238 void TimelineEvent::End(const char* label, 239 void TimelineEvent::End(const char* label,
239 int64_t micros) { 240 int64_t micros) {
240 Init(kEnd, label); 241 Init(kEnd, label);
241 timestamp0_ = micros; 242 timestamp0_ = micros;
242 } 243 }
243 244
244 245
246 void TimelineEvent::SerializedJSON(const char* json) {
247 Init(kSerializedJSON, "Dart");
248 SetNumArguments(1);
249 CopyArgument(0, "Dart", json);
250 }
251
252
245 void TimelineEvent::SetNumArguments(intptr_t length) { 253 void TimelineEvent::SetNumArguments(intptr_t length) {
246 // Cannot call this twice. 254 // Cannot call this twice.
247 ASSERT(arguments_ == NULL); 255 ASSERT(arguments_ == NULL);
248 ASSERT(arguments_length_ == 0); 256 ASSERT(arguments_length_ == 0);
249 if (length == 0) { 257 if (length == 0) {
250 return; 258 return;
251 } 259 }
252 arguments_length_ = length; 260 arguments_length_ = length;
253 arguments_ = reinterpret_cast<TimelineEventArgument*>( 261 arguments_ = reinterpret_cast<TimelineEventArgument*>(
254 calloc(sizeof(TimelineEventArgument), length)); 262 calloc(sizeof(TimelineEventArgument), length));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 } 334 }
327 335
328 336
329 void TimelineEvent::Init(EventType event_type, 337 void TimelineEvent::Init(EventType event_type,
330 const char* label) { 338 const char* label) {
331 ASSERT(label != NULL); 339 ASSERT(label != NULL);
332 set_event_type(event_type); 340 set_event_type(event_type);
333 timestamp0_ = 0; 341 timestamp0_ = 0;
334 timestamp1_ = 0; 342 timestamp1_ = 0;
335 thread_ = OSThread::GetCurrentThreadTraceId(); 343 thread_ = OSThread::GetCurrentThreadTraceId();
336 isolate_ = Isolate::Current(); 344 Isolate* isolate = Isolate::Current();
345 if (isolate != NULL) {
346 isolate_id_ = isolate->main_port();
347 } else {
348 isolate_id_ = ILLEGAL_PORT;
349 }
337 label_ = label; 350 label_ = label;
338 FreeArguments(); 351 FreeArguments();
339 } 352 }
340 353
341 354
355 const char* TimelineEvent::GetSerializedJSON() const {
356 ASSERT(event_type() == kSerializedJSON);
357 ASSERT(arguments_length_ == 1);
358 ASSERT(arguments_ != NULL);
359 return arguments_[0].value;
360 }
361
362
342 void TimelineEvent::PrintJSON(JSONStream* stream) const { 363 void TimelineEvent::PrintJSON(JSONStream* stream) const {
364 if (event_type() == kSerializedJSON) {
365 // Event has already been serialized into JSON- just append the
366 // raw data.
367 stream->AppendSerializedObject(GetSerializedJSON());
368 return;
369 }
343 JSONObject obj(stream); 370 JSONObject obj(stream);
344 int64_t pid = OS::ProcessId(); 371 int64_t pid = OS::ProcessId();
345 int64_t tid = OSThread::ThreadIdToIntPtr(thread_); 372 int64_t tid = OSThread::ThreadIdToIntPtr(thread_);
346 obj.AddProperty("name", label_); 373 obj.AddProperty("name", label_);
347 obj.AddProperty("cat", category_); 374 obj.AddProperty("cat", category_);
348 obj.AddProperty64("tid", tid); 375 obj.AddProperty64("tid", tid);
349 obj.AddProperty64("pid", pid); 376 obj.AddProperty64("pid", pid);
350 obj.AddPropertyTimeMicros("ts", TimeOrigin()); 377 obj.AddPropertyTimeMicros("ts", TimeOrigin());
351 378
352 switch (event_type()) { 379 switch (event_type()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 break; 412 break;
386 default: 413 default:
387 UNIMPLEMENTED(); 414 UNIMPLEMENTED();
388 } 415 }
389 { 416 {
390 JSONObject args(&obj, "args"); 417 JSONObject args(&obj, "args");
391 for (intptr_t i = 0; i < arguments_length_; i++) { 418 for (intptr_t i = 0; i < arguments_length_; i++) {
392 const TimelineEventArgument& arg = arguments_[i]; 419 const TimelineEventArgument& arg = arguments_[i];
393 args.AddProperty(arg.name, arg.value); 420 args.AddProperty(arg.name, arg.value);
394 } 421 }
422 if (isolate_id_ != ILLEGAL_PORT) {
423 // If we have one, append the isolate id.
424 args.AddProperty("isolateNumber", isolate_id_);
425 }
395 } 426 }
396 } 427 }
397 428
398 429
399 int64_t TimelineEvent::TimeOrigin() const { 430 int64_t TimelineEvent::TimeOrigin() const {
400 return timestamp0_; 431 return timestamp0_;
401 } 432 }
402 433
403 434
404 int64_t TimelineEvent::AsyncId() const { 435 int64_t TimelineEvent::AsyncId() const {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 612
582 613
583 TimelineEventFilter::TimelineEventFilter() { 614 TimelineEventFilter::TimelineEventFilter() {
584 } 615 }
585 616
586 617
587 TimelineEventFilter::~TimelineEventFilter() { 618 TimelineEventFilter::~TimelineEventFilter() {
588 } 619 }
589 620
590 621
591 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate) 622 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Dart_Port isolate_id)
592 : isolate_(isolate) { 623 : isolate_id_(isolate_id) {
593 } 624 }
594 625
595 626
596 DartTimelineEvent::DartTimelineEvent()
597 : isolate_(NULL),
598 event_as_json_(NULL) {
599 }
600
601
602 DartTimelineEvent::~DartTimelineEvent() {
603 Clear();
604 }
605
606
607 void DartTimelineEvent::Clear() {
608 if (isolate_ != NULL) {
609 isolate_ = NULL;
610 }
611 if (event_as_json_ != NULL) {
612 free(event_as_json_);
613 event_as_json_ = NULL;
614 }
615 }
616
617
618 void DartTimelineEvent::Init(Isolate* isolate, const char* event) {
619 ASSERT(isolate_ == NULL);
620 ASSERT(event != NULL);
621 isolate_ = isolate;
622 event_as_json_ = strdup(event);
623 }
624
625
626 TimelineEventRecorder::TimelineEventRecorder() 627 TimelineEventRecorder::TimelineEventRecorder()
627 : async_id_(0) { 628 : async_id_(0) {
628 } 629 }
629 630
630 631
631 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { 632 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
632 } 633 }
633 634
634 635
635 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { 636 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
636 // Grab the current thread. 637 // Grab the current thread.
637 Thread* thread = Thread::Current(); 638 Thread* thread = Thread::Current();
638 ASSERT(thread != NULL); 639 ASSERT(thread != NULL);
639 ASSERT(thread->isolate() != NULL);
640 Mutex* thread_block_lock = thread->timeline_block_lock(); 640 Mutex* thread_block_lock = thread->timeline_block_lock();
641 ASSERT(thread_block_lock != NULL); 641 ASSERT(thread_block_lock != NULL);
642 // We are accessing the thread's timeline block- so take the lock here. 642 // We are accessing the thread's timeline block- so take the lock here.
643 // This lock will be held until the call to |CompleteEvent| is made. 643 // This lock will be held until the call to |CompleteEvent| is made.
644 thread_block_lock->Lock(); 644 thread_block_lock->Lock();
645 645
646 TimelineEventBlock* thread_block = thread->timeline_block(); 646 TimelineEventBlock* thread_block = thread->timeline_block();
647 647
648 if ((thread_block != NULL) && thread_block->IsFull()) { 648 if ((thread_block != NULL) && thread_block->IsFull()) {
649 MutexLocker ml(&lock_); 649 MutexLocker ml(&lock_);
650 // Thread has a block and it is full: 650 // Thread has a block and it is full:
651 // 1) Mark it as finished. 651 // 1) Mark it as finished.
652 thread_block->Finish(); 652 thread_block->Finish();
653 // 2) Allocate a new block. 653 // 2) Allocate a new block.
654 thread_block = GetNewBlockLocked(thread->isolate()); 654 thread_block = GetNewBlockLocked();
655 thread->set_timeline_block(thread_block); 655 thread->set_timeline_block(thread_block);
656 } else if (thread_block == NULL) { 656 } else if (thread_block == NULL) {
657 MutexLocker ml(&lock_); 657 MutexLocker ml(&lock_);
658 // Thread has no block. Attempt to allocate one. 658 // Thread has no block. Attempt to allocate one.
659 thread_block = GetNewBlockLocked(thread->isolate()); 659 thread_block = GetNewBlockLocked();
660 thread->set_timeline_block(thread_block); 660 thread->set_timeline_block(thread_block);
661 } 661 }
662 if (thread_block != NULL) { 662 if (thread_block != NULL) {
663 // NOTE: We are exiting this function with the thread's block lock held. 663 // NOTE: We are exiting this function with the thread's block lock held.
664 ASSERT(!thread_block->IsFull()); 664 ASSERT(!thread_block->IsFull());
665 TimelineEvent* event = thread_block->StartEvent(); 665 TimelineEvent* event = thread_block->StartEvent();
666 return event; 666 return event;
667 } 667 }
668 // Drop lock here as no event is being handed out. 668 // Drop lock here as no event is being handed out.
669 thread_block_lock->Unlock(); 669 thread_block_lock->Unlock();
670 return NULL; 670 return NULL;
671 } 671 }
672 672
673 673
674 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { 674 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) {
675 if (event == NULL) { 675 if (event == NULL) {
676 return; 676 return;
677 } 677 }
678 // Grab the current thread. 678 // Grab the current thread.
679 Thread* thread = Thread::Current(); 679 Thread* thread = Thread::Current();
680 ASSERT(thread != NULL); 680 ASSERT(thread != NULL);
681 // Unlock the thread's block lock. 681 // Unlock the thread's block lock.
682 Mutex* thread_block_lock = thread->timeline_block_lock(); 682 Mutex* thread_block_lock = thread->timeline_block_lock();
683 ASSERT(thread_block_lock != NULL); 683 ASSERT(thread_block_lock != NULL);
684 thread_block_lock->Unlock(); 684 thread_block_lock->Unlock();
685 } 685 }
686 686
687 687
688 // Trims the ']' character.
689 static void TrimOutput(char* output,
690 intptr_t* output_length) {
691 ASSERT(output != NULL);
692 ASSERT(output_length != NULL);
693 ASSERT(*output_length >= 2);
694 // We expect the first character to be the opening of an array.
695 ASSERT(output[0] == '[');
696 // We expect the last character to be the closing of an array.
697 ASSERT(output[*output_length - 1] == ']');
698 // Skip the ].
699 *output_length -= 1;
700 }
701
702
703 void TimelineEventRecorder::WriteTo(const char* directory) { 688 void TimelineEventRecorder::WriteTo(const char* directory) {
704 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); 689 Dart_FileOpenCallback file_open = Isolate::file_open_callback();
705 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); 690 Dart_FileWriteCallback file_write = Isolate::file_write_callback();
706 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); 691 Dart_FileCloseCallback file_close = Isolate::file_close_callback();
707 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { 692 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
708 return; 693 return;
709 } 694 }
710 Thread* T = Thread::Current(); 695 Thread* T = Thread::Current();
711 StackZone zone(T); 696 StackZone zone(T);
712 697
(...skipping 10 matching lines...) Expand all
723 } 708 }
724 free(filename); 709 free(filename);
725 710
726 JSONStream js; 711 JSONStream js;
727 TimelineEventFilter filter; 712 TimelineEventFilter filter;
728 PrintTraceEvent(&js, &filter); 713 PrintTraceEvent(&js, &filter);
729 // Steal output from JSONStream. 714 // Steal output from JSONStream.
730 char* output = NULL; 715 char* output = NULL;
731 intptr_t output_length = 0; 716 intptr_t output_length = 0;
732 js.Steal(const_cast<const char**>(&output), &output_length); 717 js.Steal(const_cast<const char**>(&output), &output_length);
733 TrimOutput(output, &output_length);
734 ASSERT(output_length >= 1);
735 (*file_write)(output, output_length, file); 718 (*file_write)(output, output_length, file);
736 // Free the stolen output. 719 // Free the stolen output.
737 free(output); 720 free(output);
738
739 const char* dart_events =
740 DartTimelineEventIterator::PrintTraceEvents(this,
741 zone.GetZone(),
742 NULL);
743
744 // If we wrote out vm events and have dart events, write out the comma.
745 if ((output_length > 1) && (dart_events != NULL)) {
746 // Write out the ',' character.
747 const char* comma = ",";
748 (*file_write)(comma, 1, file);
749 }
750
751 // Write out the Dart events.
752 if (dart_events != NULL) {
753 (*file_write)(dart_events, strlen(dart_events), file);
754 }
755
756 // Write out the ']' character.
757 const char* array_close = "]";
758 (*file_write)(array_close, 1, file);
759 (*file_close)(file); 721 (*file_close)(file);
760 722
761 return; 723 return;
762 } 724 }
763 725
764 726
765 int64_t TimelineEventRecorder::GetNextAsyncId() { 727 int64_t TimelineEventRecorder::GetNextAsyncId() {
766 // TODO(johnmccutchan): Gracefully handle wrap around. 728 // TODO(johnmccutchan): Gracefully handle wrap around.
767 uint32_t next = static_cast<uint32_t>( 729 uint32_t next = static_cast<uint32_t>(
768 AtomicOperations::FetchAndIncrement(&async_id_)); 730 AtomicOperations::FetchAndIncrement(&async_id_));
769 return static_cast<int64_t>(next); 731 return static_cast<int64_t>(next);
770 } 732 }
771 733
772 734
773 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { 735 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) {
774 if (block == NULL) { 736 if (block == NULL) {
775 return; 737 return;
776 } 738 }
777 MutexLocker ml(&lock_); 739 MutexLocker ml(&lock_);
778 block->Finish(); 740 block->Finish();
779 } 741 }
780 742
781 743
782 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { 744 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() {
783 MutexLocker ml(&lock_); 745 MutexLocker ml(&lock_);
784 return GetNewBlockLocked(Isolate::Current()); 746 return GetNewBlockLocked();
785 } 747 }
786 748
787 749
788 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) 750 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity)
789 : blocks_(NULL), 751 : blocks_(NULL),
790 capacity_(capacity), 752 capacity_(capacity),
791 num_blocks_(0), 753 num_blocks_(0),
792 block_cursor_(0), 754 block_cursor_(0) {
793 dart_events_(NULL),
794 dart_events_capacity_(capacity),
795 dart_events_cursor_(0) {
796 // Capacity must be a multiple of TimelineEventBlock::kBlockSize 755 // Capacity must be a multiple of TimelineEventBlock::kBlockSize
797 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); 756 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0);
798 // Allocate blocks array. 757 // Allocate blocks array.
799 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; 758 num_blocks_ = capacity / TimelineEventBlock::kBlockSize;
800 blocks_ = 759 blocks_ =
801 reinterpret_cast<TimelineEventBlock**>( 760 reinterpret_cast<TimelineEventBlock**>(
802 calloc(num_blocks_, sizeof(TimelineEventBlock*))); 761 calloc(num_blocks_, sizeof(TimelineEventBlock*)));
803 // Allocate each block. 762 // Allocate each block.
804 for (intptr_t i = 0; i < num_blocks_; i++) { 763 for (intptr_t i = 0; i < num_blocks_; i++) {
805 blocks_[i] = new TimelineEventBlock(i); 764 blocks_[i] = new TimelineEventBlock(i);
806 } 765 }
807 // Chain blocks together. 766 // Chain blocks together.
808 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { 767 for (intptr_t i = 0; i < num_blocks_ - 1; i++) {
809 blocks_[i]->set_next(blocks_[i + 1]); 768 blocks_[i]->set_next(blocks_[i + 1]);
810 } 769 }
811 // Pre-allocate DartTimelineEvents.
812 dart_events_ =
813 reinterpret_cast<DartTimelineEvent**>(
814 calloc(dart_events_capacity_, sizeof(DartTimelineEvent*)));
815 for (intptr_t i = 0; i < dart_events_capacity_; i++) {
816 dart_events_[i] = new DartTimelineEvent();
817 }
818 } 770 }
819 771
820 772
821 TimelineEventRingRecorder::~TimelineEventRingRecorder() { 773 TimelineEventRingRecorder::~TimelineEventRingRecorder() {
822 // Delete all blocks. 774 // Delete all blocks.
823 for (intptr_t i = 0; i < num_blocks_; i++) { 775 for (intptr_t i = 0; i < num_blocks_; i++) {
824 TimelineEventBlock* block = blocks_[i]; 776 TimelineEventBlock* block = blocks_[i];
825 delete block; 777 delete block;
826 } 778 }
827 free(blocks_); 779 free(blocks_);
828 // Delete all DartTimelineEvents.
829 for (intptr_t i = 0; i < dart_events_capacity_; i++) {
830 DartTimelineEvent* event = dart_events_[i];
831 delete event;
832 }
833 free(dart_events_);
834 } 780 }
835 781
836 782
837 void TimelineEventRingRecorder::PrintJSONEvents( 783 void TimelineEventRingRecorder::PrintJSONEvents(
838 JSONArray* events, 784 JSONArray* events,
839 TimelineEventFilter* filter) const { 785 TimelineEventFilter* filter) const {
840 intptr_t block_offset = FindOldestBlockIndex(); 786 intptr_t block_offset = FindOldestBlockIndex();
841 if (block_offset == -1) { 787 if (block_offset == -1) {
842 // All blocks are empty. 788 // All blocks are empty.
843 return; 789 return;
(...skipping 20 matching lines...) Expand all
864 JSONObject topLevel(js); 810 JSONObject topLevel(js);
865 topLevel.AddProperty("type", "_Timeline"); 811 topLevel.AddProperty("type", "_Timeline");
866 { 812 {
867 JSONArray events(&topLevel, "traceEvents"); 813 JSONArray events(&topLevel, "traceEvents");
868 PrintJSONMeta(&events); 814 PrintJSONMeta(&events);
869 PrintJSONEvents(&events, filter); 815 PrintJSONEvents(&events, filter);
870 } 816 }
871 } 817 }
872 818
873 819
874 void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate,
875 const char* event) {
876 MutexLocker ml(&lock_);
877 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
878 // the events.
879 if (dart_events_cursor_ == dart_events_capacity_) {
880 dart_events_cursor_ = 0;
881 }
882 ASSERT(dart_events_[dart_events_cursor_] != NULL);
883 dart_events_[dart_events_cursor_]->Clear();
884 dart_events_[dart_events_cursor_]->Init(isolate, event);
885 dart_events_cursor_++;
886 }
887
888
889 intptr_t TimelineEventRingRecorder::NumDartEventsLocked() {
890 return dart_events_capacity_;
891 }
892
893
894 DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) {
895 ASSERT(i >= 0);
896 ASSERT(i < dart_events_capacity_);
897 return dart_events_[i];
898 }
899
900
901 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, 820 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js,
902 TimelineEventFilter* filter) { 821 TimelineEventFilter* filter) {
903 JSONArray events(js); 822 JSONArray events(js);
904 PrintJSONEvents(&events, filter); 823 PrintJSONEvents(&events, filter);
905 } 824 }
906 825
907 826
908 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { 827 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() {
909 return blocks_[0]; 828 return blocks_[0];
910 } 829 }
911 830
912 831
913 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked( 832 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() {
914 Isolate* isolate) {
915 // TODO(johnmccutchan): This function should only hand out blocks 833 // TODO(johnmccutchan): This function should only hand out blocks
916 // which have been marked as finished. 834 // which have been marked as finished.
917 if (block_cursor_ == num_blocks_) { 835 if (block_cursor_ == num_blocks_) {
918 block_cursor_ = 0; 836 block_cursor_ = 0;
919 } 837 }
920 TimelineEventBlock* block = blocks_[block_cursor_++]; 838 TimelineEventBlock* block = blocks_[block_cursor_++];
921 block->Reset(); 839 block->Reset();
922 block->Open(isolate); 840 block->Open();
923 return block; 841 return block;
924 } 842 }
925 843
926 844
927 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const { 845 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const {
928 int64_t earliest_time = kMaxInt64; 846 int64_t earliest_time = kMaxInt64;
929 intptr_t earliest_index = -1; 847 intptr_t earliest_index = -1;
930 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { 848 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) {
931 TimelineEventBlock* block = blocks_[block_idx]; 849 TimelineEventBlock* block = blocks_[block_idx];
932 if (block->IsEmpty()) { 850 if (block->IsEmpty()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 } 895 }
978 896
979 897
980 void TimelineEventStreamingRecorder::PrintTraceEvent( 898 void TimelineEventStreamingRecorder::PrintTraceEvent(
981 JSONStream* js, 899 JSONStream* js,
982 TimelineEventFilter* filter) { 900 TimelineEventFilter* filter) {
983 JSONArray events(js); 901 JSONArray events(js);
984 } 902 }
985 903
986 904
987 void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate,
988 const char* event) {
989 if (event != NULL) {
990 StreamDartEvent(event);
991 }
992 }
993
994
995 intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() {
996 return 0;
997 }
998
999
1000 DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked(
1001 intptr_t i) {
1002 return NULL;
1003 }
1004
1005
1006 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { 905 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() {
1007 TimelineEvent* event = new TimelineEvent(); 906 TimelineEvent* event = new TimelineEvent();
1008 return event; 907 return event;
1009 } 908 }
1010 909
1011 910
1012 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { 911 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) {
1013 StreamEvent(event); 912 StreamEvent(event);
1014 delete event; 913 delete event;
1015 } 914 }
1016 915
1017 916
1018 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() 917 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
1019 : head_(NULL), 918 : head_(NULL),
1020 block_index_(0), 919 block_index_(0) {
1021 dart_events_(NULL),
1022 dart_events_capacity_(0),
1023 dart_events_cursor_(0) {
1024 } 920 }
1025 921
1026 922
1027 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, 923 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
1028 TimelineEventFilter* filter) { 924 TimelineEventFilter* filter) {
1029 MutexLocker ml(&lock_); 925 MutexLocker ml(&lock_);
1030 JSONObject topLevel(js); 926 JSONObject topLevel(js);
1031 topLevel.AddProperty("type", "_Timeline"); 927 topLevel.AddProperty("type", "_Timeline");
1032 { 928 {
1033 JSONArray events(&topLevel, "traceEvents"); 929 JSONArray events(&topLevel, "traceEvents");
1034 PrintJSONMeta(&events); 930 PrintJSONMeta(&events);
1035 PrintJSONEvents(&events, filter); 931 PrintJSONEvents(&events, filter);
1036 } 932 }
1037 } 933 }
1038 934
1039 935
1040 void TimelineEventEndlessRecorder::PrintTraceEvent( 936 void TimelineEventEndlessRecorder::PrintTraceEvent(
1041 JSONStream* js, 937 JSONStream* js,
1042 TimelineEventFilter* filter) { 938 TimelineEventFilter* filter) {
1043 JSONArray events(js); 939 JSONArray events(js);
1044 PrintJSONEvents(&events, filter); 940 PrintJSONEvents(&events, filter);
1045 } 941 }
1046 942
1047 943
1048 void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate,
1049 const char* event) {
1050 MutexLocker ml(&lock_);
1051 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
1052 // the events.
1053 if (dart_events_cursor_ == dart_events_capacity_) {
1054 // Grow.
1055 intptr_t new_capacity =
1056 (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2;
1057 dart_events_ = reinterpret_cast<DartTimelineEvent**>(
1058 realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*)));
1059 for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) {
1060 // Fill with NULLs.
1061 dart_events_[i] = NULL;
1062 }
1063 dart_events_capacity_ = new_capacity;
1064 }
1065 ASSERT(dart_events_cursor_ < dart_events_capacity_);
1066 DartTimelineEvent* dart_event = new DartTimelineEvent();
1067 dart_event->Init(isolate, event);
1068 ASSERT(dart_events_[dart_events_cursor_] == NULL);
1069 dart_events_[dart_events_cursor_++] = dart_event;
1070 }
1071
1072
1073 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { 944 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
1074 return head_; 945 return head_;
1075 } 946 }
1076 947
1077 948
1078 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { 949 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() {
1079 // Grab the current thread. 950 // Grab the current thread.
1080 Thread* thread = Thread::Current(); 951 Thread* thread = Thread::Current();
1081 ASSERT(thread != NULL); 952 ASSERT(thread != NULL);
1082 return ThreadBlockStartEvent(); 953 return ThreadBlockStartEvent();
1083 } 954 }
1084 955
1085 956
1086 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { 957 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) {
1087 if (event == NULL) { 958 if (event == NULL) {
1088 return; 959 return;
1089 } 960 }
1090 ThreadBlockCompleteEvent(event); 961 ThreadBlockCompleteEvent(event);
1091 } 962 }
1092 963
1093 964
1094 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked( 965 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() {
1095 Isolate* isolate) {
1096 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); 966 TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
1097 block->set_next(head_); 967 block->set_next(head_);
1098 block->Open(isolate); 968 block->Open();
1099 head_ = block; 969 head_ = block;
1100 if (FLAG_trace_timeline) { 970 if (FLAG_trace_timeline) {
1101 if (isolate != NULL) { 971 OS::Print("Created new block %p\n", block);
1102 OS::Print("Created new isolate block %p for %s\n",
1103 block, isolate->name());
1104 } else {
1105 OS::Print("Created new global block %p\n", block);
1106 }
1107 } 972 }
1108 return head_; 973 return head_;
1109 } 974 }
1110 975
1111 976
1112 intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() {
1113 return dart_events_cursor_;
1114 }
1115
1116
1117 DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked(
1118 intptr_t i) {
1119 ASSERT(i >= 0);
1120 ASSERT(i < dart_events_cursor_);
1121 return dart_events_[i];
1122 }
1123
1124
1125 void TimelineEventEndlessRecorder::PrintJSONEvents( 977 void TimelineEventEndlessRecorder::PrintJSONEvents(
1126 JSONArray* events, 978 JSONArray* events,
1127 TimelineEventFilter* filter) const { 979 TimelineEventFilter* filter) const {
1128 TimelineEventBlock* current = head_; 980 TimelineEventBlock* current = head_;
1129 981
1130 while (current != NULL) { 982 while (current != NULL) {
1131 if (!filter->IncludeBlock(current)) { 983 if (!filter->IncludeBlock(current)) {
1132 current = current->next(); 984 current = current->next();
1133 continue; 985 continue;
1134 } 986 }
(...skipping 21 matching lines...) Expand all
1156 block_index_ = 0; 1008 block_index_ = 0;
1157 Thread* thread = Thread::Current(); 1009 Thread* thread = Thread::Current();
1158 thread->set_timeline_block(NULL); 1010 thread->set_timeline_block(NULL);
1159 } 1011 }
1160 1012
1161 1013
1162 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) 1014 TimelineEventBlock::TimelineEventBlock(intptr_t block_index)
1163 : next_(NULL), 1015 : next_(NULL),
1164 length_(0), 1016 length_(0),
1165 block_index_(block_index), 1017 block_index_(block_index),
1166 isolate_(NULL), 1018 thread_id_(OSThread::kInvalidThreadId),
1167 in_use_(false) { 1019 in_use_(false) {
1168 } 1020 }
1169 1021
1170 1022
1171 TimelineEventBlock::~TimelineEventBlock() { 1023 TimelineEventBlock::~TimelineEventBlock() {
1172 Reset(); 1024 Reset();
1173 } 1025 }
1174 1026
1175 1027
1176 TimelineEvent* TimelineEventBlock::StartEvent() { 1028 TimelineEvent* TimelineEventBlock::StartEvent() {
1177 ASSERT(!IsFull()); 1029 ASSERT(!IsFull());
1178 if (FLAG_trace_timeline) { 1030 if (FLAG_trace_timeline) {
1179 OS::Print("StartEvent in block %p for thread %" Px "\n", 1031 OS::Print("StartEvent in block %p for thread %" Px "\n",
1180 this, OSThread::CurrentCurrentThreadIdAsIntPtr()); 1032 this, OSThread::CurrentCurrentThreadIdAsIntPtr());
1181 } 1033 }
1182 return &events_[length_++]; 1034 return &events_[length_++];
1183 } 1035 }
1184 1036
1185 1037
1186 ThreadId TimelineEventBlock::thread() const {
1187 ASSERT(length_ > 0);
1188 return events_[0].thread();
1189 }
1190
1191
1192 int64_t TimelineEventBlock::LowerTimeBound() const { 1038 int64_t TimelineEventBlock::LowerTimeBound() const {
1039 if (length_ == 0) {
1040 return kMaxInt64;
1041 }
1193 ASSERT(length_ > 0); 1042 ASSERT(length_ > 0);
1194 return events_[0].TimeOrigin(); 1043 return events_[0].TimeOrigin();
1195 } 1044 }
1196 1045
1197 1046
1198 bool TimelineEventBlock::CheckBlock() { 1047 bool TimelineEventBlock::CheckBlock() {
1199 if (length() == 0) { 1048 if (length() == 0) {
1200 return true; 1049 return true;
1201 } 1050 }
1202 1051
1203 // - events in the block come from one thread.
1204 ThreadId tid = thread();
1205 for (intptr_t i = 0; i < length(); i++) { 1052 for (intptr_t i = 0; i < length(); i++) {
1206 if (At(i)->thread() != tid) { 1053 if (At(i)->thread() != thread_id()) {
1207 return false; 1054 return false;
1208 } 1055 }
1209 } 1056 }
1210 1057
1211 // - events have monotonically increasing timestamps. 1058 // - events have monotonically increasing timestamps.
1212 int64_t last_time = LowerTimeBound(); 1059 int64_t last_time = LowerTimeBound();
1213 for (intptr_t i = 0; i < length(); i++) { 1060 for (intptr_t i = 0; i < length(); i++) {
1214 if (last_time > At(i)->TimeOrigin()) { 1061 if (last_time > At(i)->TimeOrigin()) {
1215 return false; 1062 return false;
1216 } 1063 }
1217 last_time = At(i)->TimeOrigin(); 1064 last_time = At(i)->TimeOrigin();
1218 } 1065 }
1219 1066
1220 return true; 1067 return true;
1221 } 1068 }
1222 1069
1223 1070
1224 void TimelineEventBlock::Reset() { 1071 void TimelineEventBlock::Reset() {
1225 for (intptr_t i = 0; i < kBlockSize; i++) { 1072 for (intptr_t i = 0; i < kBlockSize; i++) {
1226 // Clear any extra data. 1073 // Clear any extra data.
1227 events_[i].Reset(); 1074 events_[i].Reset();
1228 } 1075 }
1229 length_ = 0; 1076 length_ = 0;
1230 isolate_ = NULL; 1077 thread_id_ = OSThread::kInvalidThreadId;
1231 in_use_ = false; 1078 in_use_ = false;
1232 } 1079 }
1233 1080
1234 1081
1235 void TimelineEventBlock::Open(Isolate* isolate) { 1082 void TimelineEventBlock::Open() {
1236 isolate_ = isolate; 1083 thread_id_ = OSThread::GetCurrentThreadTraceId();
1237 in_use_ = true; 1084 in_use_ = true;
1238 } 1085 }
1239 1086
1240 1087
1241 void TimelineEventBlock::Finish() { 1088 void TimelineEventBlock::Finish() {
1242 if (FLAG_trace_timeline) { 1089 if (FLAG_trace_timeline) {
1243 OS::Print("Finish block %p\n", this); 1090 OS::Print("Finish block %p\n", this);
1244 } 1091 }
1245 in_use_ = false; 1092 in_use_ = false;
1246 } 1093 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 } 1129 }
1283 1130
1284 1131
1285 TimelineEventBlock* TimelineEventBlockIterator::Next() { 1132 TimelineEventBlock* TimelineEventBlockIterator::Next() {
1286 ASSERT(current_ != NULL); 1133 ASSERT(current_ != NULL);
1287 TimelineEventBlock* r = current_; 1134 TimelineEventBlock* r = current_;
1288 current_ = current_->next(); 1135 current_ = current_->next();
1289 return r; 1136 return r;
1290 } 1137 }
1291 1138
1292
1293 DartTimelineEventIterator::DartTimelineEventIterator(
1294 TimelineEventRecorder* recorder)
1295 : cursor_(0),
1296 num_events_(0),
1297 recorder_(NULL) {
1298 Reset(recorder);
1299 }
1300
1301
1302 DartTimelineEventIterator::~DartTimelineEventIterator() {
1303 Reset(NULL);
1304 }
1305
1306
1307 void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) {
1308 // Clear state.
1309 cursor_ = 0;
1310 num_events_ = 0;
1311 if (recorder_ != NULL) {
1312 // Unlock old recorder.
1313 recorder_->lock_.Unlock();
1314 }
1315 recorder_ = recorder;
1316 if (recorder_ == NULL) {
1317 return;
1318 }
1319 // Lock new recorder.
1320 recorder_->lock_.Lock();
1321 cursor_ = 0;
1322 num_events_ = recorder_->NumDartEventsLocked();
1323 }
1324
1325
1326 bool DartTimelineEventIterator::HasNext() const {
1327 return cursor_ < num_events_;
1328 }
1329
1330
1331 DartTimelineEvent* DartTimelineEventIterator::Next() {
1332 ASSERT(cursor_ < num_events_);
1333 DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_);
1334 cursor_++;
1335 return r;
1336 }
1337
1338 const char* DartTimelineEventIterator::PrintTraceEvents(
1339 TimelineEventRecorder* recorder,
1340 Zone* zone,
1341 Isolate* isolate) {
1342 if (recorder == NULL) {
1343 return NULL;
1344 }
1345
1346 if (zone == NULL) {
1347 return NULL;
1348 }
1349
1350 char* result = NULL;
1351 DartTimelineEventIterator iterator(recorder);
1352 while (iterator.HasNext()) {
1353 DartTimelineEvent* event = iterator.Next();
1354 if (!event->IsValid()) {
1355 // Skip invalid
1356 continue;
1357 }
1358 if ((isolate != NULL) && (isolate != event->isolate())) {
1359 // If an isolate was specified, skip events from other isolates.
1360 continue;
1361 }
1362 ASSERT(event->event_as_json() != NULL);
1363 result = zone->ConcatStrings(result, event->event_as_json());
1364 }
1365 return result;
1366 }
1367
1368 } // namespace dart 1139 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/timeline.h ('k') | runtime/vm/timeline_analysis.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698