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 "platform/globals.h" | 5 #include "platform/globals.h" |
6 #ifndef PRODUCT | 6 #ifndef PRODUCT |
7 | 7 |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <cstdlib> | 10 #include <cstdlib> |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // cached block is being operated on. | 93 // cached block is being operated on. |
94 // - |Thread::thread_list_lock_| This lock is held when iterating over | 94 // - |Thread::thread_list_lock_| This lock is held when iterating over |
95 // |Thread|s. | 95 // |Thread|s. |
96 // | 96 // |
97 // Locks must always be taken in the following order: | 97 // Locks must always be taken in the following order: |
98 // |Thread::thread_list_lock_| | 98 // |Thread::thread_list_lock_| |
99 // |Thread::timeline_block_lock_| | 99 // |Thread::timeline_block_lock_| |
100 // |TimelineEventRecorder::lock_| | 100 // |TimelineEventRecorder::lock_| |
101 // | 101 // |
102 | 102 |
103 | |
104 static TimelineEventRecorder* CreateTimelineRecorder() { | 103 static TimelineEventRecorder* CreateTimelineRecorder() { |
105 // Some flags require that we use the endless recorder. | 104 // Some flags require that we use the endless recorder. |
106 const bool use_endless_recorder = | 105 const bool use_endless_recorder = |
107 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; | 106 (FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline; |
108 | 107 |
109 const bool use_startup_recorder = FLAG_startup_timeline; | 108 const bool use_startup_recorder = FLAG_startup_timeline; |
110 const bool use_systrace_recorder = FLAG_systrace_timeline; | 109 const bool use_systrace_recorder = FLAG_systrace_timeline; |
111 | 110 |
112 const char* flag = FLAG_timeline_recorder; | 111 const char* flag = FLAG_timeline_recorder; |
113 | 112 |
(...skipping 29 matching lines...) Expand all Loading... |
143 } | 142 } |
144 | 143 |
145 if (FLAG_trace_timeline) { | 144 if (FLAG_trace_timeline) { |
146 THR_Print("Using the ring timeline recorder.\n"); | 145 THR_Print("Using the ring timeline recorder.\n"); |
147 } | 146 } |
148 | 147 |
149 // Always fall back to the ring recorder. | 148 // Always fall back to the ring recorder. |
150 return new TimelineEventRingRecorder(); | 149 return new TimelineEventRingRecorder(); |
151 } | 150 } |
152 | 151 |
153 | |
154 // Returns a caller freed array of stream names in FLAG_timeline_streams. | 152 // Returns a caller freed array of stream names in FLAG_timeline_streams. |
155 static MallocGrowableArray<char*>* GetEnabledByDefaultTimelineStreams() { | 153 static MallocGrowableArray<char*>* GetEnabledByDefaultTimelineStreams() { |
156 MallocGrowableArray<char*>* result = new MallocGrowableArray<char*>(); | 154 MallocGrowableArray<char*>* result = new MallocGrowableArray<char*>(); |
157 if (FLAG_timeline_streams == NULL) { | 155 if (FLAG_timeline_streams == NULL) { |
158 // Nothing set. | 156 // Nothing set. |
159 return result; | 157 return result; |
160 } | 158 } |
161 char* save_ptr; // Needed for strtok_r. | 159 char* save_ptr; // Needed for strtok_r. |
162 // strtok modifies arg 1 so we make a copy of it. | 160 // strtok modifies arg 1 so we make a copy of it. |
163 char* streams = strdup(FLAG_timeline_streams); | 161 char* streams = strdup(FLAG_timeline_streams); |
164 char* token = strtok_r(streams, ",", &save_ptr); | 162 char* token = strtok_r(streams, ",", &save_ptr); |
165 while (token != NULL) { | 163 while (token != NULL) { |
166 result->Add(strdup(token)); | 164 result->Add(strdup(token)); |
167 token = strtok_r(NULL, ",", &save_ptr); | 165 token = strtok_r(NULL, ",", &save_ptr); |
168 } | 166 } |
169 free(streams); | 167 free(streams); |
170 return result; | 168 return result; |
171 } | 169 } |
172 | 170 |
173 | |
174 // Frees the result of |GetEnabledByDefaultTimelineStreams|. | 171 // Frees the result of |GetEnabledByDefaultTimelineStreams|. |
175 static void FreeEnabledByDefaultTimelineStreams( | 172 static void FreeEnabledByDefaultTimelineStreams( |
176 MallocGrowableArray<char*>* streams) { | 173 MallocGrowableArray<char*>* streams) { |
177 if (streams == NULL) { | 174 if (streams == NULL) { |
178 return; | 175 return; |
179 } | 176 } |
180 for (intptr_t i = 0; i < streams->length(); i++) { | 177 for (intptr_t i = 0; i < streams->length(); i++) { |
181 free((*streams)[i]); | 178 free((*streams)[i]); |
182 } | 179 } |
183 delete streams; | 180 delete streams; |
184 } | 181 } |
185 | 182 |
186 | |
187 // Returns true if |streams| contains |stream| or "all". Not case sensitive. | 183 // Returns true if |streams| contains |stream| or "all". Not case sensitive. |
188 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { | 184 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { |
189 if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || | 185 if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || |
190 FLAG_startup_timeline) { | 186 FLAG_startup_timeline) { |
191 return true; | 187 return true; |
192 } | 188 } |
193 for (intptr_t i = 0; i < streams->length(); i++) { | 189 for (intptr_t i = 0; i < streams->length(); i++) { |
194 const char* checked_stream = (*streams)[i]; | 190 const char* checked_stream = (*streams)[i]; |
195 if ((strstr(checked_stream, "all") != NULL) || | 191 if ((strstr(checked_stream, "all") != NULL) || |
196 (strstr(checked_stream, stream) != NULL)) { | 192 (strstr(checked_stream, stream) != NULL)) { |
197 return true; | 193 return true; |
198 } | 194 } |
199 } | 195 } |
200 return false; | 196 return false; |
201 } | 197 } |
202 | 198 |
203 | |
204 void Timeline::InitOnce() { | 199 void Timeline::InitOnce() { |
205 ASSERT(recorder_ == NULL); | 200 ASSERT(recorder_ == NULL); |
206 recorder_ = CreateTimelineRecorder(); | 201 recorder_ = CreateTimelineRecorder(); |
207 ASSERT(recorder_ != NULL); | 202 ASSERT(recorder_ != NULL); |
208 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); | 203 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); |
209 // Global overrides. | 204 // Global overrides. |
210 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ | 205 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ |
211 stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); | 206 stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); |
212 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) | 207 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) |
213 #undef TIMELINE_STREAM_FLAG_DEFAULT | 208 #undef TIMELINE_STREAM_FLAG_DEFAULT |
214 | 209 |
215 if (Timeline::stream_Embedder_.enabled() && | 210 if (Timeline::stream_Embedder_.enabled() && |
216 (Timeline::get_start_recording_cb() != NULL)) { | 211 (Timeline::get_start_recording_cb() != NULL)) { |
217 Timeline::get_start_recording_cb()(); | 212 Timeline::get_start_recording_cb()(); |
218 } | 213 } |
219 } | 214 } |
220 | 215 |
221 | |
222 void Timeline::StreamStateChange(const char* stream_name, | 216 void Timeline::StreamStateChange(const char* stream_name, |
223 bool prev, | 217 bool prev, |
224 bool curr) { | 218 bool curr) { |
225 if (prev == curr) { | 219 if (prev == curr) { |
226 return; | 220 return; |
227 } | 221 } |
228 if (strcmp(stream_name, "Embedder") == 0) { | 222 if (strcmp(stream_name, "Embedder") == 0) { |
229 if (curr && (Timeline::get_start_recording_cb() != NULL)) { | 223 if (curr && (Timeline::get_start_recording_cb() != NULL)) { |
230 Timeline::get_start_recording_cb()(); | 224 Timeline::get_start_recording_cb()(); |
231 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { | 225 } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) { |
232 Timeline::get_stop_recording_cb()(); | 226 Timeline::get_stop_recording_cb()(); |
233 } | 227 } |
234 } | 228 } |
235 } | 229 } |
236 | 230 |
237 | |
238 void Timeline::Shutdown() { | 231 void Timeline::Shutdown() { |
239 ASSERT(recorder_ != NULL); | 232 ASSERT(recorder_ != NULL); |
240 | 233 |
241 if (Timeline::stream_Embedder_.enabled() && | 234 if (Timeline::stream_Embedder_.enabled() && |
242 (Timeline::get_stop_recording_cb() != NULL)) { | 235 (Timeline::get_stop_recording_cb() != NULL)) { |
243 Timeline::get_stop_recording_cb()(); | 236 Timeline::get_stop_recording_cb()(); |
244 } | 237 } |
245 | 238 |
246 if (FLAG_timeline_dir != NULL) { | 239 if (FLAG_timeline_dir != NULL) { |
247 recorder_->WriteTo(FLAG_timeline_dir); | 240 recorder_->WriteTo(FLAG_timeline_dir); |
248 } | 241 } |
249 | 242 |
250 // Disable global streams. | 243 // Disable global streams. |
251 #define TIMELINE_STREAM_DISABLE(name, not_used) \ | 244 #define TIMELINE_STREAM_DISABLE(name, not_used) \ |
252 Timeline::stream_##name##_.set_enabled(false); | 245 Timeline::stream_##name##_.set_enabled(false); |
253 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) | 246 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) |
254 #undef TIMELINE_STREAM_DISABLE | 247 #undef TIMELINE_STREAM_DISABLE |
255 delete recorder_; | 248 delete recorder_; |
256 recorder_ = NULL; | 249 recorder_ = NULL; |
257 if (enabled_streams_ != NULL) { | 250 if (enabled_streams_ != NULL) { |
258 FreeEnabledByDefaultTimelineStreams(enabled_streams_); | 251 FreeEnabledByDefaultTimelineStreams(enabled_streams_); |
259 enabled_streams_ = NULL; | 252 enabled_streams_ = NULL; |
260 } | 253 } |
261 } | 254 } |
262 | 255 |
263 | |
264 TimelineEventRecorder* Timeline::recorder() { | 256 TimelineEventRecorder* Timeline::recorder() { |
265 return recorder_; | 257 return recorder_; |
266 } | 258 } |
267 | 259 |
268 | |
269 void Timeline::ReclaimCachedBlocksFromThreads() { | 260 void Timeline::ReclaimCachedBlocksFromThreads() { |
270 TimelineEventRecorder* recorder = Timeline::recorder(); | 261 TimelineEventRecorder* recorder = Timeline::recorder(); |
271 if (recorder == NULL) { | 262 if (recorder == NULL) { |
272 return; | 263 return; |
273 } | 264 } |
274 | 265 |
275 // Iterate over threads. | 266 // Iterate over threads. |
276 OSThreadIterator it; | 267 OSThreadIterator it; |
277 while (it.HasNext()) { | 268 while (it.HasNext()) { |
278 OSThread* thread = it.Next(); | 269 OSThread* thread = it.Next(); |
279 MutexLocker ml(thread->timeline_block_lock()); | 270 MutexLocker ml(thread->timeline_block_lock()); |
280 // Grab block and clear it. | 271 // Grab block and clear it. |
281 TimelineEventBlock* block = thread->timeline_block(); | 272 TimelineEventBlock* block = thread->timeline_block(); |
282 thread->set_timeline_block(NULL); | 273 thread->set_timeline_block(NULL); |
283 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here | 274 // TODO(johnmccutchan): Consider dropping the timeline_block_lock here |
284 // if we can do it everywhere. This would simplify the lock ordering | 275 // if we can do it everywhere. This would simplify the lock ordering |
285 // requirements. | 276 // requirements. |
286 recorder->FinishBlock(block); | 277 recorder->FinishBlock(block); |
287 } | 278 } |
288 } | 279 } |
289 | 280 |
290 | |
291 void Timeline::PrintFlagsToJSON(JSONStream* js) { | 281 void Timeline::PrintFlagsToJSON(JSONStream* js) { |
292 JSONObject obj(js); | 282 JSONObject obj(js); |
293 obj.AddProperty("type", "TimelineFlags"); | 283 obj.AddProperty("type", "TimelineFlags"); |
294 TimelineEventRecorder* recorder = Timeline::recorder(); | 284 TimelineEventRecorder* recorder = Timeline::recorder(); |
295 if (recorder == NULL) { | 285 if (recorder == NULL) { |
296 obj.AddProperty("recorderName", "null"); | 286 obj.AddProperty("recorderName", "null"); |
297 } else { | 287 } else { |
298 obj.AddProperty("recorderName", recorder->name()); | 288 obj.AddProperty("recorderName", recorder->name()); |
299 } | 289 } |
300 { | 290 { |
301 JSONArray availableStreams(&obj, "availableStreams"); | 291 JSONArray availableStreams(&obj, "availableStreams"); |
302 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); | 292 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); |
303 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); | 293 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); |
304 #undef ADD_STREAM_NAME | 294 #undef ADD_STREAM_NAME |
305 } | 295 } |
306 { | 296 { |
307 JSONArray recordedStreams(&obj, "recordedStreams"); | 297 JSONArray recordedStreams(&obj, "recordedStreams"); |
308 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ | 298 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ |
309 if (stream_##name##_.enabled()) { \ | 299 if (stream_##name##_.enabled()) { \ |
310 recordedStreams.AddValue(#name); \ | 300 recordedStreams.AddValue(#name); \ |
311 } | 301 } |
312 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); | 302 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); |
313 #undef ADD_RECORDED_STREAM_NAME | 303 #undef ADD_RECORDED_STREAM_NAME |
314 } | 304 } |
315 } | 305 } |
316 | 306 |
317 | |
318 void Timeline::Clear() { | 307 void Timeline::Clear() { |
319 TimelineEventRecorder* recorder = Timeline::recorder(); | 308 TimelineEventRecorder* recorder = Timeline::recorder(); |
320 if (recorder == NULL) { | 309 if (recorder == NULL) { |
321 return; | 310 return; |
322 } | 311 } |
323 ReclaimCachedBlocksFromThreads(); | 312 ReclaimCachedBlocksFromThreads(); |
324 recorder->Clear(); | 313 recorder->Clear(); |
325 } | 314 } |
326 | 315 |
327 | |
328 TimelineEventRecorder* Timeline::recorder_ = NULL; | 316 TimelineEventRecorder* Timeline::recorder_ = NULL; |
329 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; | 317 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; |
330 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; | 318 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; |
331 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; | 319 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; |
332 | 320 |
333 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ | 321 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ |
334 TimelineStream Timeline::stream_##name##_; | 322 TimelineStream Timeline::stream_##name##_; |
335 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) | 323 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) |
336 #undef TIMELINE_STREAM_DEFINE | 324 #undef TIMELINE_STREAM_DEFINE |
337 | 325 |
338 TimelineEvent::TimelineEvent() | 326 TimelineEvent::TimelineEvent() |
339 : timestamp0_(0), | 327 : timestamp0_(0), |
340 timestamp1_(0), | 328 timestamp1_(0), |
341 thread_timestamp0_(-1), | 329 thread_timestamp0_(-1), |
342 thread_timestamp1_(-1), | 330 thread_timestamp1_(-1), |
343 arguments_(NULL), | 331 arguments_(NULL), |
344 arguments_length_(0), | 332 arguments_length_(0), |
345 state_(0), | 333 state_(0), |
346 label_(NULL), | 334 label_(NULL), |
347 category_(""), | 335 category_(""), |
348 thread_(OSThread::kInvalidThreadId), | 336 thread_(OSThread::kInvalidThreadId), |
349 isolate_id_(ILLEGAL_PORT) {} | 337 isolate_id_(ILLEGAL_PORT) {} |
350 | 338 |
351 | |
352 TimelineEvent::~TimelineEvent() { | 339 TimelineEvent::~TimelineEvent() { |
353 Reset(); | 340 Reset(); |
354 } | 341 } |
355 | 342 |
356 | |
357 void TimelineEvent::Reset() { | 343 void TimelineEvent::Reset() { |
358 if (owns_label() && label_ != NULL) { | 344 if (owns_label() && label_ != NULL) { |
359 free(const_cast<char*>(label_)); | 345 free(const_cast<char*>(label_)); |
360 } | 346 } |
361 state_ = 0; | 347 state_ = 0; |
362 thread_ = OSThread::kInvalidThreadId; | 348 thread_ = OSThread::kInvalidThreadId; |
363 isolate_id_ = ILLEGAL_PORT; | 349 isolate_id_ = ILLEGAL_PORT; |
364 category_ = ""; | 350 category_ = ""; |
365 label_ = NULL; | 351 label_ = NULL; |
366 FreeArguments(); | 352 FreeArguments(); |
367 set_pre_serialized_json(false); | 353 set_pre_serialized_json(false); |
368 set_event_type(kNone); | 354 set_event_type(kNone); |
369 set_owns_label(false); | 355 set_owns_label(false); |
370 } | 356 } |
371 | 357 |
372 | |
373 void TimelineEvent::AsyncBegin(const char* label, | 358 void TimelineEvent::AsyncBegin(const char* label, |
374 int64_t async_id, | 359 int64_t async_id, |
375 int64_t micros) { | 360 int64_t micros) { |
376 Init(kAsyncBegin, label); | 361 Init(kAsyncBegin, label); |
377 set_timestamp0(micros); | 362 set_timestamp0(micros); |
378 // Overload timestamp1_ with the async_id. | 363 // Overload timestamp1_ with the async_id. |
379 set_timestamp1(async_id); | 364 set_timestamp1(async_id); |
380 } | 365 } |
381 | 366 |
382 | |
383 void TimelineEvent::AsyncInstant(const char* label, | 367 void TimelineEvent::AsyncInstant(const char* label, |
384 int64_t async_id, | 368 int64_t async_id, |
385 int64_t micros) { | 369 int64_t micros) { |
386 Init(kAsyncInstant, label); | 370 Init(kAsyncInstant, label); |
387 set_timestamp0(micros); | 371 set_timestamp0(micros); |
388 // Overload timestamp1_ with the async_id. | 372 // Overload timestamp1_ with the async_id. |
389 set_timestamp1(async_id); | 373 set_timestamp1(async_id); |
390 } | 374 } |
391 | 375 |
392 | |
393 void TimelineEvent::AsyncEnd(const char* label, | 376 void TimelineEvent::AsyncEnd(const char* label, |
394 int64_t async_id, | 377 int64_t async_id, |
395 int64_t micros) { | 378 int64_t micros) { |
396 Init(kAsyncEnd, label); | 379 Init(kAsyncEnd, label); |
397 set_timestamp0(micros); | 380 set_timestamp0(micros); |
398 // Overload timestamp1_ with the async_id. | 381 // Overload timestamp1_ with the async_id. |
399 set_timestamp1(async_id); | 382 set_timestamp1(async_id); |
400 } | 383 } |
401 | 384 |
402 | |
403 void TimelineEvent::DurationBegin(const char* label, | 385 void TimelineEvent::DurationBegin(const char* label, |
404 int64_t micros, | 386 int64_t micros, |
405 int64_t thread_micros) { | 387 int64_t thread_micros) { |
406 Init(kDuration, label); | 388 Init(kDuration, label); |
407 set_timestamp0(micros); | 389 set_timestamp0(micros); |
408 set_thread_timestamp0(thread_micros); | 390 set_thread_timestamp0(thread_micros); |
409 } | 391 } |
410 | 392 |
411 | |
412 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { | 393 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { |
413 ASSERT(timestamp1_ == 0); | 394 ASSERT(timestamp1_ == 0); |
414 set_timestamp1(micros); | 395 set_timestamp1(micros); |
415 set_thread_timestamp1(thread_micros); | 396 set_thread_timestamp1(thread_micros); |
416 } | 397 } |
417 | 398 |
418 | |
419 void TimelineEvent::Instant(const char* label, int64_t micros) { | 399 void TimelineEvent::Instant(const char* label, int64_t micros) { |
420 Init(kInstant, label); | 400 Init(kInstant, label); |
421 set_timestamp0(micros); | 401 set_timestamp0(micros); |
422 } | 402 } |
423 | 403 |
424 | |
425 void TimelineEvent::Duration(const char* label, | 404 void TimelineEvent::Duration(const char* label, |
426 int64_t start_micros, | 405 int64_t start_micros, |
427 int64_t end_micros, | 406 int64_t end_micros, |
428 int64_t thread_start_micros, | 407 int64_t thread_start_micros, |
429 int64_t thread_end_micros) { | 408 int64_t thread_end_micros) { |
430 Init(kDuration, label); | 409 Init(kDuration, label); |
431 set_timestamp0(start_micros); | 410 set_timestamp0(start_micros); |
432 set_timestamp1(end_micros); | 411 set_timestamp1(end_micros); |
433 set_thread_timestamp0(thread_start_micros); | 412 set_thread_timestamp0(thread_start_micros); |
434 set_thread_timestamp1(thread_end_micros); | 413 set_thread_timestamp1(thread_end_micros); |
435 } | 414 } |
436 | 415 |
437 | |
438 void TimelineEvent::Begin(const char* label, | 416 void TimelineEvent::Begin(const char* label, |
439 int64_t micros, | 417 int64_t micros, |
440 int64_t thread_micros) { | 418 int64_t thread_micros) { |
441 Init(kBegin, label); | 419 Init(kBegin, label); |
442 set_timestamp0(micros); | 420 set_timestamp0(micros); |
443 set_thread_timestamp0(thread_micros); | 421 set_thread_timestamp0(thread_micros); |
444 } | 422 } |
445 | 423 |
446 | |
447 void TimelineEvent::End(const char* label, | 424 void TimelineEvent::End(const char* label, |
448 int64_t micros, | 425 int64_t micros, |
449 int64_t thread_micros) { | 426 int64_t thread_micros) { |
450 Init(kEnd, label); | 427 Init(kEnd, label); |
451 set_timestamp0(micros); | 428 set_timestamp0(micros); |
452 set_thread_timestamp0(thread_micros); | 429 set_thread_timestamp0(thread_micros); |
453 } | 430 } |
454 | 431 |
455 | |
456 void TimelineEvent::Counter(const char* label, int64_t micros) { | 432 void TimelineEvent::Counter(const char* label, int64_t micros) { |
457 Init(kCounter, label); | 433 Init(kCounter, label); |
458 set_timestamp0(micros); | 434 set_timestamp0(micros); |
459 } | 435 } |
460 | 436 |
461 | |
462 void TimelineEvent::Metadata(const char* label, int64_t micros) { | 437 void TimelineEvent::Metadata(const char* label, int64_t micros) { |
463 Init(kMetadata, label); | 438 Init(kMetadata, label); |
464 set_timestamp0(micros); | 439 set_timestamp0(micros); |
465 } | 440 } |
466 | 441 |
467 | |
468 void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) { | 442 void TimelineEvent::CompleteWithPreSerializedJSON(const char* json) { |
469 set_pre_serialized_json(true); | 443 set_pre_serialized_json(true); |
470 SetNumArguments(1); | 444 SetNumArguments(1); |
471 CopyArgument(0, "Dart", json); | 445 CopyArgument(0, "Dart", json); |
472 Complete(); | 446 Complete(); |
473 } | 447 } |
474 | 448 |
475 | |
476 void TimelineEvent::SetNumArguments(intptr_t length) { | 449 void TimelineEvent::SetNumArguments(intptr_t length) { |
477 // Cannot call this twice. | 450 // Cannot call this twice. |
478 ASSERT(arguments_ == NULL); | 451 ASSERT(arguments_ == NULL); |
479 ASSERT(arguments_length_ == 0); | 452 ASSERT(arguments_length_ == 0); |
480 if (length == 0) { | 453 if (length == 0) { |
481 return; | 454 return; |
482 } | 455 } |
483 arguments_length_ = length; | 456 arguments_length_ = length; |
484 arguments_ = reinterpret_cast<TimelineEventArgument*>( | 457 arguments_ = reinterpret_cast<TimelineEventArgument*>( |
485 calloc(sizeof(TimelineEventArgument), length)); | 458 calloc(sizeof(TimelineEventArgument), length)); |
486 } | 459 } |
487 | 460 |
488 | |
489 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { | 461 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { |
490 ASSERT(i >= 0); | 462 ASSERT(i >= 0); |
491 ASSERT(i < arguments_length_); | 463 ASSERT(i < arguments_length_); |
492 arguments_[i].name = name; | 464 arguments_[i].name = name; |
493 arguments_[i].value = argument; | 465 arguments_[i].value = argument; |
494 } | 466 } |
495 | 467 |
496 | |
497 void TimelineEvent::FormatArgument(intptr_t i, | 468 void TimelineEvent::FormatArgument(intptr_t i, |
498 const char* name, | 469 const char* name, |
499 const char* fmt, | 470 const char* fmt, |
500 ...) { | 471 ...) { |
501 ASSERT(i >= 0); | 472 ASSERT(i >= 0); |
502 ASSERT(i < arguments_length_); | 473 ASSERT(i < arguments_length_); |
503 va_list args; | 474 va_list args; |
504 va_start(args, fmt); | 475 va_start(args, fmt); |
505 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 476 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
506 va_end(args); | 477 va_end(args); |
507 | 478 |
508 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 479 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
509 va_list args2; | 480 va_list args2; |
510 va_start(args2, fmt); | 481 va_start(args2, fmt); |
511 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 482 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
512 va_end(args2); | 483 va_end(args2); |
513 | 484 |
514 SetArgument(i, name, buffer); | 485 SetArgument(i, name, buffer); |
515 } | 486 } |
516 | 487 |
517 | |
518 void TimelineEvent::CopyArgument(intptr_t i, | 488 void TimelineEvent::CopyArgument(intptr_t i, |
519 const char* name, | 489 const char* name, |
520 const char* argument) { | 490 const char* argument) { |
521 SetArgument(i, name, strdup(argument)); | 491 SetArgument(i, name, strdup(argument)); |
522 } | 492 } |
523 | 493 |
524 | |
525 void TimelineEvent::StealArguments(intptr_t arguments_length, | 494 void TimelineEvent::StealArguments(intptr_t arguments_length, |
526 TimelineEventArgument* arguments) { | 495 TimelineEventArgument* arguments) { |
527 arguments_length_ = arguments_length; | 496 arguments_length_ = arguments_length; |
528 arguments_ = arguments; | 497 arguments_ = arguments; |
529 } | 498 } |
530 | 499 |
531 | |
532 #if defined(HOST_OS_FUCHSIA) | 500 #if defined(HOST_OS_FUCHSIA) |
533 | |
534 // TODO(zra): The functions below emit Dart's timeline events all as category | 501 // TODO(zra): The functions below emit Dart's timeline events all as category |
535 // "dart". Instead, we could have finer-grained categories that make use of | 502 // "dart". Instead, we could have finer-grained categories that make use of |
536 // the name of the timeline stream, e.g. "VM", "GC", etc. | 503 // the name of the timeline stream, e.g. "VM", "GC", etc. |
537 | 504 |
538 #define FUCHSIA_EVENT_ARGS_LIST(V) \ | 505 #define FUCHSIA_EVENT_ARGS_LIST(V) \ |
539 V(Begin, TRACE_DURATION_BEGIN) \ | 506 V(Begin, TRACE_DURATION_BEGIN) \ |
540 V(End, TRACE_DURATION_END) | 507 V(End, TRACE_DURATION_END) |
541 | 508 |
542 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ | 509 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ |
543 static void EmitFuchsia##__name##Event(const char* label, \ | 510 static void EmitFuchsia##__name##Event(const char* label, \ |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 } else { \ | 543 } else { \ |
577 __macro("dart", label, id, arguments[0].name, \ | 544 __macro("dart", label, id, arguments[0].name, \ |
578 const_cast<const char*>(arguments[0].value), arguments[1].name, \ | 545 const_cast<const char*>(arguments[0].value), arguments[1].name, \ |
579 const_cast<const char*>(arguments[1].value)); \ | 546 const_cast<const char*>(arguments[1].value)); \ |
580 } \ | 547 } \ |
581 } | 548 } |
582 | 549 |
583 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) | 550 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) |
584 #undef EMIT_FUCHSIA_EVENT | 551 #undef EMIT_FUCHSIA_EVENT |
585 | 552 |
586 | |
587 void TimelineEvent::EmitFuchsiaEvent() { | 553 void TimelineEvent::EmitFuchsiaEvent() { |
588 switch (event_type()) { | 554 switch (event_type()) { |
589 case kBegin: | 555 case kBegin: |
590 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); | 556 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); |
591 break; | 557 break; |
592 case kEnd: | 558 case kEnd: |
593 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); | 559 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); |
594 break; | 560 break; |
595 case kInstant: | 561 case kInstant: |
596 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, | 562 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, |
(...skipping 12 matching lines...) Expand all Loading... |
609 arguments_length_); | 575 arguments_length_); |
610 break; | 576 break; |
611 default: | 577 default: |
612 // TODO(zra): Figure out what to do with kDuration, kCounter, and | 578 // TODO(zra): Figure out what to do with kDuration, kCounter, and |
613 // kMetadata. | 579 // kMetadata. |
614 break; | 580 break; |
615 } | 581 } |
616 } | 582 } |
617 #endif | 583 #endif |
618 | 584 |
619 | |
620 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 585 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
621 ASSERT(buffer != NULL); | 586 ASSERT(buffer != NULL); |
622 ASSERT(buffer_size > 0); | 587 ASSERT(buffer_size > 0); |
623 buffer[0] = '\0'; | 588 buffer[0] = '\0'; |
624 intptr_t length = 0; | 589 intptr_t length = 0; |
625 int64_t pid = OS::ProcessId(); | 590 int64_t pid = OS::ProcessId(); |
626 switch (event_type()) { | 591 switch (event_type()) { |
627 case kBegin: { | 592 case kBegin: { |
628 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); | 593 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); |
629 } break; | 594 } break; |
630 case kEnd: { | 595 case kEnd: { |
631 length = OS::SNPrint(buffer, buffer_size, "E"); | 596 length = OS::SNPrint(buffer, buffer_size, "E"); |
632 } break; | 597 } break; |
633 case kCounter: { | 598 case kCounter: { |
634 if (arguments_length_ > 0) { | 599 if (arguments_length_ > 0) { |
635 // We only report the first counter value. | 600 // We only report the first counter value. |
636 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, | 601 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, |
637 label(), arguments_[0].value); | 602 label(), arguments_[0].value); |
638 } | 603 } |
639 } | 604 } |
640 default: | 605 default: |
641 // Ignore event types that we cannot serialize to the Systrace format. | 606 // Ignore event types that we cannot serialize to the Systrace format. |
642 break; | 607 break; |
643 } | 608 } |
644 return length; | 609 return length; |
645 } | 610 } |
646 | 611 |
647 | |
648 void TimelineEvent::Complete() { | 612 void TimelineEvent::Complete() { |
649 TimelineEventRecorder* recorder = Timeline::recorder(); | 613 TimelineEventRecorder* recorder = Timeline::recorder(); |
650 if (recorder != NULL) { | 614 if (recorder != NULL) { |
651 recorder->CompleteEvent(this); | 615 recorder->CompleteEvent(this); |
652 } | 616 } |
653 } | 617 } |
654 | 618 |
655 | |
656 void TimelineEvent::FreeArguments() { | 619 void TimelineEvent::FreeArguments() { |
657 if (arguments_ == NULL) { | 620 if (arguments_ == NULL) { |
658 return; | 621 return; |
659 } | 622 } |
660 for (intptr_t i = 0; i < arguments_length_; i++) { | 623 for (intptr_t i = 0; i < arguments_length_; i++) { |
661 free(arguments_[i].value); | 624 free(arguments_[i].value); |
662 } | 625 } |
663 free(arguments_); | 626 free(arguments_); |
664 arguments_ = NULL; | 627 arguments_ = NULL; |
665 arguments_length_ = 0; | 628 arguments_length_ = 0; |
666 } | 629 } |
667 | 630 |
668 | |
669 void TimelineEvent::StreamInit(TimelineStream* stream) { | 631 void TimelineEvent::StreamInit(TimelineStream* stream) { |
670 if (stream != NULL) { | 632 if (stream != NULL) { |
671 category_ = stream->name(); | 633 category_ = stream->name(); |
672 } else { | 634 } else { |
673 category_ = ""; | 635 category_ = ""; |
674 } | 636 } |
675 } | 637 } |
676 | 638 |
677 | |
678 void TimelineEvent::Init(EventType event_type, const char* label) { | 639 void TimelineEvent::Init(EventType event_type, const char* label) { |
679 ASSERT(label != NULL); | 640 ASSERT(label != NULL); |
680 state_ = 0; | 641 state_ = 0; |
681 timestamp0_ = 0; | 642 timestamp0_ = 0; |
682 timestamp1_ = 0; | 643 timestamp1_ = 0; |
683 thread_timestamp0_ = -1; | 644 thread_timestamp0_ = -1; |
684 thread_timestamp1_ = -1; | 645 thread_timestamp1_ = -1; |
685 OSThread* os_thread = OSThread::Current(); | 646 OSThread* os_thread = OSThread::Current(); |
686 ASSERT(os_thread != NULL); | 647 ASSERT(os_thread != NULL); |
687 thread_ = os_thread->trace_id(); | 648 thread_ = os_thread->trace_id(); |
688 Isolate* isolate = Isolate::Current(); | 649 Isolate* isolate = Isolate::Current(); |
689 if (isolate != NULL) { | 650 if (isolate != NULL) { |
690 isolate_id_ = isolate->main_port(); | 651 isolate_id_ = isolate->main_port(); |
691 } else { | 652 } else { |
692 isolate_id_ = ILLEGAL_PORT; | 653 isolate_id_ = ILLEGAL_PORT; |
693 } | 654 } |
694 label_ = label; | 655 label_ = label; |
695 FreeArguments(); | 656 FreeArguments(); |
696 set_pre_serialized_json(false); | 657 set_pre_serialized_json(false); |
697 set_event_type(event_type); | 658 set_event_type(event_type); |
698 set_owns_label(false); | 659 set_owns_label(false); |
699 } | 660 } |
700 | 661 |
701 | |
702 bool TimelineEvent::Within(int64_t time_origin_micros, | 662 bool TimelineEvent::Within(int64_t time_origin_micros, |
703 int64_t time_extent_micros) { | 663 int64_t time_extent_micros) { |
704 if ((time_origin_micros == -1) || (time_extent_micros == -1)) { | 664 if ((time_origin_micros == -1) || (time_extent_micros == -1)) { |
705 // No time range specified. | 665 // No time range specified. |
706 return true; | 666 return true; |
707 } | 667 } |
708 if (IsFinishedDuration()) { | 668 if (IsFinishedDuration()) { |
709 // Event is from e_t0 to e_t1. | 669 // Event is from e_t0 to e_t1. |
710 int64_t e_t0 = TimeOrigin(); | 670 int64_t e_t0 = TimeOrigin(); |
711 int64_t e_t1 = TimeEnd(); | 671 int64_t e_t1 = TimeEnd(); |
712 ASSERT(e_t0 <= e_t1); | 672 ASSERT(e_t0 <= e_t1); |
713 // Range is from r_t0 to r_t1. | 673 // Range is from r_t0 to r_t1. |
714 int64_t r_t0 = time_origin_micros; | 674 int64_t r_t0 = time_origin_micros; |
715 int64_t r_t1 = time_origin_micros + time_extent_micros; | 675 int64_t r_t1 = time_origin_micros + time_extent_micros; |
716 ASSERT(r_t0 <= r_t1); | 676 ASSERT(r_t0 <= r_t1); |
717 return !((r_t1 < e_t0) || (e_t1 < r_t0)); | 677 return !((r_t1 < e_t0) || (e_t1 < r_t0)); |
718 } | 678 } |
719 int64_t delta = TimeOrigin() - time_origin_micros; | 679 int64_t delta = TimeOrigin() - time_origin_micros; |
720 return (delta >= 0) && (delta <= time_extent_micros); | 680 return (delta >= 0) && (delta <= time_extent_micros); |
721 } | 681 } |
722 | 682 |
723 | |
724 const char* TimelineEvent::GetSerializedJSON() const { | 683 const char* TimelineEvent::GetSerializedJSON() const { |
725 ASSERT(pre_serialized_json()); | 684 ASSERT(pre_serialized_json()); |
726 ASSERT(arguments_length_ == 1); | 685 ASSERT(arguments_length_ == 1); |
727 ASSERT(arguments_ != NULL); | 686 ASSERT(arguments_ != NULL); |
728 return arguments_[0].value; | 687 return arguments_[0].value; |
729 } | 688 } |
730 | 689 |
731 | |
732 void TimelineEvent::PrintJSON(JSONStream* stream) const { | 690 void TimelineEvent::PrintJSON(JSONStream* stream) const { |
733 if (!FLAG_support_service) { | 691 if (!FLAG_support_service) { |
734 return; | 692 return; |
735 } | 693 } |
736 if (pre_serialized_json()) { | 694 if (pre_serialized_json()) { |
737 // Event has already been serialized into JSON- just append the | 695 // Event has already been serialized into JSON- just append the |
738 // raw data. | 696 // raw data. |
739 stream->AppendSerializedObject(GetSerializedJSON()); | 697 stream->AppendSerializedObject(GetSerializedJSON()); |
740 return; | 698 return; |
741 } | 699 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 args.AddProperty(arg.name, arg.value); | 754 args.AddProperty(arg.name, arg.value); |
797 } | 755 } |
798 if (isolate_id_ != ILLEGAL_PORT) { | 756 if (isolate_id_ != ILLEGAL_PORT) { |
799 // If we have one, append the isolate id. | 757 // If we have one, append the isolate id. |
800 args.AddPropertyF("isolateNumber", "%" Pd64 "", | 758 args.AddPropertyF("isolateNumber", "%" Pd64 "", |
801 static_cast<int64_t>(isolate_id_)); | 759 static_cast<int64_t>(isolate_id_)); |
802 } | 760 } |
803 } | 761 } |
804 } | 762 } |
805 | 763 |
806 | |
807 int64_t TimelineEvent::TimeOrigin() const { | 764 int64_t TimelineEvent::TimeOrigin() const { |
808 return timestamp0_; | 765 return timestamp0_; |
809 } | 766 } |
810 | 767 |
811 | |
812 int64_t TimelineEvent::AsyncId() const { | 768 int64_t TimelineEvent::AsyncId() const { |
813 return timestamp1_; | 769 return timestamp1_; |
814 } | 770 } |
815 | 771 |
816 | |
817 int64_t TimelineEvent::LowTime() const { | 772 int64_t TimelineEvent::LowTime() const { |
818 return timestamp0_; | 773 return timestamp0_; |
819 } | 774 } |
820 | 775 |
821 | |
822 int64_t TimelineEvent::HighTime() const { | 776 int64_t TimelineEvent::HighTime() const { |
823 if (event_type() == kDuration) { | 777 if (event_type() == kDuration) { |
824 return timestamp1_; | 778 return timestamp1_; |
825 } else { | 779 } else { |
826 return timestamp0_; | 780 return timestamp0_; |
827 } | 781 } |
828 } | 782 } |
829 | 783 |
830 | |
831 int64_t TimelineEvent::TimeDuration() const { | 784 int64_t TimelineEvent::TimeDuration() const { |
832 if (timestamp1_ == 0) { | 785 if (timestamp1_ == 0) { |
833 // This duration is still open, use current time as end. | 786 // This duration is still open, use current time as end. |
834 return OS::GetCurrentMonotonicMicros() - timestamp0_; | 787 return OS::GetCurrentMonotonicMicros() - timestamp0_; |
835 } | 788 } |
836 return timestamp1_ - timestamp0_; | 789 return timestamp1_ - timestamp0_; |
837 } | 790 } |
838 | 791 |
839 | |
840 bool TimelineEvent::HasThreadCPUTime() const { | 792 bool TimelineEvent::HasThreadCPUTime() const { |
841 return (thread_timestamp0_ != -1); | 793 return (thread_timestamp0_ != -1); |
842 } | 794 } |
843 | 795 |
844 | |
845 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { | 796 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { |
846 ASSERT(HasThreadCPUTime()); | 797 ASSERT(HasThreadCPUTime()); |
847 return thread_timestamp0_; | 798 return thread_timestamp0_; |
848 } | 799 } |
849 | 800 |
850 | |
851 int64_t TimelineEvent::ThreadCPUTimeDuration() const { | 801 int64_t TimelineEvent::ThreadCPUTimeDuration() const { |
852 ASSERT(HasThreadCPUTime()); | 802 ASSERT(HasThreadCPUTime()); |
853 if (thread_timestamp1_ == -1) { | 803 if (thread_timestamp1_ == -1) { |
854 // This duration is still open, use current time as end. | 804 // This duration is still open, use current time as end. |
855 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; | 805 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; |
856 } | 806 } |
857 return thread_timestamp1_ - thread_timestamp0_; | 807 return thread_timestamp1_ - thread_timestamp0_; |
858 } | 808 } |
859 | 809 |
860 | |
861 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} | 810 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} |
862 | 811 |
863 | |
864 void TimelineStream::Init(const char* name, bool enabled) { | 812 void TimelineStream::Init(const char* name, bool enabled) { |
865 name_ = name; | 813 name_ = name; |
866 enabled_ = enabled; | 814 enabled_ = enabled; |
867 } | 815 } |
868 | 816 |
869 | |
870 TimelineEvent* TimelineStream::StartEvent() { | 817 TimelineEvent* TimelineStream::StartEvent() { |
871 TimelineEventRecorder* recorder = Timeline::recorder(); | 818 TimelineEventRecorder* recorder = Timeline::recorder(); |
872 if (!enabled() || (recorder == NULL)) { | 819 if (!enabled() || (recorder == NULL)) { |
873 return NULL; | 820 return NULL; |
874 } | 821 } |
875 ASSERT(name_ != NULL); | 822 ASSERT(name_ != NULL); |
876 TimelineEvent* event = recorder->StartEvent(); | 823 TimelineEvent* event = recorder->StartEvent(); |
877 if (event != NULL) { | 824 if (event != NULL) { |
878 event->StreamInit(this); | 825 event->StreamInit(this); |
879 } | 826 } |
880 return event; | 827 return event; |
881 } | 828 } |
882 | 829 |
883 | |
884 TimelineEventScope::TimelineEventScope(TimelineStream* stream, | 830 TimelineEventScope::TimelineEventScope(TimelineStream* stream, |
885 const char* label) | 831 const char* label) |
886 : StackResource(reinterpret_cast<Thread*>(NULL)), | 832 : StackResource(reinterpret_cast<Thread*>(NULL)), |
887 stream_(stream), | 833 stream_(stream), |
888 label_(label), | 834 label_(label), |
889 arguments_(NULL), | 835 arguments_(NULL), |
890 arguments_length_(0), | 836 arguments_length_(0), |
891 enabled_(false) { | 837 enabled_(false) { |
892 Init(); | 838 Init(); |
893 } | 839 } |
894 | 840 |
895 | |
896 TimelineEventScope::TimelineEventScope(Thread* thread, | 841 TimelineEventScope::TimelineEventScope(Thread* thread, |
897 TimelineStream* stream, | 842 TimelineStream* stream, |
898 const char* label) | 843 const char* label) |
899 : StackResource(thread), | 844 : StackResource(thread), |
900 stream_(stream), | 845 stream_(stream), |
901 label_(label), | 846 label_(label), |
902 arguments_(NULL), | 847 arguments_(NULL), |
903 arguments_length_(0), | 848 arguments_length_(0), |
904 enabled_(false) { | 849 enabled_(false) { |
905 Init(); | 850 Init(); |
906 } | 851 } |
907 | 852 |
908 | |
909 TimelineEventScope::~TimelineEventScope() { | 853 TimelineEventScope::~TimelineEventScope() { |
910 FreeArguments(); | 854 FreeArguments(); |
911 } | 855 } |
912 | 856 |
913 | |
914 void TimelineEventScope::Init() { | 857 void TimelineEventScope::Init() { |
915 ASSERT(enabled_ == false); | 858 ASSERT(enabled_ == false); |
916 ASSERT(label_ != NULL); | 859 ASSERT(label_ != NULL); |
917 ASSERT(stream_ != NULL); | 860 ASSERT(stream_ != NULL); |
918 if (!stream_->enabled()) { | 861 if (!stream_->enabled()) { |
919 // Stream is not enabled, do nothing. | 862 // Stream is not enabled, do nothing. |
920 return; | 863 return; |
921 } | 864 } |
922 enabled_ = true; | 865 enabled_ = true; |
923 } | 866 } |
924 | 867 |
925 | |
926 void TimelineEventScope::SetNumArguments(intptr_t length) { | 868 void TimelineEventScope::SetNumArguments(intptr_t length) { |
927 if (!enabled()) { | 869 if (!enabled()) { |
928 return; | 870 return; |
929 } | 871 } |
930 ASSERT(arguments_ == NULL); | 872 ASSERT(arguments_ == NULL); |
931 ASSERT(arguments_length_ == 0); | 873 ASSERT(arguments_length_ == 0); |
932 arguments_length_ = length; | 874 arguments_length_ = length; |
933 if (arguments_length_ == 0) { | 875 if (arguments_length_ == 0) { |
934 return; | 876 return; |
935 } | 877 } |
936 arguments_ = reinterpret_cast<TimelineEventArgument*>( | 878 arguments_ = reinterpret_cast<TimelineEventArgument*>( |
937 calloc(sizeof(TimelineEventArgument), length)); | 879 calloc(sizeof(TimelineEventArgument), length)); |
938 } | 880 } |
939 | 881 |
940 | |
941 // |name| must be a compile time constant. Takes ownership of |argumentp|. | 882 // |name| must be a compile time constant. Takes ownership of |argumentp|. |
942 void TimelineEventScope::SetArgument(intptr_t i, | 883 void TimelineEventScope::SetArgument(intptr_t i, |
943 const char* name, | 884 const char* name, |
944 char* argument) { | 885 char* argument) { |
945 if (!enabled()) { | 886 if (!enabled()) { |
946 return; | 887 return; |
947 } | 888 } |
948 ASSERT(i >= 0); | 889 ASSERT(i >= 0); |
949 ASSERT(i < arguments_length_); | 890 ASSERT(i < arguments_length_); |
950 arguments_[i].name = name; | 891 arguments_[i].name = name; |
951 arguments_[i].value = argument; | 892 arguments_[i].value = argument; |
952 } | 893 } |
953 | 894 |
954 | |
955 // |name| must be a compile time constant. Copies |argument|. | 895 // |name| must be a compile time constant. Copies |argument|. |
956 void TimelineEventScope::CopyArgument(intptr_t i, | 896 void TimelineEventScope::CopyArgument(intptr_t i, |
957 const char* name, | 897 const char* name, |
958 const char* argument) { | 898 const char* argument) { |
959 if (!enabled()) { | 899 if (!enabled()) { |
960 return; | 900 return; |
961 } | 901 } |
962 SetArgument(i, name, strdup(argument)); | 902 SetArgument(i, name, strdup(argument)); |
963 } | 903 } |
964 | 904 |
965 | |
966 void TimelineEventScope::FormatArgument(intptr_t i, | 905 void TimelineEventScope::FormatArgument(intptr_t i, |
967 const char* name, | 906 const char* name, |
968 const char* fmt, | 907 const char* fmt, |
969 ...) { | 908 ...) { |
970 if (!enabled()) { | 909 if (!enabled()) { |
971 return; | 910 return; |
972 } | 911 } |
973 va_list args; | 912 va_list args; |
974 va_start(args, fmt); | 913 va_start(args, fmt); |
975 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 914 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
976 va_end(args); | 915 va_end(args); |
977 | 916 |
978 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 917 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
979 va_list args2; | 918 va_list args2; |
980 va_start(args2, fmt); | 919 va_start(args2, fmt); |
981 OS::VSNPrint(buffer, (len + 1), fmt, args2); | 920 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
982 va_end(args2); | 921 va_end(args2); |
983 | 922 |
984 SetArgument(i, name, buffer); | 923 SetArgument(i, name, buffer); |
985 } | 924 } |
986 | 925 |
987 | |
988 void TimelineEventScope::FreeArguments() { | 926 void TimelineEventScope::FreeArguments() { |
989 if (arguments_ == NULL) { | 927 if (arguments_ == NULL) { |
990 return; | 928 return; |
991 } | 929 } |
992 for (intptr_t i = 0; i < arguments_length_; i++) { | 930 for (intptr_t i = 0; i < arguments_length_; i++) { |
993 free(arguments_[i].value); | 931 free(arguments_[i].value); |
994 } | 932 } |
995 free(arguments_); | 933 free(arguments_); |
996 arguments_ = NULL; | 934 arguments_ = NULL; |
997 arguments_length_ = 0; | 935 arguments_length_ = 0; |
998 } | 936 } |
999 | 937 |
1000 | |
1001 void TimelineEventScope::StealArguments(TimelineEvent* event) { | 938 void TimelineEventScope::StealArguments(TimelineEvent* event) { |
1002 if (event == NULL) { | 939 if (event == NULL) { |
1003 return; | 940 return; |
1004 } | 941 } |
1005 event->StealArguments(arguments_length_, arguments_); | 942 event->StealArguments(arguments_length_, arguments_); |
1006 arguments_length_ = 0; | 943 arguments_length_ = 0; |
1007 arguments_ = NULL; | 944 arguments_ = NULL; |
1008 } | 945 } |
1009 | 946 |
1010 | |
1011 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, | 947 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
1012 const char* label) | 948 const char* label) |
1013 : TimelineEventScope(stream, label) { | 949 : TimelineEventScope(stream, label) { |
1014 if (!FLAG_support_timeline || !enabled()) { | 950 if (!FLAG_support_timeline || !enabled()) { |
1015 return; | 951 return; |
1016 } | 952 } |
1017 #if defined(HOST_OS_FUCHSIA) | 953 #if defined(HOST_OS_FUCHSIA) |
1018 TRACE_DURATION_BEGIN("dart", label); | 954 TRACE_DURATION_BEGIN("dart", label); |
1019 #else | 955 #else |
1020 timestamp_ = OS::GetCurrentMonotonicMicros(); | 956 timestamp_ = OS::GetCurrentMonotonicMicros(); |
1021 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 957 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
1022 #endif | 958 #endif |
1023 } | 959 } |
1024 | 960 |
1025 | |
1026 TimelineDurationScope::TimelineDurationScope(Thread* thread, | 961 TimelineDurationScope::TimelineDurationScope(Thread* thread, |
1027 TimelineStream* stream, | 962 TimelineStream* stream, |
1028 const char* label) | 963 const char* label) |
1029 : TimelineEventScope(thread, stream, label) { | 964 : TimelineEventScope(thread, stream, label) { |
1030 if (!FLAG_support_timeline || !enabled()) { | 965 if (!FLAG_support_timeline || !enabled()) { |
1031 return; | 966 return; |
1032 } | 967 } |
1033 #if defined(HOST_OS_FUCHSIA) | 968 #if defined(HOST_OS_FUCHSIA) |
1034 TRACE_DURATION_BEGIN("dart", label); | 969 TRACE_DURATION_BEGIN("dart", label); |
1035 #else | 970 #else |
1036 timestamp_ = OS::GetCurrentMonotonicMicros(); | 971 timestamp_ = OS::GetCurrentMonotonicMicros(); |
1037 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 972 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
1038 #endif | 973 #endif |
1039 } | 974 } |
1040 | 975 |
1041 | |
1042 TimelineDurationScope::~TimelineDurationScope() { | 976 TimelineDurationScope::~TimelineDurationScope() { |
1043 if (!FLAG_support_timeline) { | 977 if (!FLAG_support_timeline) { |
1044 return; | 978 return; |
1045 } | 979 } |
1046 if (!ShouldEmitEvent()) { | 980 if (!ShouldEmitEvent()) { |
1047 return; | 981 return; |
1048 } | 982 } |
1049 #if defined(HOST_OS_FUCHSIA) | 983 #if defined(HOST_OS_FUCHSIA) |
1050 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | 984 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); |
1051 #else | 985 #else |
1052 TimelineEvent* event = stream()->StartEvent(); | 986 TimelineEvent* event = stream()->StartEvent(); |
1053 if (event == NULL) { | 987 if (event == NULL) { |
1054 // Stream is now disabled. | 988 // Stream is now disabled. |
1055 return; | 989 return; |
1056 } | 990 } |
1057 ASSERT(event != NULL); | 991 ASSERT(event != NULL); |
1058 // Emit a duration event. | 992 // Emit a duration event. |
1059 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 993 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
1060 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 994 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
1061 StealArguments(event); | 995 StealArguments(event); |
1062 event->Complete(); | 996 event->Complete(); |
1063 #endif | 997 #endif |
1064 } | 998 } |
1065 | 999 |
1066 | |
1067 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 1000 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |
1068 const char* label) | 1001 const char* label) |
1069 : TimelineEventScope(stream, label) { | 1002 : TimelineEventScope(stream, label) { |
1070 if (!FLAG_support_timeline) { | 1003 if (!FLAG_support_timeline) { |
1071 return; | 1004 return; |
1072 } | 1005 } |
1073 EmitBegin(); | 1006 EmitBegin(); |
1074 } | 1007 } |
1075 | 1008 |
1076 | |
1077 TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread, | 1009 TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread, |
1078 TimelineStream* stream, | 1010 TimelineStream* stream, |
1079 const char* label) | 1011 const char* label) |
1080 : TimelineEventScope(thread, stream, label) { | 1012 : TimelineEventScope(thread, stream, label) { |
1081 if (!FLAG_support_timeline) { | 1013 if (!FLAG_support_timeline) { |
1082 return; | 1014 return; |
1083 } | 1015 } |
1084 EmitBegin(); | 1016 EmitBegin(); |
1085 } | 1017 } |
1086 | 1018 |
1087 | |
1088 TimelineBeginEndScope::~TimelineBeginEndScope() { | 1019 TimelineBeginEndScope::~TimelineBeginEndScope() { |
1089 if (!FLAG_support_timeline) { | 1020 if (!FLAG_support_timeline) { |
1090 return; | 1021 return; |
1091 } | 1022 } |
1092 EmitEnd(); | 1023 EmitEnd(); |
1093 } | 1024 } |
1094 | 1025 |
1095 | |
1096 void TimelineBeginEndScope::EmitBegin() { | 1026 void TimelineBeginEndScope::EmitBegin() { |
1097 if (!FLAG_support_timeline) { | 1027 if (!FLAG_support_timeline) { |
1098 return; | 1028 return; |
1099 } | 1029 } |
1100 if (!ShouldEmitEvent()) { | 1030 if (!ShouldEmitEvent()) { |
1101 return; | 1031 return; |
1102 } | 1032 } |
1103 TimelineEvent* event = stream()->StartEvent(); | 1033 TimelineEvent* event = stream()->StartEvent(); |
1104 if (event == NULL) { | 1034 if (event == NULL) { |
1105 // Stream is now disabled. | 1035 // Stream is now disabled. |
1106 set_enabled(false); | 1036 set_enabled(false); |
1107 return; | 1037 return; |
1108 } | 1038 } |
1109 ASSERT(event != NULL); | 1039 ASSERT(event != NULL); |
1110 // Emit a begin event. | 1040 // Emit a begin event. |
1111 event->Begin(label()); | 1041 event->Begin(label()); |
1112 event->Complete(); | 1042 event->Complete(); |
1113 } | 1043 } |
1114 | 1044 |
1115 | |
1116 void TimelineBeginEndScope::EmitEnd() { | 1045 void TimelineBeginEndScope::EmitEnd() { |
1117 if (!FLAG_support_timeline) { | 1046 if (!FLAG_support_timeline) { |
1118 return; | 1047 return; |
1119 } | 1048 } |
1120 if (!ShouldEmitEvent()) { | 1049 if (!ShouldEmitEvent()) { |
1121 return; | 1050 return; |
1122 } | 1051 } |
1123 TimelineEvent* event = stream()->StartEvent(); | 1052 TimelineEvent* event = stream()->StartEvent(); |
1124 if (event == NULL) { | 1053 if (event == NULL) { |
1125 // Stream is now disabled. | 1054 // Stream is now disabled. |
1126 set_enabled(false); | 1055 set_enabled(false); |
1127 return; | 1056 return; |
1128 } | 1057 } |
1129 ASSERT(event != NULL); | 1058 ASSERT(event != NULL); |
1130 // Emit an end event. | 1059 // Emit an end event. |
1131 event->End(label()); | 1060 event->End(label()); |
1132 StealArguments(event); | 1061 StealArguments(event); |
1133 event->Complete(); | 1062 event->Complete(); |
1134 } | 1063 } |
1135 | 1064 |
1136 | |
1137 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, | 1065 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, |
1138 int64_t time_extent_micros) | 1066 int64_t time_extent_micros) |
1139 : time_origin_micros_(time_origin_micros), | 1067 : time_origin_micros_(time_origin_micros), |
1140 time_extent_micros_(time_extent_micros) { | 1068 time_extent_micros_(time_extent_micros) { |
1141 ASSERT(time_origin_micros_ >= -1); | 1069 ASSERT(time_origin_micros_ >= -1); |
1142 ASSERT(time_extent_micros_ >= -1); | 1070 ASSERT(time_extent_micros_ >= -1); |
1143 } | 1071 } |
1144 | 1072 |
1145 | |
1146 TimelineEventFilter::~TimelineEventFilter() {} | 1073 TimelineEventFilter::~TimelineEventFilter() {} |
1147 | 1074 |
1148 | |
1149 IsolateTimelineEventFilter::IsolateTimelineEventFilter( | 1075 IsolateTimelineEventFilter::IsolateTimelineEventFilter( |
1150 Dart_Port isolate_id, | 1076 Dart_Port isolate_id, |
1151 int64_t time_origin_micros, | 1077 int64_t time_origin_micros, |
1152 int64_t time_extent_micros) | 1078 int64_t time_extent_micros) |
1153 : TimelineEventFilter(time_origin_micros, time_extent_micros), | 1079 : TimelineEventFilter(time_origin_micros, time_extent_micros), |
1154 isolate_id_(isolate_id) {} | 1080 isolate_id_(isolate_id) {} |
1155 | 1081 |
1156 | |
1157 TimelineEventRecorder::TimelineEventRecorder() | 1082 TimelineEventRecorder::TimelineEventRecorder() |
1158 : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} | 1083 : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} |
1159 | 1084 |
1160 | |
1161 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 1085 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
1162 if (!FLAG_support_service) { | 1086 if (!FLAG_support_service) { |
1163 return; | 1087 return; |
1164 } | 1088 } |
1165 OSThreadIterator it; | 1089 OSThreadIterator it; |
1166 while (it.HasNext()) { | 1090 while (it.HasNext()) { |
1167 OSThread* thread = it.Next(); | 1091 OSThread* thread = it.Next(); |
1168 const char* thread_name = thread->name(); | 1092 const char* thread_name = thread->name(); |
1169 if (thread_name == NULL) { | 1093 if (thread_name == NULL) { |
1170 // Only emit a thread name if one was set. | 1094 // Only emit a thread name if one was set. |
1171 continue; | 1095 continue; |
1172 } | 1096 } |
1173 JSONObject obj(events); | 1097 JSONObject obj(events); |
1174 int64_t pid = OS::ProcessId(); | 1098 int64_t pid = OS::ProcessId(); |
1175 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); | 1099 int64_t tid = OSThread::ThreadIdToIntPtr(thread->trace_id()); |
1176 obj.AddProperty("name", "thread_name"); | 1100 obj.AddProperty("name", "thread_name"); |
1177 obj.AddProperty("ph", "M"); | 1101 obj.AddProperty("ph", "M"); |
1178 obj.AddProperty64("pid", pid); | 1102 obj.AddProperty64("pid", pid); |
1179 obj.AddProperty64("tid", tid); | 1103 obj.AddProperty64("tid", tid); |
1180 { | 1104 { |
1181 JSONObject args(&obj, "args"); | 1105 JSONObject args(&obj, "args"); |
1182 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); | 1106 args.AddPropertyF("name", "%s (%" Pd64 ")", thread_name, tid); |
1183 } | 1107 } |
1184 } | 1108 } |
1185 } | 1109 } |
1186 | 1110 |
1187 | |
1188 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { | 1111 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
1189 // Grab the current thread. | 1112 // Grab the current thread. |
1190 OSThread* thread = OSThread::Current(); | 1113 OSThread* thread = OSThread::Current(); |
1191 ASSERT(thread != NULL); | 1114 ASSERT(thread != NULL); |
1192 Mutex* thread_block_lock = thread->timeline_block_lock(); | 1115 Mutex* thread_block_lock = thread->timeline_block_lock(); |
1193 ASSERT(thread_block_lock != NULL); | 1116 ASSERT(thread_block_lock != NULL); |
1194 // We are accessing the thread's timeline block- so take the lock here. | 1117 // We are accessing the thread's timeline block- so take the lock here. |
1195 // This lock will be held until the call to |CompleteEvent| is made. | 1118 // This lock will be held until the call to |CompleteEvent| is made. |
1196 thread_block_lock->Lock(); | 1119 thread_block_lock->Lock(); |
1197 #if defined(DEBUG) | 1120 #if defined(DEBUG) |
(...skipping 28 matching lines...) Expand all Loading... |
1226 // Drop lock here as no event is being handed out. | 1149 // Drop lock here as no event is being handed out. |
1227 #if defined(DEBUG) | 1150 #if defined(DEBUG) |
1228 if (T != NULL) { | 1151 if (T != NULL) { |
1229 T->DecrementNoSafepointScopeDepth(); | 1152 T->DecrementNoSafepointScopeDepth(); |
1230 } | 1153 } |
1231 #endif // defined(DEBUG) | 1154 #endif // defined(DEBUG) |
1232 thread_block_lock->Unlock(); | 1155 thread_block_lock->Unlock(); |
1233 return NULL; | 1156 return NULL; |
1234 } | 1157 } |
1235 | 1158 |
1236 | |
1237 void TimelineEventRecorder::ResetTimeTracking() { | 1159 void TimelineEventRecorder::ResetTimeTracking() { |
1238 time_high_micros_ = 0; | 1160 time_high_micros_ = 0; |
1239 time_low_micros_ = kMaxInt64; | 1161 time_low_micros_ = kMaxInt64; |
1240 } | 1162 } |
1241 | 1163 |
1242 | |
1243 void TimelineEventRecorder::ReportTime(int64_t micros) { | 1164 void TimelineEventRecorder::ReportTime(int64_t micros) { |
1244 if (time_high_micros_ < micros) { | 1165 if (time_high_micros_ < micros) { |
1245 time_high_micros_ = micros; | 1166 time_high_micros_ = micros; |
1246 } | 1167 } |
1247 if (time_low_micros_ > micros) { | 1168 if (time_low_micros_ > micros) { |
1248 time_low_micros_ = micros; | 1169 time_low_micros_ = micros; |
1249 } | 1170 } |
1250 } | 1171 } |
1251 | 1172 |
1252 | |
1253 int64_t TimelineEventRecorder::TimeOriginMicros() const { | 1173 int64_t TimelineEventRecorder::TimeOriginMicros() const { |
1254 if (time_high_micros_ == 0) { | 1174 if (time_high_micros_ == 0) { |
1255 return 0; | 1175 return 0; |
1256 } | 1176 } |
1257 return time_low_micros_; | 1177 return time_low_micros_; |
1258 } | 1178 } |
1259 | 1179 |
1260 | |
1261 int64_t TimelineEventRecorder::TimeExtentMicros() const { | 1180 int64_t TimelineEventRecorder::TimeExtentMicros() const { |
1262 if (time_high_micros_ == 0) { | 1181 if (time_high_micros_ == 0) { |
1263 return 0; | 1182 return 0; |
1264 } | 1183 } |
1265 return time_high_micros_ - time_low_micros_; | 1184 return time_high_micros_ - time_low_micros_; |
1266 } | 1185 } |
1267 | 1186 |
1268 | |
1269 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { | 1187 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { |
1270 if (event == NULL) { | 1188 if (event == NULL) { |
1271 return; | 1189 return; |
1272 } | 1190 } |
1273 // Grab the current thread. | 1191 // Grab the current thread. |
1274 OSThread* thread = OSThread::Current(); | 1192 OSThread* thread = OSThread::Current(); |
1275 ASSERT(thread != NULL); | 1193 ASSERT(thread != NULL); |
1276 // Unlock the thread's block lock. | 1194 // Unlock the thread's block lock. |
1277 Mutex* thread_block_lock = thread->timeline_block_lock(); | 1195 Mutex* thread_block_lock = thread->timeline_block_lock(); |
1278 ASSERT(thread_block_lock != NULL); | 1196 ASSERT(thread_block_lock != NULL); |
1279 #if defined(DEBUG) | 1197 #if defined(DEBUG) |
1280 Thread* T = Thread::Current(); | 1198 Thread* T = Thread::Current(); |
1281 if (T != NULL) { | 1199 if (T != NULL) { |
1282 T->DecrementNoSafepointScopeDepth(); | 1200 T->DecrementNoSafepointScopeDepth(); |
1283 } | 1201 } |
1284 #endif // defined(DEBUG) | 1202 #endif // defined(DEBUG) |
1285 thread_block_lock->Unlock(); | 1203 thread_block_lock->Unlock(); |
1286 } | 1204 } |
1287 | 1205 |
1288 | |
1289 void TimelineEventRecorder::WriteTo(const char* directory) { | 1206 void TimelineEventRecorder::WriteTo(const char* directory) { |
1290 if (!FLAG_support_service) { | 1207 if (!FLAG_support_service) { |
1291 return; | 1208 return; |
1292 } | 1209 } |
1293 Dart_FileOpenCallback file_open = Dart::file_open_callback(); | 1210 Dart_FileOpenCallback file_open = Dart::file_open_callback(); |
1294 Dart_FileWriteCallback file_write = Dart::file_write_callback(); | 1211 Dart_FileWriteCallback file_write = Dart::file_write_callback(); |
1295 Dart_FileCloseCallback file_close = Dart::file_close_callback(); | 1212 Dart_FileCloseCallback file_close = Dart::file_close_callback(); |
1296 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 1213 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
1297 return; | 1214 return; |
1298 } | 1215 } |
(...skipping 19 matching lines...) Expand all Loading... |
1318 intptr_t output_length = 0; | 1235 intptr_t output_length = 0; |
1319 js.Steal(&output, &output_length); | 1236 js.Steal(&output, &output_length); |
1320 (*file_write)(output, output_length, file); | 1237 (*file_write)(output, output_length, file); |
1321 // Free the stolen output. | 1238 // Free the stolen output. |
1322 free(output); | 1239 free(output); |
1323 (*file_close)(file); | 1240 (*file_close)(file); |
1324 | 1241 |
1325 return; | 1242 return; |
1326 } | 1243 } |
1327 | 1244 |
1328 | |
1329 int64_t TimelineEventRecorder::GetNextAsyncId() { | 1245 int64_t TimelineEventRecorder::GetNextAsyncId() { |
1330 // TODO(johnmccutchan): Gracefully handle wrap around. | 1246 // TODO(johnmccutchan): Gracefully handle wrap around. |
1331 uint32_t next = | 1247 uint32_t next = |
1332 static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); | 1248 static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); |
1333 return static_cast<int64_t>(next); | 1249 return static_cast<int64_t>(next); |
1334 } | 1250 } |
1335 | 1251 |
1336 | |
1337 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { | 1252 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |
1338 if (block == NULL) { | 1253 if (block == NULL) { |
1339 return; | 1254 return; |
1340 } | 1255 } |
1341 MutexLocker ml(&lock_); | 1256 MutexLocker ml(&lock_); |
1342 block->Finish(); | 1257 block->Finish(); |
1343 } | 1258 } |
1344 | 1259 |
1345 | |
1346 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 1260 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
1347 MutexLocker ml(&lock_); | 1261 MutexLocker ml(&lock_); |
1348 return GetNewBlockLocked(); | 1262 return GetNewBlockLocked(); |
1349 } | 1263 } |
1350 | 1264 |
1351 | |
1352 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( | 1265 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( |
1353 intptr_t capacity) | 1266 intptr_t capacity) |
1354 : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { | 1267 : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { |
1355 // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 1268 // Capacity must be a multiple of TimelineEventBlock::kBlockSize |
1356 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 1269 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
1357 // Allocate blocks array. | 1270 // Allocate blocks array. |
1358 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 1271 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |
1359 blocks_ = reinterpret_cast<TimelineEventBlock**>( | 1272 blocks_ = reinterpret_cast<TimelineEventBlock**>( |
1360 calloc(num_blocks_, sizeof(TimelineEventBlock*))); | 1273 calloc(num_blocks_, sizeof(TimelineEventBlock*))); |
1361 // Allocate each block. | 1274 // Allocate each block. |
1362 for (intptr_t i = 0; i < num_blocks_; i++) { | 1275 for (intptr_t i = 0; i < num_blocks_; i++) { |
1363 blocks_[i] = new TimelineEventBlock(i); | 1276 blocks_[i] = new TimelineEventBlock(i); |
1364 } | 1277 } |
1365 // Chain blocks together. | 1278 // Chain blocks together. |
1366 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 1279 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |
1367 blocks_[i]->set_next(blocks_[i + 1]); | 1280 blocks_[i]->set_next(blocks_[i + 1]); |
1368 } | 1281 } |
1369 } | 1282 } |
1370 | 1283 |
1371 | |
1372 TimelineEventFixedBufferRecorder::~TimelineEventFixedBufferRecorder() { | 1284 TimelineEventFixedBufferRecorder::~TimelineEventFixedBufferRecorder() { |
1373 // Delete all blocks. | 1285 // Delete all blocks. |
1374 for (intptr_t i = 0; i < num_blocks_; i++) { | 1286 for (intptr_t i = 0; i < num_blocks_; i++) { |
1375 TimelineEventBlock* block = blocks_[i]; | 1287 TimelineEventBlock* block = blocks_[i]; |
1376 delete block; | 1288 delete block; |
1377 } | 1289 } |
1378 free(blocks_); | 1290 free(blocks_); |
1379 } | 1291 } |
1380 | 1292 |
1381 | |
1382 void TimelineEventFixedBufferRecorder::PrintJSONEvents( | 1293 void TimelineEventFixedBufferRecorder::PrintJSONEvents( |
1383 JSONArray* events, | 1294 JSONArray* events, |
1384 TimelineEventFilter* filter) { | 1295 TimelineEventFilter* filter) { |
1385 if (!FLAG_support_service) { | 1296 if (!FLAG_support_service) { |
1386 return; | 1297 return; |
1387 } | 1298 } |
1388 MutexLocker ml(&lock_); | 1299 MutexLocker ml(&lock_); |
1389 ResetTimeTracking(); | 1300 ResetTimeTracking(); |
1390 intptr_t block_offset = FindOldestBlockIndex(); | 1301 intptr_t block_offset = FindOldestBlockIndex(); |
1391 if (block_offset == -1) { | 1302 if (block_offset == -1) { |
(...skipping 12 matching lines...) Expand all Loading... |
1404 event->Within(filter->time_origin_micros(), | 1315 event->Within(filter->time_origin_micros(), |
1405 filter->time_extent_micros())) { | 1316 filter->time_extent_micros())) { |
1406 ReportTime(event->LowTime()); | 1317 ReportTime(event->LowTime()); |
1407 ReportTime(event->HighTime()); | 1318 ReportTime(event->HighTime()); |
1408 events->AddValue(event); | 1319 events->AddValue(event); |
1409 } | 1320 } |
1410 } | 1321 } |
1411 } | 1322 } |
1412 } | 1323 } |
1413 | 1324 |
1414 | |
1415 void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js, | 1325 void TimelineEventFixedBufferRecorder::PrintJSON(JSONStream* js, |
1416 TimelineEventFilter* filter) { | 1326 TimelineEventFilter* filter) { |
1417 if (!FLAG_support_service) { | 1327 if (!FLAG_support_service) { |
1418 return; | 1328 return; |
1419 } | 1329 } |
1420 JSONObject topLevel(js); | 1330 JSONObject topLevel(js); |
1421 topLevel.AddProperty("type", "_Timeline"); | 1331 topLevel.AddProperty("type", "_Timeline"); |
1422 { | 1332 { |
1423 JSONArray events(&topLevel, "traceEvents"); | 1333 JSONArray events(&topLevel, "traceEvents"); |
1424 PrintJSONMeta(&events); | 1334 PrintJSONMeta(&events); |
1425 PrintJSONEvents(&events, filter); | 1335 PrintJSONEvents(&events, filter); |
1426 } | 1336 } |
1427 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); | 1337 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); |
1428 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); | 1338 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); |
1429 } | 1339 } |
1430 | 1340 |
1431 | |
1432 void TimelineEventFixedBufferRecorder::PrintTraceEvent( | 1341 void TimelineEventFixedBufferRecorder::PrintTraceEvent( |
1433 JSONStream* js, | 1342 JSONStream* js, |
1434 TimelineEventFilter* filter) { | 1343 TimelineEventFilter* filter) { |
1435 if (!FLAG_support_service) { | 1344 if (!FLAG_support_service) { |
1436 return; | 1345 return; |
1437 } | 1346 } |
1438 JSONArray events(js); | 1347 JSONArray events(js); |
1439 PrintJSONMeta(&events); | 1348 PrintJSONMeta(&events); |
1440 PrintJSONEvents(&events, filter); | 1349 PrintJSONEvents(&events, filter); |
1441 } | 1350 } |
1442 | 1351 |
1443 | |
1444 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() { | 1352 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() { |
1445 return blocks_[0]; | 1353 return blocks_[0]; |
1446 } | 1354 } |
1447 | 1355 |
1448 | |
1449 void TimelineEventFixedBufferRecorder::Clear() { | 1356 void TimelineEventFixedBufferRecorder::Clear() { |
1450 MutexLocker ml(&lock_); | 1357 MutexLocker ml(&lock_); |
1451 for (intptr_t i = 0; i < num_blocks_; i++) { | 1358 for (intptr_t i = 0; i < num_blocks_; i++) { |
1452 TimelineEventBlock* block = blocks_[i]; | 1359 TimelineEventBlock* block = blocks_[i]; |
1453 block->Reset(); | 1360 block->Reset(); |
1454 } | 1361 } |
1455 } | 1362 } |
1456 | 1363 |
1457 | |
1458 intptr_t TimelineEventFixedBufferRecorder::FindOldestBlockIndex() const { | 1364 intptr_t TimelineEventFixedBufferRecorder::FindOldestBlockIndex() const { |
1459 int64_t earliest_time = kMaxInt64; | 1365 int64_t earliest_time = kMaxInt64; |
1460 intptr_t earliest_index = -1; | 1366 intptr_t earliest_index = -1; |
1461 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { | 1367 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { |
1462 TimelineEventBlock* block = blocks_[block_idx]; | 1368 TimelineEventBlock* block = blocks_[block_idx]; |
1463 if (block->IsEmpty()) { | 1369 if (block->IsEmpty()) { |
1464 // Skip empty blocks. | 1370 // Skip empty blocks. |
1465 continue; | 1371 continue; |
1466 } | 1372 } |
1467 if (block->LowerTimeBound() < earliest_time) { | 1373 if (block->LowerTimeBound() < earliest_time) { |
1468 earliest_time = block->LowerTimeBound(); | 1374 earliest_time = block->LowerTimeBound(); |
1469 earliest_index = block_idx; | 1375 earliest_index = block_idx; |
1470 } | 1376 } |
1471 } | 1377 } |
1472 return earliest_index; | 1378 return earliest_index; |
1473 } | 1379 } |
1474 | 1380 |
1475 | |
1476 TimelineEvent* TimelineEventFixedBufferRecorder::StartEvent() { | 1381 TimelineEvent* TimelineEventFixedBufferRecorder::StartEvent() { |
1477 return ThreadBlockStartEvent(); | 1382 return ThreadBlockStartEvent(); |
1478 } | 1383 } |
1479 | 1384 |
1480 | |
1481 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { | 1385 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { |
1482 if (event == NULL) { | 1386 if (event == NULL) { |
1483 return; | 1387 return; |
1484 } | 1388 } |
1485 ThreadBlockCompleteEvent(event); | 1389 ThreadBlockCompleteEvent(event); |
1486 } | 1390 } |
1487 | 1391 |
1488 | |
1489 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | 1392 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |
1490 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { | 1393 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { |
1491 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1394 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
1492 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | 1395 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; |
1493 systrace_fd_ = open(kSystracePath, O_WRONLY); | 1396 systrace_fd_ = open(kSystracePath, O_WRONLY); |
1494 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | 1397 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { |
1495 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | 1398 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |
1496 kSystracePath); | 1399 kSystracePath); |
1497 } | 1400 } |
1498 #else | 1401 #else |
1499 OS::PrintErr( | 1402 OS::PrintErr( |
1500 "Warning: The systrace timeline recorder is equivalent to the" | 1403 "Warning: The systrace timeline recorder is equivalent to the" |
1501 "ring recorder on this platform."); | 1404 "ring recorder on this platform."); |
1502 #endif | 1405 #endif |
1503 } | 1406 } |
1504 | 1407 |
1505 | |
1506 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | 1408 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { |
1507 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1409 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
1508 if (systrace_fd_ >= 0) { | 1410 if (systrace_fd_ >= 0) { |
1509 close(systrace_fd_); | 1411 close(systrace_fd_); |
1510 } | 1412 } |
1511 #endif | 1413 #endif |
1512 } | 1414 } |
1513 | 1415 |
1514 | |
1515 TimelineEventBlock* TimelineEventSystraceRecorder::GetNewBlockLocked() { | 1416 TimelineEventBlock* TimelineEventSystraceRecorder::GetNewBlockLocked() { |
1516 // TODO(johnmccutchan): This function should only hand out blocks | 1417 // TODO(johnmccutchan): This function should only hand out blocks |
1517 // which have been marked as finished. | 1418 // which have been marked as finished. |
1518 if (block_cursor_ == num_blocks_) { | 1419 if (block_cursor_ == num_blocks_) { |
1519 block_cursor_ = 0; | 1420 block_cursor_ = 0; |
1520 } | 1421 } |
1521 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1422 TimelineEventBlock* block = blocks_[block_cursor_++]; |
1522 block->Reset(); | 1423 block->Reset(); |
1523 block->Open(); | 1424 block->Open(); |
1524 return block; | 1425 return block; |
1525 } | 1426 } |
1526 | 1427 |
1527 | |
1528 void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { | 1428 void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { |
1529 if (event == NULL) { | 1429 if (event == NULL) { |
1530 return; | 1430 return; |
1531 } | 1431 } |
1532 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) | 1432 #if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) |
1533 if (systrace_fd_ >= 0) { | 1433 if (systrace_fd_ >= 0) { |
1534 // Serialize to the systrace format. | 1434 // Serialize to the systrace format. |
1535 const intptr_t kBufferLength = 1024; | 1435 const intptr_t kBufferLength = 1024; |
1536 char buffer[kBufferLength]; | 1436 char buffer[kBufferLength]; |
1537 const intptr_t event_length = | 1437 const intptr_t event_length = |
1538 event->PrintSystrace(&buffer[0], kBufferLength); | 1438 event->PrintSystrace(&buffer[0], kBufferLength); |
1539 if (event_length > 0) { | 1439 if (event_length > 0) { |
1540 ssize_t __result; | 1440 ssize_t __result; |
1541 // Repeatedly attempt the write while we are being interrupted. | 1441 // Repeatedly attempt the write while we are being interrupted. |
1542 do { | 1442 do { |
1543 __result = write(systrace_fd_, buffer, event_length); | 1443 __result = write(systrace_fd_, buffer, event_length); |
1544 } while ((__result == -1L) && (errno == EINTR)); | 1444 } while ((__result == -1L) && (errno == EINTR)); |
1545 } | 1445 } |
1546 } | 1446 } |
1547 #endif | 1447 #endif |
1548 ThreadBlockCompleteEvent(event); | 1448 ThreadBlockCompleteEvent(event); |
1549 } | 1449 } |
1550 | 1450 |
1551 | |
1552 #if defined(HOST_OS_FUCHSIA) | 1451 #if defined(HOST_OS_FUCHSIA) |
1553 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) | 1452 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) |
1554 : TimelineEventFixedBufferRecorder(capacity) {} | 1453 : TimelineEventFixedBufferRecorder(capacity) {} |
1555 | 1454 |
1556 | 1455 |
1557 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { | 1456 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { |
1558 // TODO(johnmccutchan): This function should only hand out blocks | 1457 // TODO(johnmccutchan): This function should only hand out blocks |
1559 // which have been marked as finished. | 1458 // which have been marked as finished. |
1560 if (block_cursor_ == num_blocks_) { | 1459 if (block_cursor_ == num_blocks_) { |
1561 block_cursor_ = 0; | 1460 block_cursor_ = 0; |
1562 } | 1461 } |
1563 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1462 TimelineEventBlock* block = blocks_[block_cursor_++]; |
1564 block->Reset(); | 1463 block->Reset(); |
1565 block->Open(); | 1464 block->Open(); |
1566 return block; | 1465 return block; |
1567 } | 1466 } |
1568 | 1467 |
1569 | |
1570 void TimelineEventFuchsiaRecorder::CompleteEvent(TimelineEvent* event) { | 1468 void TimelineEventFuchsiaRecorder::CompleteEvent(TimelineEvent* event) { |
1571 if (event == NULL) { | 1469 if (event == NULL) { |
1572 return; | 1470 return; |
1573 } | 1471 } |
1574 event->EmitFuchsiaEvent(); | 1472 event->EmitFuchsiaEvent(); |
1575 ThreadBlockCompleteEvent(event); | 1473 ThreadBlockCompleteEvent(event); |
1576 } | 1474 } |
1577 #endif // defined(HOST_OS_FUCHSIA) | 1475 #endif // defined(HOST_OS_FUCHSIA) |
1578 | 1476 |
1579 | |
1580 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { | 1477 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
1581 // TODO(johnmccutchan): This function should only hand out blocks | 1478 // TODO(johnmccutchan): This function should only hand out blocks |
1582 // which have been marked as finished. | 1479 // which have been marked as finished. |
1583 if (block_cursor_ == num_blocks_) { | 1480 if (block_cursor_ == num_blocks_) { |
1584 block_cursor_ = 0; | 1481 block_cursor_ = 0; |
1585 } | 1482 } |
1586 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1483 TimelineEventBlock* block = blocks_[block_cursor_++]; |
1587 block->Reset(); | 1484 block->Reset(); |
1588 block->Open(); | 1485 block->Open(); |
1589 return block; | 1486 return block; |
1590 } | 1487 } |
1591 | 1488 |
1592 | |
1593 TimelineEventBlock* TimelineEventStartupRecorder::GetNewBlockLocked() { | 1489 TimelineEventBlock* TimelineEventStartupRecorder::GetNewBlockLocked() { |
1594 if (block_cursor_ == num_blocks_) { | 1490 if (block_cursor_ == num_blocks_) { |
1595 return NULL; | 1491 return NULL; |
1596 } | 1492 } |
1597 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1493 TimelineEventBlock* block = blocks_[block_cursor_++]; |
1598 block->Reset(); | 1494 block->Reset(); |
1599 block->Open(); | 1495 block->Open(); |
1600 return block; | 1496 return block; |
1601 } | 1497 } |
1602 | 1498 |
1603 | |
1604 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} | 1499 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} |
1605 | 1500 |
1606 | |
1607 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} | 1501 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} |
1608 | 1502 |
1609 | |
1610 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, | 1503 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, |
1611 TimelineEventFilter* filter) { | 1504 TimelineEventFilter* filter) { |
1612 if (!FLAG_support_service) { | 1505 if (!FLAG_support_service) { |
1613 return; | 1506 return; |
1614 } | 1507 } |
1615 JSONObject topLevel(js); | 1508 JSONObject topLevel(js); |
1616 topLevel.AddProperty("type", "_Timeline"); | 1509 topLevel.AddProperty("type", "_Timeline"); |
1617 { | 1510 { |
1618 JSONArray events(&topLevel, "traceEvents"); | 1511 JSONArray events(&topLevel, "traceEvents"); |
1619 PrintJSONMeta(&events); | 1512 PrintJSONMeta(&events); |
1620 } | 1513 } |
1621 } | 1514 } |
1622 | 1515 |
1623 | |
1624 void TimelineEventCallbackRecorder::PrintTraceEvent( | 1516 void TimelineEventCallbackRecorder::PrintTraceEvent( |
1625 JSONStream* js, | 1517 JSONStream* js, |
1626 TimelineEventFilter* filter) { | 1518 TimelineEventFilter* filter) { |
1627 if (!FLAG_support_service) { | 1519 if (!FLAG_support_service) { |
1628 return; | 1520 return; |
1629 } | 1521 } |
1630 JSONArray events(js); | 1522 JSONArray events(js); |
1631 } | 1523 } |
1632 | 1524 |
1633 | |
1634 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() { | 1525 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() { |
1635 TimelineEvent* event = new TimelineEvent(); | 1526 TimelineEvent* event = new TimelineEvent(); |
1636 return event; | 1527 return event; |
1637 } | 1528 } |
1638 | 1529 |
1639 | |
1640 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { | 1530 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { |
1641 OnEvent(event); | 1531 OnEvent(event); |
1642 delete event; | 1532 delete event; |
1643 } | 1533 } |
1644 | 1534 |
1645 | |
1646 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 1535 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
1647 : head_(NULL), block_index_(0) {} | 1536 : head_(NULL), block_index_(0) {} |
1648 | 1537 |
1649 TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() { | 1538 TimelineEventEndlessRecorder::~TimelineEventEndlessRecorder() { |
1650 TimelineEventBlock* current = head_; | 1539 TimelineEventBlock* current = head_; |
1651 head_ = NULL; | 1540 head_ = NULL; |
1652 | 1541 |
1653 while (current != NULL) { | 1542 while (current != NULL) { |
1654 TimelineEventBlock* next = current->next(); | 1543 TimelineEventBlock* next = current->next(); |
1655 delete current; | 1544 delete current; |
(...skipping 10 matching lines...) Expand all Loading... |
1666 topLevel.AddProperty("type", "_Timeline"); | 1555 topLevel.AddProperty("type", "_Timeline"); |
1667 { | 1556 { |
1668 JSONArray events(&topLevel, "traceEvents"); | 1557 JSONArray events(&topLevel, "traceEvents"); |
1669 PrintJSONMeta(&events); | 1558 PrintJSONMeta(&events); |
1670 PrintJSONEvents(&events, filter); | 1559 PrintJSONEvents(&events, filter); |
1671 } | 1560 } |
1672 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); | 1561 topLevel.AddPropertyTimeMicros("timeOriginMicros", TimeOriginMicros()); |
1673 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); | 1562 topLevel.AddPropertyTimeMicros("timeExtentMicros", TimeExtentMicros()); |
1674 } | 1563 } |
1675 | 1564 |
1676 | |
1677 void TimelineEventEndlessRecorder::PrintTraceEvent( | 1565 void TimelineEventEndlessRecorder::PrintTraceEvent( |
1678 JSONStream* js, | 1566 JSONStream* js, |
1679 TimelineEventFilter* filter) { | 1567 TimelineEventFilter* filter) { |
1680 if (!FLAG_support_service) { | 1568 if (!FLAG_support_service) { |
1681 return; | 1569 return; |
1682 } | 1570 } |
1683 JSONArray events(js); | 1571 JSONArray events(js); |
1684 PrintJSONMeta(&events); | 1572 PrintJSONMeta(&events); |
1685 PrintJSONEvents(&events, filter); | 1573 PrintJSONEvents(&events, filter); |
1686 } | 1574 } |
1687 | 1575 |
1688 | |
1689 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 1576 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
1690 return head_; | 1577 return head_; |
1691 } | 1578 } |
1692 | 1579 |
1693 | |
1694 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 1580 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
1695 return ThreadBlockStartEvent(); | 1581 return ThreadBlockStartEvent(); |
1696 } | 1582 } |
1697 | 1583 |
1698 | |
1699 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { | 1584 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { |
1700 if (event == NULL) { | 1585 if (event == NULL) { |
1701 return; | 1586 return; |
1702 } | 1587 } |
1703 ThreadBlockCompleteEvent(event); | 1588 ThreadBlockCompleteEvent(event); |
1704 } | 1589 } |
1705 | 1590 |
1706 | |
1707 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { | 1591 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { |
1708 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); | 1592 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); |
1709 block->set_next(head_); | 1593 block->set_next(head_); |
1710 block->Open(); | 1594 block->Open(); |
1711 head_ = block; | 1595 head_ = block; |
1712 if (FLAG_trace_timeline) { | 1596 if (FLAG_trace_timeline) { |
1713 OS::Print("Created new block %p\n", block); | 1597 OS::Print("Created new block %p\n", block); |
1714 } | 1598 } |
1715 return head_; | 1599 return head_; |
1716 } | 1600 } |
1717 | 1601 |
1718 static int TimelineEventBlockCompare(TimelineEventBlock* const* a, | 1602 static int TimelineEventBlockCompare(TimelineEventBlock* const* a, |
1719 TimelineEventBlock* const* b) { | 1603 TimelineEventBlock* const* b) { |
1720 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); | 1604 return (*a)->LowerTimeBound() - (*b)->LowerTimeBound(); |
1721 } | 1605 } |
1722 | 1606 |
1723 | |
1724 void TimelineEventEndlessRecorder::PrintJSONEvents( | 1607 void TimelineEventEndlessRecorder::PrintJSONEvents( |
1725 JSONArray* events, | 1608 JSONArray* events, |
1726 TimelineEventFilter* filter) { | 1609 TimelineEventFilter* filter) { |
1727 if (!FLAG_support_service) { | 1610 if (!FLAG_support_service) { |
1728 return; | 1611 return; |
1729 } | 1612 } |
1730 MutexLocker ml(&lock_); | 1613 MutexLocker ml(&lock_); |
1731 ResetTimeTracking(); | 1614 ResetTimeTracking(); |
1732 // Collect all interesting blocks. | 1615 // Collect all interesting blocks. |
1733 MallocGrowableArray<TimelineEventBlock*> blocks(8); | 1616 MallocGrowableArray<TimelineEventBlock*> blocks(8); |
(...skipping 21 matching lines...) Expand all Loading... |
1755 event->Within(filter->time_origin_micros(), | 1638 event->Within(filter->time_origin_micros(), |
1756 filter->time_extent_micros())) { | 1639 filter->time_extent_micros())) { |
1757 ReportTime(event->LowTime()); | 1640 ReportTime(event->LowTime()); |
1758 ReportTime(event->HighTime()); | 1641 ReportTime(event->HighTime()); |
1759 events->AddValue(event); | 1642 events->AddValue(event); |
1760 } | 1643 } |
1761 } | 1644 } |
1762 } | 1645 } |
1763 } | 1646 } |
1764 | 1647 |
1765 | |
1766 void TimelineEventEndlessRecorder::Clear() { | 1648 void TimelineEventEndlessRecorder::Clear() { |
1767 TimelineEventBlock* current = head_; | 1649 TimelineEventBlock* current = head_; |
1768 while (current != NULL) { | 1650 while (current != NULL) { |
1769 TimelineEventBlock* next = current->next(); | 1651 TimelineEventBlock* next = current->next(); |
1770 delete current; | 1652 delete current; |
1771 current = next; | 1653 current = next; |
1772 } | 1654 } |
1773 head_ = NULL; | 1655 head_ = NULL; |
1774 block_index_ = 0; | 1656 block_index_ = 0; |
1775 OSThread* thread = OSThread::Current(); | 1657 OSThread* thread = OSThread::Current(); |
1776 thread->set_timeline_block(NULL); | 1658 thread->set_timeline_block(NULL); |
1777 } | 1659 } |
1778 | 1660 |
1779 | |
1780 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 1661 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
1781 : next_(NULL), | 1662 : next_(NULL), |
1782 length_(0), | 1663 length_(0), |
1783 block_index_(block_index), | 1664 block_index_(block_index), |
1784 thread_id_(OSThread::kInvalidThreadId), | 1665 thread_id_(OSThread::kInvalidThreadId), |
1785 in_use_(false) {} | 1666 in_use_(false) {} |
1786 | 1667 |
1787 | |
1788 TimelineEventBlock::~TimelineEventBlock() { | 1668 TimelineEventBlock::~TimelineEventBlock() { |
1789 Reset(); | 1669 Reset(); |
1790 } | 1670 } |
1791 | 1671 |
1792 | |
1793 void TimelineEventBlock::PrintJSON(JSONStream* js) const { | 1672 void TimelineEventBlock::PrintJSON(JSONStream* js) const { |
1794 ASSERT(!in_use()); | 1673 ASSERT(!in_use()); |
1795 JSONArray events(js); | 1674 JSONArray events(js); |
1796 for (intptr_t i = 0; i < length(); i++) { | 1675 for (intptr_t i = 0; i < length(); i++) { |
1797 const TimelineEvent* event = At(i); | 1676 const TimelineEvent* event = At(i); |
1798 events.AddValue(event); | 1677 events.AddValue(event); |
1799 } | 1678 } |
1800 } | 1679 } |
1801 | 1680 |
1802 | |
1803 TimelineEvent* TimelineEventBlock::StartEvent() { | 1681 TimelineEvent* TimelineEventBlock::StartEvent() { |
1804 ASSERT(!IsFull()); | 1682 ASSERT(!IsFull()); |
1805 if (FLAG_trace_timeline) { | 1683 if (FLAG_trace_timeline) { |
1806 OSThread* os_thread = OSThread::Current(); | 1684 OSThread* os_thread = OSThread::Current(); |
1807 ASSERT(os_thread != NULL); | 1685 ASSERT(os_thread != NULL); |
1808 intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id()); | 1686 intptr_t tid = OSThread::ThreadIdToIntPtr(os_thread->id()); |
1809 OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid); | 1687 OS::Print("StartEvent in block %p for thread %" Px "\n", this, tid); |
1810 } | 1688 } |
1811 return &events_[length_++]; | 1689 return &events_[length_++]; |
1812 } | 1690 } |
1813 | 1691 |
1814 | |
1815 int64_t TimelineEventBlock::LowerTimeBound() const { | 1692 int64_t TimelineEventBlock::LowerTimeBound() const { |
1816 if (length_ == 0) { | 1693 if (length_ == 0) { |
1817 return kMaxInt64; | 1694 return kMaxInt64; |
1818 } | 1695 } |
1819 ASSERT(length_ > 0); | 1696 ASSERT(length_ > 0); |
1820 return events_[0].TimeOrigin(); | 1697 return events_[0].TimeOrigin(); |
1821 } | 1698 } |
1822 | 1699 |
1823 | |
1824 bool TimelineEventBlock::CheckBlock() { | 1700 bool TimelineEventBlock::CheckBlock() { |
1825 if (length() == 0) { | 1701 if (length() == 0) { |
1826 return true; | 1702 return true; |
1827 } | 1703 } |
1828 | 1704 |
1829 for (intptr_t i = 0; i < length(); i++) { | 1705 for (intptr_t i = 0; i < length(); i++) { |
1830 if (At(i)->thread() != thread_id()) { | 1706 if (At(i)->thread() != thread_id()) { |
1831 return false; | 1707 return false; |
1832 } | 1708 } |
1833 } | 1709 } |
1834 | 1710 |
1835 // - events have monotonically increasing timestamps. | 1711 // - events have monotonically increasing timestamps. |
1836 int64_t last_time = LowerTimeBound(); | 1712 int64_t last_time = LowerTimeBound(); |
1837 for (intptr_t i = 0; i < length(); i++) { | 1713 for (intptr_t i = 0; i < length(); i++) { |
1838 if (last_time > At(i)->TimeOrigin()) { | 1714 if (last_time > At(i)->TimeOrigin()) { |
1839 return false; | 1715 return false; |
1840 } | 1716 } |
1841 last_time = At(i)->TimeOrigin(); | 1717 last_time = At(i)->TimeOrigin(); |
1842 } | 1718 } |
1843 | 1719 |
1844 return true; | 1720 return true; |
1845 } | 1721 } |
1846 | 1722 |
1847 | |
1848 void TimelineEventBlock::Reset() { | 1723 void TimelineEventBlock::Reset() { |
1849 for (intptr_t i = 0; i < kBlockSize; i++) { | 1724 for (intptr_t i = 0; i < kBlockSize; i++) { |
1850 // Clear any extra data. | 1725 // Clear any extra data. |
1851 events_[i].Reset(); | 1726 events_[i].Reset(); |
1852 } | 1727 } |
1853 length_ = 0; | 1728 length_ = 0; |
1854 thread_id_ = OSThread::kInvalidThreadId; | 1729 thread_id_ = OSThread::kInvalidThreadId; |
1855 in_use_ = false; | 1730 in_use_ = false; |
1856 } | 1731 } |
1857 | 1732 |
1858 | |
1859 void TimelineEventBlock::Open() { | 1733 void TimelineEventBlock::Open() { |
1860 OSThread* os_thread = OSThread::Current(); | 1734 OSThread* os_thread = OSThread::Current(); |
1861 ASSERT(os_thread != NULL); | 1735 ASSERT(os_thread != NULL); |
1862 thread_id_ = os_thread->trace_id(); | 1736 thread_id_ = os_thread->trace_id(); |
1863 in_use_ = true; | 1737 in_use_ = true; |
1864 } | 1738 } |
1865 | 1739 |
1866 | |
1867 void TimelineEventBlock::Finish() { | 1740 void TimelineEventBlock::Finish() { |
1868 if (FLAG_trace_timeline) { | 1741 if (FLAG_trace_timeline) { |
1869 OS::Print("Finish block %p\n", this); | 1742 OS::Print("Finish block %p\n", this); |
1870 } | 1743 } |
1871 in_use_ = false; | 1744 in_use_ = false; |
1872 if (Service::timeline_stream.enabled()) { | 1745 if (Service::timeline_stream.enabled()) { |
1873 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); | 1746 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); |
1874 service_event.set_timeline_event_block(this); | 1747 service_event.set_timeline_event_block(this); |
1875 Service::HandleEvent(&service_event); | 1748 Service::HandleEvent(&service_event); |
1876 } | 1749 } |
1877 } | 1750 } |
1878 | 1751 |
1879 | |
1880 TimelineEventBlockIterator::TimelineEventBlockIterator( | 1752 TimelineEventBlockIterator::TimelineEventBlockIterator( |
1881 TimelineEventRecorder* recorder) | 1753 TimelineEventRecorder* recorder) |
1882 : current_(NULL), recorder_(NULL) { | 1754 : current_(NULL), recorder_(NULL) { |
1883 Reset(recorder); | 1755 Reset(recorder); |
1884 } | 1756 } |
1885 | 1757 |
1886 | |
1887 TimelineEventBlockIterator::~TimelineEventBlockIterator() { | 1758 TimelineEventBlockIterator::~TimelineEventBlockIterator() { |
1888 Reset(NULL); | 1759 Reset(NULL); |
1889 } | 1760 } |
1890 | 1761 |
1891 | |
1892 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { | 1762 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { |
1893 // Clear current. | 1763 // Clear current. |
1894 current_ = NULL; | 1764 current_ = NULL; |
1895 if (recorder_ != NULL) { | 1765 if (recorder_ != NULL) { |
1896 // Unlock old recorder. | 1766 // Unlock old recorder. |
1897 recorder_->lock_.Unlock(); | 1767 recorder_->lock_.Unlock(); |
1898 } | 1768 } |
1899 recorder_ = recorder; | 1769 recorder_ = recorder; |
1900 if (recorder_ == NULL) { | 1770 if (recorder_ == NULL) { |
1901 return; | 1771 return; |
1902 } | 1772 } |
1903 // Lock new recorder. | 1773 // Lock new recorder. |
1904 recorder_->lock_.Lock(); | 1774 recorder_->lock_.Lock(); |
1905 // Queue up first block. | 1775 // Queue up first block. |
1906 current_ = recorder_->GetHeadBlockLocked(); | 1776 current_ = recorder_->GetHeadBlockLocked(); |
1907 } | 1777 } |
1908 | 1778 |
1909 | |
1910 bool TimelineEventBlockIterator::HasNext() const { | 1779 bool TimelineEventBlockIterator::HasNext() const { |
1911 return current_ != NULL; | 1780 return current_ != NULL; |
1912 } | 1781 } |
1913 | 1782 |
1914 | |
1915 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1783 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
1916 ASSERT(current_ != NULL); | 1784 ASSERT(current_ != NULL); |
1917 TimelineEventBlock* r = current_; | 1785 TimelineEventBlock* r = current_; |
1918 current_ = current_->next(); | 1786 current_ = current_->next(); |
1919 return r; | 1787 return r; |
1920 } | 1788 } |
1921 | 1789 |
1922 } // namespace dart | 1790 } // namespace dart |
1923 | 1791 |
1924 #endif // !PRODUCT | 1792 #endif // !PRODUCT |
OLD | NEW |