| 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 |