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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 const bool use_ring_recorder = true; | 131 const bool use_ring_recorder = true; |
132 // Some flags require that we use the endless recorder. | 132 // Some flags require that we use the endless recorder. |
133 const bool use_endless_recorder = | 133 const bool use_endless_recorder = |
134 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; | 134 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; |
135 if (use_endless_recorder) { | 135 if (use_endless_recorder) { |
136 recorder_ = new TimelineEventEndlessRecorder(); | 136 recorder_ = new TimelineEventEndlessRecorder(); |
137 } else if (use_ring_recorder) { | 137 } else if (use_ring_recorder) { |
138 recorder_ = new TimelineEventRingRecorder(); | 138 recorder_ = new TimelineEventRingRecorder(); |
139 } | 139 } |
140 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); | 140 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); |
141 vm_stream_.Init("VM", HasStream(enabled_streams_, "VM"), NULL); | |
142 vm_api_stream_.Init("API", | |
143 HasStream(enabled_streams_, "API"), | |
144 &stream_API_enabled_); | |
145 // Global overrides. | 141 // Global overrides. |
146 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ | 142 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ |
147 stream_##name##_enabled_ = HasStream(enabled_streams_, #name); | 143 stream_##name##_enabled_ = HasStream(enabled_streams_, #name); \ |
148 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT) | 144 stream_##name##_.Init(#name, \ |
149 #undef ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT | 145 stream_##name##_enabled_, \ |
| 146 &stream_##name##_enabled_); |
| 147 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) |
| 148 #undef TIMELINE_STREAM_FLAG_DEFAULT |
150 } | 149 } |
151 | 150 |
152 | 151 |
153 void Timeline::SetVMStreamEnabled(bool enabled) { | |
154 vm_stream_.set_enabled(enabled); | |
155 } | |
156 | |
157 | |
158 void Timeline::StreamStateChange(const char* stream_name, | 152 void Timeline::StreamStateChange(const char* stream_name, |
159 bool prev, | 153 bool prev, |
160 bool curr) { | 154 bool curr) { |
161 if (prev == curr) { | 155 if (prev == curr) { |
162 return; | 156 return; |
163 } | 157 } |
164 if (strcmp(stream_name, "Embedder") == 0) { | 158 if (strcmp(stream_name, "Embedder") == 0) { |
165 if (curr && (Timeline::get_start_recording_cb() != NULL)) { | 159 if (curr && (Timeline::get_start_recording_cb() != NULL)) { |
166 Timeline::get_start_recording_cb()(); | 160 Timeline::get_start_recording_cb()(); |
167 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { | 161 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { |
168 Timeline::get_stop_recording_cb()(); | 162 Timeline::get_stop_recording_cb()(); |
169 } | 163 } |
170 } | 164 } |
171 } | 165 } |
172 | 166 |
173 | 167 |
174 void Timeline::Shutdown() { | 168 void Timeline::Shutdown() { |
175 ASSERT(recorder_ != NULL); | 169 ASSERT(recorder_ != NULL); |
176 if (FLAG_timeline_dir != NULL) { | 170 if (FLAG_timeline_dir != NULL) { |
177 recorder_->WriteTo(FLAG_timeline_dir); | 171 recorder_->WriteTo(FLAG_timeline_dir); |
178 } | 172 } |
179 // Disable global streams. | 173 // Disable global streams. |
180 vm_stream_.set_enabled(false); | 174 #define TIMELINE_STREAM_DISABLE(name, not_used) \ |
181 vm_api_stream_.set_enabled(false); | |
182 #define ISOLATE_TIMELINE_STREAM_DISABLE(name, not_used) \ | |
183 stream_##name##_enabled_ = false; | 175 stream_##name##_enabled_ = false; |
184 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DISABLE) | 176 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) |
185 #undef ISOLATE_TIMELINE_STREAM_DISABLE | 177 #undef TIMELINE_STREAM_DISABLE |
186 delete recorder_; | 178 delete recorder_; |
187 recorder_ = NULL; | 179 recorder_ = NULL; |
188 if (enabled_streams_ != NULL) { | 180 if (enabled_streams_ != NULL) { |
189 FreeEnabledByDefaultTimelineStreams(enabled_streams_); | 181 FreeEnabledByDefaultTimelineStreams(enabled_streams_); |
190 enabled_streams_ = NULL; | 182 enabled_streams_ = NULL; |
191 } | 183 } |
192 } | 184 } |
193 | 185 |
194 | 186 |
195 TimelineEventRecorder* Timeline::recorder() { | 187 TimelineEventRecorder* Timeline::recorder() { |
196 return recorder_; | 188 return recorder_; |
197 } | 189 } |
198 | 190 |
199 | 191 |
200 void Timeline::SetupIsolateStreams(Isolate* isolate) { | |
201 if (!FLAG_support_timeline) { | |
202 return; | |
203 } | |
204 #define ISOLATE_TIMELINE_STREAM_INIT(name, enabled_by_default) \ | |
205 isolate->Get##name##Stream()->Init( \ | |
206 #name, \ | |
207 (enabled_by_default || HasStream(enabled_streams_, #name)), \ | |
208 Timeline::Stream##name##EnabledFlag()); | |
209 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_INIT); | |
210 #undef ISOLATE_TIMELINE_STREAM_INIT | |
211 } | |
212 | |
213 | |
214 TimelineStream* Timeline::GetVMStream() { | |
215 return &vm_stream_; | |
216 } | |
217 | |
218 | |
219 TimelineStream* Timeline::GetVMApiStream() { | |
220 return &vm_api_stream_; | |
221 } | |
222 | |
223 | |
224 void Timeline::ReclaimCachedBlocksFromThreads() { | 192 void Timeline::ReclaimCachedBlocksFromThreads() { |
225 TimelineEventRecorder* recorder = Timeline::recorder(); | 193 TimelineEventRecorder* recorder = Timeline::recorder(); |
226 if (recorder == NULL) { | 194 if (recorder == NULL) { |
227 return; | 195 return; |
228 } | 196 } |
229 | 197 |
230 // Iterate over threads. | 198 // Iterate over threads. |
231 OSThreadIterator it; | 199 OSThreadIterator it; |
232 while (it.HasNext()) { | 200 while (it.HasNext()) { |
233 OSThread* thread = it.Next(); | 201 OSThread* thread = it.Next(); |
(...skipping 15 matching lines...) Expand all Loading... |
249 TimelineEventRecorder* recorder = Timeline::recorder(); | 217 TimelineEventRecorder* recorder = Timeline::recorder(); |
250 if (recorder == NULL) { | 218 if (recorder == NULL) { |
251 obj.AddProperty("recorderName", "null"); | 219 obj.AddProperty("recorderName", "null"); |
252 } else { | 220 } else { |
253 obj.AddProperty("recorderName", recorder->name()); | 221 obj.AddProperty("recorderName", recorder->name()); |
254 } | 222 } |
255 { | 223 { |
256 JSONArray availableStreams(&obj, "availableStreams"); | 224 JSONArray availableStreams(&obj, "availableStreams"); |
257 #define ADD_STREAM_NAME(name, not_used) \ | 225 #define ADD_STREAM_NAME(name, not_used) \ |
258 availableStreams.AddValue(#name); | 226 availableStreams.AddValue(#name); |
259 ISOLATE_TIMELINE_STREAM_LIST(ADD_STREAM_NAME); | 227 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); |
260 #undef ADD_STREAM_NAME | 228 #undef ADD_STREAM_NAME |
261 availableStreams.AddValue("VM"); | |
262 } | 229 } |
263 { | 230 { |
264 JSONArray recordedStreams(&obj, "recordedStreams"); | 231 JSONArray recordedStreams(&obj, "recordedStreams"); |
265 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ | 232 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ |
266 if (stream_##name##_enabled_) { \ | 233 if (stream_##name##_enabled_) { \ |
267 recordedStreams.AddValue(#name); \ | 234 recordedStreams.AddValue(#name); \ |
268 } | 235 } |
269 ISOLATE_TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); | 236 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); |
270 #undef ADD_RECORDED_STREAM_NAME | 237 #undef ADD_RECORDED_STREAM_NAME |
271 if (vm_stream_.enabled()) { | |
272 recordedStreams.AddValue("VM"); | |
273 } | |
274 } | 238 } |
275 } | 239 } |
276 | 240 |
277 | 241 |
278 void Timeline::Clear() { | 242 void Timeline::Clear() { |
279 TimelineEventRecorder* recorder = Timeline::recorder(); | 243 TimelineEventRecorder* recorder = Timeline::recorder(); |
280 if (recorder == NULL) { | 244 if (recorder == NULL) { |
281 return; | 245 return; |
282 } | 246 } |
283 ReclaimCachedBlocksFromThreads(); | 247 ReclaimCachedBlocksFromThreads(); |
284 recorder->Clear(); | 248 recorder->Clear(); |
285 } | 249 } |
286 | 250 |
287 | 251 |
288 TimelineEventRecorder* Timeline::recorder_ = NULL; | 252 TimelineEventRecorder* Timeline::recorder_ = NULL; |
289 TimelineStream Timeline::vm_stream_; | |
290 TimelineStream Timeline::vm_api_stream_; | |
291 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; | 253 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; |
292 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; | 254 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; |
293 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; | 255 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; |
294 Dart_EmbedderTimelineGetTimeline Timeline::get_timeline_cb_ = NULL; | |
295 | 256 |
296 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \ | 257 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ |
297 bool Timeline::stream_##name##_enabled_ = enabled_by_default; | 258 bool Timeline::stream_##name##_enabled_ = enabled_by_default; \ |
298 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DEFINE_FLAG) | 259 TimelineStream Timeline::stream_##name##_; |
299 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG | 260 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) |
| 261 #undef TIMELINE_STREAM_DEFINE |
300 | 262 |
301 TimelineEvent::TimelineEvent() | 263 TimelineEvent::TimelineEvent() |
302 : timestamp0_(0), | 264 : timestamp0_(0), |
303 timestamp1_(0), | 265 timestamp1_(0), |
304 arguments_(NULL), | 266 arguments_(NULL), |
305 arguments_length_(0), | 267 arguments_length_(0), |
306 state_(0), | 268 state_(0), |
307 label_(NULL), | 269 label_(NULL), |
308 category_(""), | 270 category_(""), |
309 thread_(OSThread::kInvalidThreadId), | 271 thread_(OSThread::kInvalidThreadId), |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 #if defined(DEBUG) | 982 #if defined(DEBUG) |
1021 Thread* T = Thread::Current(); | 983 Thread* T = Thread::Current(); |
1022 if (T != NULL) { | 984 if (T != NULL) { |
1023 T->DecrementNoSafepointScopeDepth(); | 985 T->DecrementNoSafepointScopeDepth(); |
1024 } | 986 } |
1025 #endif // defined(DEBUG) | 987 #endif // defined(DEBUG) |
1026 thread_block_lock->Unlock(); | 988 thread_block_lock->Unlock(); |
1027 } | 989 } |
1028 | 990 |
1029 | 991 |
1030 void TimelineEventRecorder::PrintEmbedderJSONEvents(JSONStream* events) { | |
1031 if (Timeline::get_get_timeline_cb() != NULL) { | |
1032 events->PrintCommaIfNeeded(); | |
1033 Timeline::get_get_timeline_cb()(AppendJSONStreamConsumer, events); | |
1034 } | |
1035 } | |
1036 | |
1037 | |
1038 void TimelineEventRecorder::WriteTo(const char* directory) { | 992 void TimelineEventRecorder::WriteTo(const char* directory) { |
1039 if (!FLAG_support_service) { | 993 if (!FLAG_support_service) { |
1040 return; | 994 return; |
1041 } | 995 } |
1042 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | 996 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); |
1043 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); | 997 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); |
1044 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | 998 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); |
1045 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 999 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
1046 return; | 1000 return; |
1047 } | 1001 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 TimelineEventFilter* filter) { | 1121 TimelineEventFilter* filter) { |
1168 if (!FLAG_support_service) { | 1122 if (!FLAG_support_service) { |
1169 return; | 1123 return; |
1170 } | 1124 } |
1171 JSONObject topLevel(js); | 1125 JSONObject topLevel(js); |
1172 topLevel.AddProperty("type", "_Timeline"); | 1126 topLevel.AddProperty("type", "_Timeline"); |
1173 { | 1127 { |
1174 JSONArray events(&topLevel, "traceEvents"); | 1128 JSONArray events(&topLevel, "traceEvents"); |
1175 PrintJSONMeta(&events); | 1129 PrintJSONMeta(&events); |
1176 PrintJSONEvents(&events, filter); | 1130 PrintJSONEvents(&events, filter); |
1177 PrintEmbedderJSONEvents(js); | |
1178 } | 1131 } |
1179 } | 1132 } |
1180 | 1133 |
1181 | 1134 |
1182 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, | 1135 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, |
1183 TimelineEventFilter* filter) { | 1136 TimelineEventFilter* filter) { |
1184 if (!FLAG_support_service) { | 1137 if (!FLAG_support_service) { |
1185 return; | 1138 return; |
1186 } | 1139 } |
1187 JSONArray events(js); | 1140 JSONArray events(js); |
1188 PrintJSONEvents(&events, filter); | 1141 PrintJSONEvents(&events, filter); |
1189 PrintEmbedderJSONEvents(js); | |
1190 } | 1142 } |
1191 | 1143 |
1192 | 1144 |
1193 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { | 1145 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { |
1194 return blocks_[0]; | 1146 return blocks_[0]; |
1195 } | 1147 } |
1196 | 1148 |
1197 | 1149 |
1198 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { | 1150 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
1199 // TODO(johnmccutchan): This function should only hand out blocks | 1151 // TODO(johnmccutchan): This function should only hand out blocks |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 TimelineEventFilter* filter) { | 1254 TimelineEventFilter* filter) { |
1303 if (!FLAG_support_service) { | 1255 if (!FLAG_support_service) { |
1304 return; | 1256 return; |
1305 } | 1257 } |
1306 JSONObject topLevel(js); | 1258 JSONObject topLevel(js); |
1307 topLevel.AddProperty("type", "_Timeline"); | 1259 topLevel.AddProperty("type", "_Timeline"); |
1308 { | 1260 { |
1309 JSONArray events(&topLevel, "traceEvents"); | 1261 JSONArray events(&topLevel, "traceEvents"); |
1310 PrintJSONMeta(&events); | 1262 PrintJSONMeta(&events); |
1311 PrintJSONEvents(&events, filter); | 1263 PrintJSONEvents(&events, filter); |
1312 PrintEmbedderJSONEvents(js); | |
1313 } | 1264 } |
1314 } | 1265 } |
1315 | 1266 |
1316 | 1267 |
1317 void TimelineEventEndlessRecorder::PrintTraceEvent( | 1268 void TimelineEventEndlessRecorder::PrintTraceEvent( |
1318 JSONStream* js, | 1269 JSONStream* js, |
1319 TimelineEventFilter* filter) { | 1270 TimelineEventFilter* filter) { |
1320 if (!FLAG_support_service) { | 1271 if (!FLAG_support_service) { |
1321 return; | 1272 return; |
1322 } | 1273 } |
1323 JSONArray events(js); | 1274 JSONArray events(js); |
1324 PrintJSONEvents(&events, filter); | 1275 PrintJSONEvents(&events, filter); |
1325 PrintEmbedderJSONEvents(js); | |
1326 } | 1276 } |
1327 | 1277 |
1328 | 1278 |
1329 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 1279 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
1330 return head_; | 1280 return head_; |
1331 } | 1281 } |
1332 | 1282 |
1333 | 1283 |
1334 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 1284 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
1335 return ThreadBlockStartEvent(); | 1285 return ThreadBlockStartEvent(); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1504 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
1555 ASSERT(current_ != NULL); | 1505 ASSERT(current_ != NULL); |
1556 TimelineEventBlock* r = current_; | 1506 TimelineEventBlock* r = current_; |
1557 current_ = current_->next(); | 1507 current_ = current_->next(); |
1558 return r; | 1508 return r; |
1559 } | 1509 } |
1560 | 1510 |
1561 #endif // !PRODUCT | 1511 #endif // !PRODUCT |
1562 | 1512 |
1563 } // namespace dart | 1513 } // namespace dart |
OLD | NEW |