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 #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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 void Timeline::ReclaimCachedBlocksFromThreads() { | 122 void Timeline::ReclaimCachedBlocksFromThreads() { |
123 TimelineEventRecorder* recorder = Timeline::recorder(); | 123 TimelineEventRecorder* recorder = Timeline::recorder(); |
124 if (recorder == NULL) { | 124 if (recorder == NULL) { |
125 return; | 125 return; |
126 } | 126 } |
127 | 127 |
128 // Iterate over threads. | 128 // Iterate over threads. |
129 ThreadIterator it; | 129 OSThreadIterator it; |
130 while (it.HasNext()) { | 130 while (it.HasNext()) { |
131 Thread* thread = it.Next(); | 131 OSThread* thread = it.Next(); |
132 MutexLocker ml(thread->timeline_block_lock()); | 132 MutexLocker ml(thread->timeline_block_lock()); |
133 // Grab block and clear it. | 133 // Grab block and clear it. |
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 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 } | 343 } |
344 } | 344 } |
345 | 345 |
346 | 346 |
347 void TimelineEvent::Init(EventType event_type, | 347 void TimelineEvent::Init(EventType event_type, |
348 const char* label) { | 348 const char* label) { |
349 ASSERT(label != NULL); | 349 ASSERT(label != NULL); |
350 set_event_type(event_type); | 350 set_event_type(event_type); |
351 timestamp0_ = 0; | 351 timestamp0_ = 0; |
352 timestamp1_ = 0; | 352 timestamp1_ = 0; |
353 thread_ = OSThread::GetCurrentThreadTraceId(); | 353 OSThread* os_thread = OSThread::Current(); |
| 354 ASSERT(os_thread != NULL); |
| 355 thread_ = os_thread->trace_id(); |
354 Isolate* isolate = Isolate::Current(); | 356 Isolate* isolate = Isolate::Current(); |
355 if (isolate != NULL) { | 357 if (isolate != NULL) { |
356 isolate_id_ = isolate->main_port(); | 358 isolate_id_ = isolate->main_port(); |
357 } else { | 359 } else { |
358 isolate_id_ = ILLEGAL_PORT; | 360 isolate_id_ = ILLEGAL_PORT; |
359 } | 361 } |
360 label_ = label; | 362 label_ = label; |
361 FreeArguments(); | 363 FreeArguments(); |
362 } | 364 } |
363 | 365 |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 : isolate_id_(isolate_id) { | 636 : isolate_id_(isolate_id) { |
635 } | 637 } |
636 | 638 |
637 | 639 |
638 TimelineEventRecorder::TimelineEventRecorder() | 640 TimelineEventRecorder::TimelineEventRecorder() |
639 : async_id_(0) { | 641 : async_id_(0) { |
640 } | 642 } |
641 | 643 |
642 | 644 |
643 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 645 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
644 ThreadIterator it; | 646 OSThreadIterator it; |
645 while (it.HasNext()) { | 647 while (it.HasNext()) { |
646 Thread* thread = it.Next(); | 648 OSThread* thread = it.Next(); |
647 const char* thread_name = thread->name(); | 649 const char* thread_name = thread->name(); |
648 if (thread_name == NULL) { | 650 if (thread_name == NULL) { |
649 // Only emit a thread name if one was set. | 651 // Only emit a thread name if one was set. |
650 continue; | 652 continue; |
651 } | 653 } |
652 JSONObject obj(events); | 654 JSONObject obj(events); |
653 int64_t pid = OS::ProcessId(); | 655 int64_t pid = OS::ProcessId(); |
654 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); | 656 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); |
655 obj.AddProperty("name", "thread_name"); | 657 obj.AddProperty("name", "thread_name"); |
656 obj.AddProperty("ph", "M"); | 658 obj.AddProperty("ph", "M"); |
657 obj.AddProperty64("pid", pid); | 659 obj.AddProperty64("pid", pid); |
658 obj.AddProperty64("tid", tid); | 660 obj.AddProperty64("tid", tid); |
659 { | 661 { |
660 JSONObject args(&obj, "args"); | 662 JSONObject args(&obj, "args"); |
661 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); | 663 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); |
662 } | 664 } |
663 } | 665 } |
664 } | 666 } |
665 | 667 |
666 | 668 |
667 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { | 669 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
668 // Grab the current thread. | 670 // Grab the current thread. |
669 Thread* thread = Thread::Current(); | 671 OSThread* thread = OSThread::Current(); |
670 ASSERT(thread != NULL); | 672 ASSERT(thread != NULL); |
671 Mutex* thread_block_lock = thread->timeline_block_lock(); | 673 Mutex* thread_block_lock = thread->timeline_block_lock(); |
672 ASSERT(thread_block_lock != NULL); | 674 ASSERT(thread_block_lock != NULL); |
673 // We are accessing the thread's timeline block- so take the lock here. | 675 // We are accessing the thread's timeline block- so take the lock here. |
674 // This lock will be held until the call to |CompleteEvent| is made. | 676 // This lock will be held until the call to |CompleteEvent| is made. |
675 thread_block_lock->Lock(); | 677 thread_block_lock->Lock(); |
676 | 678 |
677 TimelineEventBlock* thread_block = thread->timeline_block(); | 679 TimelineEventBlock* thread_block = thread->timeline_block(); |
678 | 680 |
679 if ((thread_block != NULL) && thread_block->IsFull()) { | 681 if ((thread_block != NULL) && thread_block->IsFull()) { |
(...skipping 20 matching lines...) Expand all Loading... |
700 thread_block_lock->Unlock(); | 702 thread_block_lock->Unlock(); |
701 return NULL; | 703 return NULL; |
702 } | 704 } |
703 | 705 |
704 | 706 |
705 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { | 707 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { |
706 if (event == NULL) { | 708 if (event == NULL) { |
707 return; | 709 return; |
708 } | 710 } |
709 // Grab the current thread. | 711 // Grab the current thread. |
710 Thread* thread = Thread::Current(); | 712 OSThread* thread = OSThread::Current(); |
711 ASSERT(thread != NULL); | 713 ASSERT(thread != NULL); |
712 // Unlock the thread's block lock. | 714 // Unlock the thread's block lock. |
713 Mutex* thread_block_lock = thread->timeline_block_lock(); | 715 Mutex* thread_block_lock = thread->timeline_block_lock(); |
714 ASSERT(thread_block_lock != NULL); | 716 ASSERT(thread_block_lock != NULL); |
715 thread_block_lock->Unlock(); | 717 thread_block_lock->Unlock(); |
716 } | 718 } |
717 | 719 |
718 | 720 |
719 void TimelineEventRecorder::WriteTo(const char* directory) { | 721 void TimelineEventRecorder::WriteTo(const char* directory) { |
720 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | 722 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 if (block->LowerTimeBound() < earliest_time) { | 896 if (block->LowerTimeBound() < earliest_time) { |
895 earliest_time = block->LowerTimeBound(); | 897 earliest_time = block->LowerTimeBound(); |
896 earliest_index = block_idx; | 898 earliest_index = block_idx; |
897 } | 899 } |
898 } | 900 } |
899 return earliest_index; | 901 return earliest_index; |
900 } | 902 } |
901 | 903 |
902 | 904 |
903 TimelineEvent* TimelineEventRingRecorder::StartEvent() { | 905 TimelineEvent* TimelineEventRingRecorder::StartEvent() { |
904 // Grab the current thread. | |
905 Thread* thread = Thread::Current(); | |
906 ASSERT(thread != NULL); | |
907 return ThreadBlockStartEvent(); | 906 return ThreadBlockStartEvent(); |
908 } | 907 } |
909 | 908 |
910 | 909 |
911 void TimelineEventRingRecorder::CompleteEvent(TimelineEvent* event) { | 910 void TimelineEventRingRecorder::CompleteEvent(TimelineEvent* event) { |
912 if (event == NULL) { | 911 if (event == NULL) { |
913 return; | 912 return; |
914 } | 913 } |
915 ThreadBlockCompleteEvent(event); | 914 ThreadBlockCompleteEvent(event); |
916 } | 915 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 PrintJSONEvents(&events, filter); | 978 PrintJSONEvents(&events, filter); |
980 } | 979 } |
981 | 980 |
982 | 981 |
983 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 982 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
984 return head_; | 983 return head_; |
985 } | 984 } |
986 | 985 |
987 | 986 |
988 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 987 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
989 // Grab the current thread. | |
990 Thread* thread = Thread::Current(); | |
991 ASSERT(thread != NULL); | |
992 return ThreadBlockStartEvent(); | 988 return ThreadBlockStartEvent(); |
993 } | 989 } |
994 | 990 |
995 | 991 |
996 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { | 992 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { |
997 if (event == NULL) { | 993 if (event == NULL) { |
998 return; | 994 return; |
999 } | 995 } |
1000 ThreadBlockCompleteEvent(event); | 996 ThreadBlockCompleteEvent(event); |
1001 } | 997 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 | 1034 |
1039 void TimelineEventEndlessRecorder::Clear() { | 1035 void TimelineEventEndlessRecorder::Clear() { |
1040 TimelineEventBlock* current = head_; | 1036 TimelineEventBlock* current = head_; |
1041 while (current != NULL) { | 1037 while (current != NULL) { |
1042 TimelineEventBlock* next = current->next(); | 1038 TimelineEventBlock* next = current->next(); |
1043 delete current; | 1039 delete current; |
1044 current = next; | 1040 current = next; |
1045 } | 1041 } |
1046 head_ = NULL; | 1042 head_ = NULL; |
1047 block_index_ = 0; | 1043 block_index_ = 0; |
1048 Thread* thread = Thread::Current(); | 1044 OSThread* thread = OSThread::Current(); |
1049 thread->set_timeline_block(NULL); | 1045 thread->set_timeline_block(NULL); |
1050 } | 1046 } |
1051 | 1047 |
1052 | 1048 |
1053 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 1049 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
1054 : next_(NULL), | 1050 : next_(NULL), |
1055 length_(0), | 1051 length_(0), |
1056 block_index_(block_index), | 1052 block_index_(block_index), |
1057 thread_id_(OSThread::kInvalidThreadId), | 1053 thread_id_(OSThread::kInvalidThreadId), |
1058 in_use_(false) { | 1054 in_use_(false) { |
1059 } | 1055 } |
1060 | 1056 |
1061 | 1057 |
1062 TimelineEventBlock::~TimelineEventBlock() { | 1058 TimelineEventBlock::~TimelineEventBlock() { |
1063 Reset(); | 1059 Reset(); |
1064 } | 1060 } |
1065 | 1061 |
1066 | 1062 |
1067 TimelineEvent* TimelineEventBlock::StartEvent() { | 1063 TimelineEvent* TimelineEventBlock::StartEvent() { |
1068 ASSERT(!IsFull()); | 1064 ASSERT(!IsFull()); |
1069 if (FLAG_trace_timeline) { | 1065 if (FLAG_trace_timeline) { |
1070 OS::Print("StartEvent in block %p for thread %" Px "\n", | 1066 OSThread* os_thread = OSThread::Current(); |
1071 this, OSThread::CurrentCurrentThreadIdAsIntPtr()); | 1067 ASSERT(os_thread != NULL); |
| 1068 intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id()); |
| 1069 OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid); |
1072 } | 1070 } |
1073 return &events_[length_++]; | 1071 return &events_[length_++]; |
1074 } | 1072 } |
1075 | 1073 |
1076 | 1074 |
1077 int64_t TimelineEventBlock::LowerTimeBound() const { | 1075 int64_t TimelineEventBlock::LowerTimeBound() const { |
1078 if (length_ == 0) { | 1076 if (length_ == 0) { |
1079 return kMaxInt64; | 1077 return kMaxInt64; |
1080 } | 1078 } |
1081 ASSERT(length_ > 0); | 1079 ASSERT(length_ > 0); |
(...skipping 30 matching lines...) Expand all Loading... |
1112 // Clear any extra data. | 1110 // Clear any extra data. |
1113 events_[i].Reset(); | 1111 events_[i].Reset(); |
1114 } | 1112 } |
1115 length_ = 0; | 1113 length_ = 0; |
1116 thread_id_ = OSThread::kInvalidThreadId; | 1114 thread_id_ = OSThread::kInvalidThreadId; |
1117 in_use_ = false; | 1115 in_use_ = false; |
1118 } | 1116 } |
1119 | 1117 |
1120 | 1118 |
1121 void TimelineEventBlock::Open() { | 1119 void TimelineEventBlock::Open() { |
1122 thread_id_ = OSThread::GetCurrentThreadTraceId(); | 1120 OSThread* os_thread = OSThread::Current(); |
| 1121 ASSERT(os_thread != NULL); |
| 1122 thread_id_ = os_thread->trace_id(); |
1123 in_use_ = true; | 1123 in_use_ = true; |
1124 } | 1124 } |
1125 | 1125 |
1126 | 1126 |
1127 void TimelineEventBlock::Finish() { | 1127 void TimelineEventBlock::Finish() { |
1128 if (FLAG_trace_timeline) { | 1128 if (FLAG_trace_timeline) { |
1129 OS::Print("Finish block %p\n", this); | 1129 OS::Print("Finish block %p\n", this); |
1130 } | 1130 } |
1131 in_use_ = false; | 1131 in_use_ = false; |
1132 } | 1132 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 | 1169 |
1170 | 1170 |
1171 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1171 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
1172 ASSERT(current_ != NULL); | 1172 ASSERT(current_ != NULL); |
1173 TimelineEventBlock* r = current_; | 1173 TimelineEventBlock* r = current_; |
1174 current_ = current_->next(); | 1174 current_ = current_->next(); |
1175 return r; | 1175 return r; |
1176 } | 1176 } |
1177 | 1177 |
1178 } // namespace dart | 1178 } // namespace dart |
OLD | NEW |