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

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

Issue 1402383003: Simplify timeline backend (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') | 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 12 matching lines...) Expand all
23 DEFINE_FLAG(bool, timing, false, 23 DEFINE_FLAG(bool, timing, false,
24 "Dump isolate timing information from timeline."); 24 "Dump isolate timing information from timeline.");
25 DEFINE_FLAG(charp, timeline_dir, NULL, 25 DEFINE_FLAG(charp, timeline_dir, NULL,
26 "Enable all timeline trace streams and output VM global trace " 26 "Enable all timeline trace streams and output VM global trace "
27 "into specified directory."); 27 "into specified directory.");
28 28
29 // Implementation notes: 29 // Implementation notes:
30 // 30 //
31 // Writing events: 31 // Writing events:
32 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches 32 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches
33 // a |TimelineEventBlock| in TLS so that it can write events without 33 // a |TimelineEventBlock| object so that it can write events without
34 // synchronizing with other threads in the system. Even though the |Thread| owns 34 // synchronizing with other threads in the system. Even though the |Thread| owns
35 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting 35 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting
36 // system. To support that, a |Thread| must hold its |timeline_block_lock_| 36 // system. To support that, a |Thread| must hold its |timeline_block_lock_|
37 // when operating on the |TimelineEventBlock|. This lock will only ever be 37 // when operating on the |TimelineEventBlock|. This lock will only ever be
38 // busy if blocks are being reclaimed by the reporting system. 38 // busy if blocks are being reclaimed by the reporting system.
39 // 39 //
40 // Reporting: 40 // Reporting:
41 // When requested, the timeline is serialized in the trace-event format 41 // When requested, the timeline is serialized in the trace-event format
42 // (https://goo.gl/hDZw5M). The request can be for a VM-wide timeline or an 42 // (https://goo.gl/hDZw5M). The request can be for a VM-wide timeline or an
43 // isolate specific timeline. In both cases it may be that a thread has 43 // isolate specific timeline. In both cases it may be that a thread has
44 // a |TimelineEventBlock| cached in TLS. In order to report a complete timeline 44 // a |TimelineEventBlock| cached in TLS partially filled with events. In order
45 // the cached |TimelineEventBlock|s need to be reclaimed. 45 // to report a complete timeline the cached |TimelineEventBlock|s need to be
46 // reclaimed.
46 // 47 //
47 // Reclaiming open |TimelineEventBlock|s for an isolate: 48 // Reclaiming open |TimelineEventBlock|s from threads:
48 // 49 //
49 // Cached |TimelineEventBlock|s can be in two places: 50 // Each |Thread| can have one |TimelineEventBlock| cached in it.
50 // 1) In a |Thread| (Thread currently in an |Isolate|)
51 // 2) In a |Thread::State| (Thread not currently in an |Isolate|).
52 // 51 //
53 // As a |Thread| enters and exits an |Isolate|, a |TimelineEventBlock| 52 // To reclaim blocks, we iterate over all threads and remove the cached
54 // will move between (1) and (2). 53 // |TimelineEventBlock| from each thread. This is safe because we hold the
55 // 54 // |Thread|'s |timeline_block_lock_| meaning the block can't be being modified.
56 // The first case occurs for |Thread|s that are currently running inside an
57 // isolate. The second case occurs for |Thread|s that are not currently
58 // running inside an isolate.
59 //
60 // To reclaim the first case, we take the |Thread|'s |timeline_block_lock_|
61 // and reclaim the cached block.
62 //
63 // To reclaim the second case, we can take the |ThreadRegistry| lock and
64 // reclaim these blocks.
65 //
66 // |Timeline::ReclaimIsolateBlocks| and |Timeline::ReclaimAllBlocks| are
67 // the two utility methods used to reclaim blocks before reporting.
68 // 55 //
69 // Locking notes: 56 // Locking notes:
70 // The following locks are used by the timeline system: 57 // The following locks are used by the timeline system:
71 // - |TimelineEventRecorder::lock_| This lock is held whenever a 58 // - |TimelineEventRecorder::lock_| This lock is held whenever a
72 // |TimelineEventBlock| is being requested or reclaimed. 59 // |TimelineEventBlock| is being requested or reclaimed.
73 // - |Thread::timeline_block_lock_| This lock is held whenever a |Thread|'s 60 // - |Thread::timeline_block_lock_| This lock is held whenever a |Thread|'s
74 // cached block is being operated on. 61 // cached block is being operated on.
75 // - |ThreadRegistry::monitor_| This lock protects the cached block for 62 // - |Thread::thread_list_lock_| This lock is held when iterating over
76 // unscheduled threads of an isolate. 63 // |Thread|s.
77 // - |Isolate::isolates_list_monitor_| This lock protects the list of
78 // isolates in the system.
79 // 64 //
80 // Locks must always be taken in the following order: 65 // Locks must always be taken in the following order:
81 // |Isolate::isolates_list_monitor_| 66 // |Thread::thread_list_lock_|
82 // |ThreadRegistry::monitor_|
83 // |Thread::timeline_block_lock_| 67 // |Thread::timeline_block_lock_|
84 // |TimelineEventRecorder::lock_| 68 // |TimelineEventRecorder::lock_|
85 // 69 //
86 70
87 void Timeline::InitOnce() { 71 void Timeline::InitOnce() {
88 ASSERT(recorder_ == NULL); 72 ASSERT(recorder_ == NULL);
89 // Default to ring recorder being enabled. 73 // Default to ring recorder being enabled.
90 const bool use_ring_recorder = true; 74 const bool use_ring_recorder = true;
91 // Some flags require that we use the endless recorder. 75 // Some flags require that we use the endless recorder.
92 const bool use_endless_recorder = 76 const bool use_endless_recorder =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 return (FLAG_timeline_dir != NULL) || FLAG_timing; 112 return (FLAG_timeline_dir != NULL) || FLAG_timing;
129 } 113 }
130 114
131 115
132 TimelineStream* Timeline::GetVMStream() { 116 TimelineStream* Timeline::GetVMStream() {
133 ASSERT(vm_stream_ != NULL); 117 ASSERT(vm_stream_ != NULL);
134 return vm_stream_; 118 return vm_stream_;
135 } 119 }
136 120
137 121
138 void Timeline::ReclaimIsolateBlocks() { 122 void Timeline::ReclaimCachedBlocksFromThreads() {
139 ReclaimBlocksForIsolate(Isolate::Current()); 123 TimelineEventRecorder* recorder = Timeline::recorder();
124 if (recorder == NULL) {
125 return;
126 }
127
128 // Iterate over threads.
129 ThreadIterator it;
130 while (it.HasNext()) {
131 Thread* thread = it.Next();
132 MutexLocker ml(thread->timeline_block_lock());
133 // Grab block and clear it.
134 TimelineEventBlock* block = thread->timeline_block();
135 thread->set_timeline_block(NULL);
136 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here
137 // if we can do it everywhere. This would simplify the lock ordering
138 // requirements.
139 recorder->FinishBlock(block);
140 }
140 } 141 }
141 142
142 143
143 class ReclaimBlocksIsolateVisitor : public IsolateVisitor {
144 public:
145 ReclaimBlocksIsolateVisitor() {}
146
147 virtual void VisitIsolate(Isolate* isolate) {
148 Timeline::ReclaimBlocksForIsolate(isolate);
149 }
150
151 private:
152 };
153
154
155 void Timeline::ReclaimAllBlocks() {
156 if (recorder() == NULL) {
157 return;
158 }
159 // Reclaim all blocks cached for all isolates.
160 ReclaimBlocksIsolateVisitor visitor;
161 Isolate::VisitIsolates(&visitor);
162 // Reclaim the global VM block.
163 recorder()->ReclaimGlobalBlock();
164 }
165
166
167 void Timeline::ReclaimBlocksForIsolate(Isolate* isolate) {
168 if (recorder() == NULL) {
169 return;
170 }
171 ASSERT(isolate != NULL);
172 isolate->ReclaimTimelineBlocks();
173 }
174
175
176 TimelineEventRecorder* Timeline::recorder_ = NULL; 144 TimelineEventRecorder* Timeline::recorder_ = NULL;
177 TimelineStream* Timeline::vm_stream_ = NULL; 145 TimelineStream* Timeline::vm_stream_ = NULL;
178 146
179 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \ 147 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \
180 bool Timeline::stream_##name##_enabled_ = false; 148 bool Timeline::stream_##name##_enabled_ = false;
181 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG) 149 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG)
182 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG 150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG
183 151
184 TimelineEvent::TimelineEvent() 152 TimelineEvent::TimelineEvent()
185 : timestamp0_(0), 153 : timestamp0_(0),
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 617
650 void DartTimelineEvent::Init(Isolate* isolate, const char* event) { 618 void DartTimelineEvent::Init(Isolate* isolate, const char* event) {
651 ASSERT(isolate_ == NULL); 619 ASSERT(isolate_ == NULL);
652 ASSERT(event != NULL); 620 ASSERT(event != NULL);
653 isolate_ = isolate; 621 isolate_ = isolate;
654 event_as_json_ = strdup(event); 622 event_as_json_ = strdup(event);
655 } 623 }
656 624
657 625
658 TimelineEventRecorder::TimelineEventRecorder() 626 TimelineEventRecorder::TimelineEventRecorder()
659 : global_block_(NULL), 627 : async_id_(0) {
660 async_id_(0) {
661 } 628 }
662 629
663 630
664 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { 631 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
665 } 632 }
666 633
667 634
668 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { 635 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
669 // Grab the current thread. 636 // Grab the current thread.
670 Thread* thread = Thread::Current(); 637 Thread* thread = Thread::Current();
(...skipping 18 matching lines...) Expand all
689 } else if (thread_block == NULL) { 656 } else if (thread_block == NULL) {
690 MutexLocker ml(&lock_); 657 MutexLocker ml(&lock_);
691 // Thread has no block. Attempt to allocate one. 658 // Thread has no block. Attempt to allocate one.
692 thread_block = GetNewBlockLocked(thread->isolate()); 659 thread_block = GetNewBlockLocked(thread->isolate());
693 thread->set_timeline_block(thread_block); 660 thread->set_timeline_block(thread_block);
694 } 661 }
695 if (thread_block != NULL) { 662 if (thread_block != NULL) {
696 // 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.
697 ASSERT(!thread_block->IsFull()); 664 ASSERT(!thread_block->IsFull());
698 TimelineEvent* event = thread_block->StartEvent(); 665 TimelineEvent* event = thread_block->StartEvent();
699 if (event != NULL) {
700 event->set_global_block(false);
701 }
702 return event; 666 return event;
703 } 667 }
704 // Drop lock here as no event is being handed out. 668 // Drop lock here as no event is being handed out.
705 thread_block_lock->Unlock(); 669 thread_block_lock->Unlock();
706 return NULL; 670 return NULL;
707 } 671 }
708 672
709 673
710 TimelineEvent* TimelineEventRecorder::GlobalBlockStartEvent() {
711 // Take recorder lock. This lock will be held until the call to
712 // |CompleteEvent| is made.
713 lock_.Lock();
714 if (FLAG_trace_timeline) {
715 OS::Print("GlobalBlockStartEvent in block %p for thread %" Px "\n",
716 global_block_, OSThread::CurrentCurrentThreadIdAsIntPtr());
717 }
718 if ((global_block_ != NULL) && global_block_->IsFull()) {
719 // Global block is full.
720 global_block_->Finish();
721 global_block_ = NULL;
722 }
723 if (global_block_ == NULL) {
724 // Allocate a new block.
725 global_block_ = GetNewBlockLocked(NULL);
726 ASSERT(global_block_ != NULL);
727 }
728 if (global_block_ != NULL) {
729 // NOTE: We are exiting this function with the recorder's lock held.
730 ASSERT(!global_block_->IsFull());
731 TimelineEvent* event = global_block_->StartEvent();
732 if (event != NULL) {
733 event->set_global_block(true);
734 }
735 return event;
736 }
737 // Drop lock here as no event is being handed out.
738 lock_.Unlock();
739 return NULL;
740 }
741
742
743 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { 674 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) {
744 if (event == NULL) { 675 if (event == NULL) {
745 return; 676 return;
746 } 677 }
747 ASSERT(!event->global_block());
748 // Grab the current thread. 678 // Grab the current thread.
749 Thread* thread = Thread::Current(); 679 Thread* thread = Thread::Current();
750 ASSERT(thread != NULL); 680 ASSERT(thread != NULL);
751 ASSERT(thread->isolate() != NULL); 681 // Unlock the thread's block lock.
752 // This event came from the isolate's thread local block. Unlock the
753 // thread's block lock.
754 Mutex* thread_block_lock = thread->timeline_block_lock(); 682 Mutex* thread_block_lock = thread->timeline_block_lock();
755 ASSERT(thread_block_lock != NULL); 683 ASSERT(thread_block_lock != NULL);
756 thread_block_lock->Unlock(); 684 thread_block_lock->Unlock();
757 } 685 }
758 686
759 687
760 void TimelineEventRecorder::GlobalBlockCompleteEvent(TimelineEvent* event) {
761 if (event == NULL) {
762 return;
763 }
764 ASSERT(event->global_block());
765 // This event came from the global block, unlock the recorder's lock now
766 // that the event is filled.
767 lock_.Unlock();
768 }
769
770
771 // Trims the ']' character. 688 // Trims the ']' character.
772 static void TrimOutput(char* output, 689 static void TrimOutput(char* output,
773 intptr_t* output_length) { 690 intptr_t* output_length) {
774 ASSERT(output != NULL); 691 ASSERT(output != NULL);
775 ASSERT(output_length != NULL); 692 ASSERT(output_length != NULL);
776 ASSERT(*output_length >= 2); 693 ASSERT(*output_length >= 2);
777 // We expect the first character to be the opening of an array. 694 // We expect the first character to be the opening of an array.
778 ASSERT(output[0] == '['); 695 ASSERT(output[0] == '[');
779 // We expect the last character to be the closing of an array. 696 // We expect the last character to be the closing of an array.
780 ASSERT(output[*output_length - 1] == ']'); 697 ASSERT(output[*output_length - 1] == ']');
781 // Skip the ]. 698 // Skip the ].
782 *output_length -= 1; 699 *output_length -= 1;
783 } 700 }
784 701
785 702
786 void TimelineEventRecorder::WriteTo(const char* directory) { 703 void TimelineEventRecorder::WriteTo(const char* directory) {
787 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); 704 Dart_FileOpenCallback file_open = Isolate::file_open_callback();
788 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); 705 Dart_FileWriteCallback file_write = Isolate::file_write_callback();
789 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); 706 Dart_FileCloseCallback file_close = Isolate::file_close_callback();
790 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { 707 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
791 return; 708 return;
792 } 709 }
793 Thread* T = Thread::Current(); 710 Thread* T = Thread::Current();
794 StackZone zone(T); 711 StackZone zone(T);
795 712
796 Timeline::ReclaimAllBlocks(); 713 Timeline::ReclaimCachedBlocksFromThreads();
797 714
798 intptr_t pid = OS::ProcessId(); 715 intptr_t pid = OS::ProcessId();
799 char* filename = OS::SCreate(NULL, 716 char* filename = OS::SCreate(NULL,
800 "%s/dart-timeline-%" Pd ".json", directory, pid); 717 "%s/dart-timeline-%" Pd ".json", directory, pid);
801 void* file = (*file_open)(filename, true); 718 void* file = (*file_open)(filename, true);
802 if (file == NULL) { 719 if (file == NULL) {
803 OS::Print("Failed to write timeline file: %s\n", filename); 720 OS::Print("Failed to write timeline file: %s\n", filename);
804 free(filename); 721 free(filename);
805 return; 722 return;
806 } 723 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 755
839 // Write out the ']' character. 756 // Write out the ']' character.
840 const char* array_close = "]"; 757 const char* array_close = "]";
841 (*file_write)(array_close, 1, file); 758 (*file_write)(array_close, 1, file);
842 (*file_close)(file); 759 (*file_close)(file);
843 760
844 return; 761 return;
845 } 762 }
846 763
847 764
848 void TimelineEventRecorder::ReclaimGlobalBlock() {
849 MutexLocker ml(&lock_);
850 if (global_block_ != NULL) {
851 global_block_->Finish();
852 global_block_ = NULL;
853 }
854 }
855
856
857 int64_t TimelineEventRecorder::GetNextAsyncId() { 765 int64_t TimelineEventRecorder::GetNextAsyncId() {
858 // TODO(johnmccutchan): Gracefully handle wrap around. 766 // TODO(johnmccutchan): Gracefully handle wrap around.
859 uint32_t next = static_cast<uint32_t>( 767 uint32_t next = static_cast<uint32_t>(
860 AtomicOperations::FetchAndIncrement(&async_id_)); 768 AtomicOperations::FetchAndIncrement(&async_id_));
861 return static_cast<int64_t>(next); 769 return static_cast<int64_t>(next);
862 } 770 }
863 771
864 772
865 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { 773 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) {
866 if (block == NULL) { 774 if (block == NULL) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 } 939 }
1032 } 940 }
1033 return earliest_index; 941 return earliest_index;
1034 } 942 }
1035 943
1036 944
1037 TimelineEvent* TimelineEventRingRecorder::StartEvent() { 945 TimelineEvent* TimelineEventRingRecorder::StartEvent() {
1038 // Grab the current thread. 946 // Grab the current thread.
1039 Thread* thread = Thread::Current(); 947 Thread* thread = Thread::Current();
1040 ASSERT(thread != NULL); 948 ASSERT(thread != NULL);
1041 if (thread->isolate() == NULL) {
1042 // Non-isolate thread case. This should be infrequent.
1043 return GlobalBlockStartEvent();
1044 }
1045 return ThreadBlockStartEvent(); 949 return ThreadBlockStartEvent();
1046 } 950 }
1047 951
1048 952
1049 void TimelineEventRingRecorder::CompleteEvent(TimelineEvent* event) { 953 void TimelineEventRingRecorder::CompleteEvent(TimelineEvent* event) {
1050 if (event == NULL) { 954 if (event == NULL) {
1051 return; 955 return;
1052 } 956 }
1053 if (event->global_block()) { 957 ThreadBlockCompleteEvent(event);
1054 GlobalBlockCompleteEvent(event);
1055 } else {
1056 ThreadBlockCompleteEvent(event);
1057 }
1058 } 958 }
1059 959
1060 960
1061 TimelineEventStreamingRecorder::TimelineEventStreamingRecorder() { 961 TimelineEventStreamingRecorder::TimelineEventStreamingRecorder() {
1062 } 962 }
1063 963
1064 964
1065 TimelineEventStreamingRecorder::~TimelineEventStreamingRecorder() { 965 TimelineEventStreamingRecorder::~TimelineEventStreamingRecorder() {
1066 } 966 }
1067 967
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 1072
1173 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { 1073 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
1174 return head_; 1074 return head_;
1175 } 1075 }
1176 1076
1177 1077
1178 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { 1078 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() {
1179 // Grab the current thread. 1079 // Grab the current thread.
1180 Thread* thread = Thread::Current(); 1080 Thread* thread = Thread::Current();
1181 ASSERT(thread != NULL); 1081 ASSERT(thread != NULL);
1182 if (thread->isolate() == NULL) {
1183 // Non-isolate thread case. This should be infrequent.
1184 return GlobalBlockStartEvent();
1185 }
1186 return ThreadBlockStartEvent(); 1082 return ThreadBlockStartEvent();
1187 } 1083 }
1188 1084
1189 1085
1190 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { 1086 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) {
1191 if (event == NULL) { 1087 if (event == NULL) {
1192 return; 1088 return;
1193 } 1089 }
1194 if (event->global_block()) { 1090 ThreadBlockCompleteEvent(event);
1195 GlobalBlockCompleteEvent(event);
1196 } else {
1197 ThreadBlockCompleteEvent(event);
1198 }
1199 } 1091 }
1200 1092
1201 1093
1202 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked( 1094 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked(
1203 Isolate* isolate) { 1095 Isolate* isolate) {
1204 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); 1096 TimelineEventBlock* block = new TimelineEventBlock(block_index_++);
1205 block->set_next(head_); 1097 block->set_next(head_);
1206 block->Open(isolate); 1098 block->Open(isolate);
1207 head_ = block; 1099 head_ = block;
1208 if (FLAG_trace_timeline) { 1100 if (FLAG_trace_timeline) {
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 // If an isolate was specified, skip events from other isolates. 1359 // If an isolate was specified, skip events from other isolates.
1468 continue; 1360 continue;
1469 } 1361 }
1470 ASSERT(event->event_as_json() != NULL); 1362 ASSERT(event->event_as_json() != NULL);
1471 result = zone->ConcatStrings(result, event->event_as_json()); 1363 result = zone->ConcatStrings(result, event->event_as_json());
1472 } 1364 }
1473 return result; 1365 return result;
1474 } 1366 }
1475 1367
1476 } // namespace dart 1368 } // 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