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

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

Issue 1406413006: Timeline service protocol support with Observatory UI (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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') | no next file » | 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; 77 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
78 if (use_endless_recorder) { 78 if (use_endless_recorder) {
79 recorder_ = new TimelineEventEndlessRecorder(); 79 recorder_ = new TimelineEventEndlessRecorder();
80 } else if (use_ring_recorder) { 80 } else if (use_ring_recorder) {
81 recorder_ = new TimelineEventRingRecorder(); 81 recorder_ = new TimelineEventRingRecorder();
82 } 82 }
83 vm_stream_ = new TimelineStream(); 83 vm_stream_ = new TimelineStream();
84 vm_stream_->Init("VM", EnableStreamByDefault("VM"), NULL); 84 vm_stream_->Init("VM", EnableStreamByDefault("VM"), NULL);
85 // Global overrides. 85 // Global overrides.
86 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ 86 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \
87 stream_##name##_enabled_ = false; 87 stream_##name##_enabled_ = EnableStreamByDefault(#name);
88 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT) 88 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT)
89 #undef ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT 89 #undef ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT
90 } 90 }
91 91
92 92
93 void Timeline::Shutdown() { 93 void Timeline::Shutdown() {
94 ASSERT(recorder_ != NULL); 94 ASSERT(recorder_ != NULL);
95 if (FLAG_timeline_dir != NULL) { 95 if (FLAG_timeline_dir != NULL) {
96 recorder_->WriteTo(FLAG_timeline_dir); 96 recorder_->WriteTo(FLAG_timeline_dir);
97 } 97 }
98 delete recorder_; 98 delete recorder_;
99 recorder_ = NULL; 99 recorder_ = NULL;
100 delete vm_stream_; 100 delete vm_stream_;
101 vm_stream_ = NULL; 101 vm_stream_ = NULL;
102 } 102 }
103 103
104 104
105 TimelineEventRecorder* Timeline::recorder() { 105 TimelineEventRecorder* Timeline::recorder() {
106 return recorder_; 106 return recorder_;
107 } 107 }
108 108
109 109
110 bool Timeline::EnableStreamByDefault(const char* stream_name) { 110 bool Timeline::EnableStreamByDefault(const char* stream_name) {
111 // TODO(johnmccutchan): Allow for command line control over streams. 111 // TODO(johnmccutchan): Allow for command line control over streams.
112 return (FLAG_timeline_dir != NULL) || FLAG_timing; 112 return (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline;
113 } 113 }
114 114
115 115
116 TimelineStream* Timeline::GetVMStream() { 116 TimelineStream* Timeline::GetVMStream() {
117 ASSERT(vm_stream_ != NULL); 117 ASSERT(vm_stream_ != NULL);
118 return vm_stream_; 118 return vm_stream_;
119 } 119 }
120 120
121 121
122 void Timeline::ReclaimCachedBlocksFromThreads() { 122 void Timeline::ReclaimCachedBlocksFromThreads() {
(...skipping 11 matching lines...) Expand all
134 TimelineEventBlock* block = thread->timeline_block(); 134 TimelineEventBlock* block = thread->timeline_block();
135 thread->set_timeline_block(NULL); 135 thread->set_timeline_block(NULL);
136 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here 136 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here
137 // if we can do it everywhere. This would simplify the lock ordering 137 // if we can do it everywhere. This would simplify the lock ordering
138 // requirements. 138 // requirements.
139 recorder->FinishBlock(block); 139 recorder->FinishBlock(block);
140 } 140 }
141 } 141 }
142 142
143 143
144 void Timeline::Clear() {
145 TimelineEventRecorder* recorder = Timeline::recorder();
146 if (recorder == NULL) {
147 return;
148 }
149 ReclaimCachedBlocksFromThreads();
150 recorder->Clear();
151 }
152
153
144 TimelineEventRecorder* Timeline::recorder_ = NULL; 154 TimelineEventRecorder* Timeline::recorder_ = NULL;
145 TimelineStream* Timeline::vm_stream_ = NULL; 155 TimelineStream* Timeline::vm_stream_ = NULL;
146 156
147 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \ 157 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \
148 bool Timeline::stream_##name##_enabled_ = false; 158 bool Timeline::stream_##name##_enabled_ = enabled_by_default;
149 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG) 159 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG)
150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG 160 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG
151 161
152 TimelineEvent::TimelineEvent() 162 TimelineEvent::TimelineEvent()
153 : timestamp0_(0), 163 : timestamp0_(0),
154 timestamp1_(0), 164 timestamp1_(0),
155 arguments_(NULL), 165 arguments_(NULL),
156 arguments_length_(0), 166 arguments_length_(0),
157 state_(0), 167 state_(0),
158 label_(NULL), 168 label_(NULL),
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 : isolate_id_(isolate_id) { 634 : isolate_id_(isolate_id) {
625 } 635 }
626 636
627 637
628 TimelineEventRecorder::TimelineEventRecorder() 638 TimelineEventRecorder::TimelineEventRecorder()
629 : async_id_(0) { 639 : async_id_(0) {
630 } 640 }
631 641
632 642
633 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { 643 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
644 ThreadIterator it;
645 while (it.HasNext()) {
646 Thread* thread = it.Next();
647 const char* thread_name = thread->name();
648 if (thread_name == NULL) {
649 // Only emit a thread name if one was set.
650 continue;
651 }
652 JSONObject obj(events);
653 int64_t pid = OS::ProcessId();
654 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id());
655 obj.AddProperty("name", "thread_name");
656 obj.AddProperty("ph", "M");
657 obj.AddProperty64("pid", pid);
658 obj.AddProperty64("tid", tid);
659 {
660 JSONObject args(&obj, "args");
661 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid);
662 }
663 }
634 } 664 }
635 665
636 666
637 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { 667 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
638 // Grab the current thread. 668 // Grab the current thread.
639 Thread* thread = Thread::Current(); 669 Thread* thread = Thread::Current();
640 ASSERT(thread != NULL); 670 ASSERT(thread != NULL);
641 Mutex* thread_block_lock = thread->timeline_block_lock(); 671 Mutex* thread_block_lock = thread->timeline_block_lock();
642 ASSERT(thread_block_lock != NULL); 672 ASSERT(thread_block_lock != NULL);
643 // We are accessing the thread's timeline block- so take the lock here. 673 // We are accessing the thread's timeline block- so take the lock here.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 for (intptr_t i = 0; i < num_blocks_; i++) { 806 for (intptr_t i = 0; i < num_blocks_; i++) {
777 TimelineEventBlock* block = blocks_[i]; 807 TimelineEventBlock* block = blocks_[i];
778 delete block; 808 delete block;
779 } 809 }
780 free(blocks_); 810 free(blocks_);
781 } 811 }
782 812
783 813
784 void TimelineEventRingRecorder::PrintJSONEvents( 814 void TimelineEventRingRecorder::PrintJSONEvents(
785 JSONArray* events, 815 JSONArray* events,
786 TimelineEventFilter* filter) const { 816 TimelineEventFilter* filter) {
817 MutexLocker ml(&lock_);
787 intptr_t block_offset = FindOldestBlockIndex(); 818 intptr_t block_offset = FindOldestBlockIndex();
788 if (block_offset == -1) { 819 if (block_offset == -1) {
789 // All blocks are empty. 820 // All blocks are empty.
790 return; 821 return;
791 } 822 }
792 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { 823 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) {
793 TimelineEventBlock* block = 824 TimelineEventBlock* block =
794 blocks_[(block_idx + block_offset) % num_blocks_]; 825 blocks_[(block_idx + block_offset) % num_blocks_];
795 if (!filter->IncludeBlock(block)) { 826 if (!filter->IncludeBlock(block)) {
796 continue; 827 continue;
797 } 828 }
798 for (intptr_t event_idx = 0; event_idx < block->length(); event_idx++) { 829 for (intptr_t event_idx = 0; event_idx < block->length(); event_idx++) {
799 TimelineEvent* event = block->At(event_idx); 830 TimelineEvent* event = block->At(event_idx);
800 if (filter->IncludeEvent(event)) { 831 if (filter->IncludeEvent(event)) {
801 events->AddValue(event); 832 events->AddValue(event);
802 } 833 }
803 } 834 }
804 } 835 }
805 } 836 }
806 837
807 838
808 void TimelineEventRingRecorder::PrintJSON(JSONStream* js, 839 void TimelineEventRingRecorder::PrintJSON(JSONStream* js,
809 TimelineEventFilter* filter) { 840 TimelineEventFilter* filter) {
810 MutexLocker ml(&lock_);
811 JSONObject topLevel(js); 841 JSONObject topLevel(js);
812 topLevel.AddProperty("type", "_Timeline"); 842 topLevel.AddProperty("type", "_Timeline");
813 { 843 {
814 JSONArray events(&topLevel, "traceEvents"); 844 JSONArray events(&topLevel, "traceEvents");
815 PrintJSONMeta(&events); 845 PrintJSONMeta(&events);
816 PrintJSONEvents(&events, filter); 846 PrintJSONEvents(&events, filter);
817 } 847 }
818 } 848 }
819 849
820 850
(...skipping 15 matching lines...) Expand all
836 if (block_cursor_ == num_blocks_) { 866 if (block_cursor_ == num_blocks_) {
837 block_cursor_ = 0; 867 block_cursor_ = 0;
838 } 868 }
839 TimelineEventBlock* block = blocks_[block_cursor_++]; 869 TimelineEventBlock* block = blocks_[block_cursor_++];
840 block->Reset(); 870 block->Reset();
841 block->Open(); 871 block->Open();
842 return block; 872 return block;
843 } 873 }
844 874
845 875
876 void TimelineEventRingRecorder::Clear() {
877 MutexLocker ml(&lock_);
878 for (intptr_t i = 0; i < num_blocks_; i++) {
879 TimelineEventBlock* block = blocks_[i];
880 block->Reset();
881 }
882 }
883
884
846 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const { 885 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const {
847 int64_t earliest_time = kMaxInt64; 886 int64_t earliest_time = kMaxInt64;
848 intptr_t earliest_index = -1; 887 intptr_t earliest_index = -1;
849 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { 888 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) {
850 TimelineEventBlock* block = blocks_[block_idx]; 889 TimelineEventBlock* block = blocks_[block_idx];
851 if (block->IsEmpty()) { 890 if (block->IsEmpty()) {
852 // Skip empty blocks. 891 // Skip empty blocks.
853 continue; 892 continue;
854 } 893 }
855 if (block->LowerTimeBound() < earliest_time) { 894 if (block->LowerTimeBound() < earliest_time) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 955
917 956
918 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() 957 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
919 : head_(NULL), 958 : head_(NULL),
920 block_index_(0) { 959 block_index_(0) {
921 } 960 }
922 961
923 962
924 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, 963 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
925 TimelineEventFilter* filter) { 964 TimelineEventFilter* filter) {
926 MutexLocker ml(&lock_);
927 JSONObject topLevel(js); 965 JSONObject topLevel(js);
928 topLevel.AddProperty("type", "_Timeline"); 966 topLevel.AddProperty("type", "_Timeline");
929 { 967 {
930 JSONArray events(&topLevel, "traceEvents"); 968 JSONArray events(&topLevel, "traceEvents");
931 PrintJSONMeta(&events); 969 PrintJSONMeta(&events);
932 PrintJSONEvents(&events, filter); 970 PrintJSONEvents(&events, filter);
933 } 971 }
934 } 972 }
935 973
936 974
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 head_ = block; 1008 head_ = block;
971 if (FLAG_trace_timeline) { 1009 if (FLAG_trace_timeline) {
972 OS::Print("Created new block %p\n", block); 1010 OS::Print("Created new block %p\n", block);
973 } 1011 }
974 return head_; 1012 return head_;
975 } 1013 }
976 1014
977 1015
978 void TimelineEventEndlessRecorder::PrintJSONEvents( 1016 void TimelineEventEndlessRecorder::PrintJSONEvents(
979 JSONArray* events, 1017 JSONArray* events,
980 TimelineEventFilter* filter) const { 1018 TimelineEventFilter* filter) {
1019 MutexLocker ml(&lock_);
981 TimelineEventBlock* current = head_; 1020 TimelineEventBlock* current = head_;
982
983 while (current != NULL) { 1021 while (current != NULL) {
984 if (!filter->IncludeBlock(current)) { 1022 if (!filter->IncludeBlock(current)) {
985 current = current->next(); 1023 current = current->next();
986 continue; 1024 continue;
987 } 1025 }
988 intptr_t length = current->length(); 1026 intptr_t length = current->length();
989 for (intptr_t i = 0; i < length; i++) { 1027 for (intptr_t i = 0; i < length; i++) {
990 TimelineEvent* event = current->At(i); 1028 TimelineEvent* event = current->At(i);
991 if (!filter->IncludeEvent(event)) { 1029 if (!filter->IncludeEvent(event)) {
992 continue; 1030 continue;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 1169
1132 1170
1133 TimelineEventBlock* TimelineEventBlockIterator::Next() { 1171 TimelineEventBlock* TimelineEventBlockIterator::Next() {
1134 ASSERT(current_ != NULL); 1172 ASSERT(current_ != NULL);
1135 TimelineEventBlock* r = current_; 1173 TimelineEventBlock* r = current_;
1136 current_ = current_->next(); 1174 current_ = current_->next();
1137 return r; 1175 return r;
1138 } 1176 }
1139 1177
1140 } // namespace dart 1178 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/timeline.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698