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 #ifndef PRODUCT | 5 #ifndef PRODUCT |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <cstdlib> | 9 #include <cstdlib> |
10 | 10 |
11 #include "vm/atomic.h" | 11 #include "vm/atomic.h" |
12 #include "vm/isolate.h" | 12 #include "vm/isolate.h" |
13 #include "vm/json_stream.h" | 13 #include "vm/json_stream.h" |
14 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
15 #include "vm/log.h" | 15 #include "vm/log.h" |
16 #include "vm/object.h" | 16 #include "vm/object.h" |
17 #include "vm/service_event.h" | 17 #include "vm/service_event.h" |
18 #include "vm/thread.h" | 18 #include "vm/thread.h" |
19 #include "vm/timeline.h" | 19 #include "vm/timeline.h" |
20 | 20 |
21 namespace dart { | 21 namespace dart { |
22 | 22 |
23 DEFINE_FLAG(bool, complete_timeline, false, "Record the complete timeline"); | 23 DEFINE_FLAG(bool, complete_timeline, false, "Record the complete timeline"); |
24 DEFINE_FLAG(bool, startup_timeline, false, "Record the startup timeline"); | 24 DEFINE_FLAG(bool, startup_timeline, false, "Record the startup timeline"); |
25 DEFINE_FLAG(bool, systrace_timeline, false, "Record the timeline to systrace"); | 25 DEFINE_FLAG(bool, systrace_timeline, false, "Record the timeline to systrace"); |
26 DEFINE_FLAG(bool, trace_timeline, false, | 26 DEFINE_FLAG(bool, trace_timeline, false, "Trace timeline backend"); |
27 "Trace timeline backend"); | 27 DEFINE_FLAG(bool, |
28 DEFINE_FLAG(bool, trace_timeline_analysis, false, | 28 trace_timeline_analysis, |
| 29 false, |
29 "Trace timeline analysis backend"); | 30 "Trace timeline analysis backend"); |
30 DEFINE_FLAG(bool, timing, false, | 31 DEFINE_FLAG(bool, |
| 32 timing, |
| 33 false, |
31 "Dump isolate timing information from timeline."); | 34 "Dump isolate timing information from timeline."); |
32 DEFINE_FLAG(charp, timeline_dir, NULL, | 35 DEFINE_FLAG(charp, |
| 36 timeline_dir, |
| 37 NULL, |
33 "Enable all timeline trace streams and output VM global trace " | 38 "Enable all timeline trace streams and output VM global trace " |
34 "into specified directory."); | 39 "into specified directory."); |
35 DEFINE_FLAG(charp, timeline_streams, NULL, | 40 DEFINE_FLAG(charp, |
| 41 timeline_streams, |
| 42 NULL, |
36 "Comma separated list of timeline streams to record. " | 43 "Comma separated list of timeline streams to record. " |
37 "Valid values: all, API, Compiler, Dart, Debugger, Embedder, " | 44 "Valid values: all, API, Compiler, Dart, Debugger, Embedder, " |
38 "GC, Isolate, and VM."); | 45 "GC, Isolate, and VM."); |
39 DEFINE_FLAG(charp, timeline_recorder, "ring", | 46 DEFINE_FLAG(charp, |
| 47 timeline_recorder, |
| 48 "ring", |
40 "Select the timeline recorder used. " | 49 "Select the timeline recorder used. " |
41 "Valid values: ring, endless, startup, and systrace.") | 50 "Valid values: ring, endless, startup, and systrace.") |
42 | 51 |
43 // Implementation notes: | 52 // Implementation notes: |
44 // | 53 // |
45 // Writing events: | 54 // Writing events: |
46 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches | 55 // |TimelineEvent|s are written into |TimelineEventBlock|s. Each |Thread| caches |
47 // a |TimelineEventBlock| object so that it can write events without | 56 // a |TimelineEventBlock| object so that it can write events without |
48 // synchronizing with other threads in the system. Even though the |Thread| owns | 57 // synchronizing with other threads in the system. Even though the |Thread| owns |
49 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting | 58 // the |TimelineEventBlock| the block may need to be reclaimed by the reporting |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 } | 166 } |
158 for (intptr_t i = 0; i < streams->length(); i++) { | 167 for (intptr_t i = 0; i < streams->length(); i++) { |
159 free((*streams)[i]); | 168 free((*streams)[i]); |
160 } | 169 } |
161 delete streams; | 170 delete streams; |
162 } | 171 } |
163 | 172 |
164 | 173 |
165 // Returns true if |streams| contains |stream| or "all". Not case sensitive. | 174 // Returns true if |streams| contains |stream| or "all". Not case sensitive. |
166 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { | 175 static bool HasStream(MallocGrowableArray<char*>* streams, const char* stream) { |
167 if ((FLAG_timeline_dir != NULL) || | 176 if ((FLAG_timeline_dir != NULL) || FLAG_timing || FLAG_complete_timeline || |
168 FLAG_timing || FLAG_complete_timeline || FLAG_startup_timeline) { | 177 FLAG_startup_timeline) { |
169 return true; | 178 return true; |
170 } | 179 } |
171 for (intptr_t i = 0; i < streams->length(); i++) { | 180 for (intptr_t i = 0; i < streams->length(); i++) { |
172 const char* checked_stream = (*streams)[i]; | 181 const char* checked_stream = (*streams)[i]; |
173 if ((strstr(checked_stream, "all") != NULL) || | 182 if ((strstr(checked_stream, "all") != NULL) || |
174 (strstr(checked_stream, stream) != NULL)) { | 183 (strstr(checked_stream, stream) != NULL)) { |
175 return true; | 184 return true; |
176 } | 185 } |
177 } | 186 } |
178 return false; | 187 return false; |
179 } | 188 } |
180 | 189 |
181 | 190 |
182 void Timeline::InitOnce() { | 191 void Timeline::InitOnce() { |
183 ASSERT(recorder_ == NULL); | 192 ASSERT(recorder_ == NULL); |
184 recorder_ = CreateTimelineRecorder(); | 193 recorder_ = CreateTimelineRecorder(); |
185 ASSERT(recorder_ != NULL); | 194 ASSERT(recorder_ != NULL); |
186 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); | 195 enabled_streams_ = GetEnabledByDefaultTimelineStreams(); |
187 // Global overrides. | 196 // Global overrides. |
188 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ | 197 #define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ |
189 stream_##name##_.Init(#name, \ | 198 stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); |
190 HasStream(enabled_streams_, #name)); | |
191 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) | 199 TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) |
192 #undef TIMELINE_STREAM_FLAG_DEFAULT | 200 #undef TIMELINE_STREAM_FLAG_DEFAULT |
193 | 201 |
194 if (Timeline::stream_Embedder_.enabled() && | 202 if (Timeline::stream_Embedder_.enabled() && |
195 (Timeline::get_start_recording_cb() != NULL)) { | 203 (Timeline::get_start_recording_cb() != NULL)) { |
196 Timeline::get_start_recording_cb()(); | 204 Timeline::get_start_recording_cb()(); |
197 } | 205 } |
198 } | 206 } |
199 | 207 |
200 | 208 |
(...skipping 18 matching lines...) Expand all Loading... |
219 | 227 |
220 if (Timeline::stream_Embedder_.enabled() && | 228 if (Timeline::stream_Embedder_.enabled() && |
221 (Timeline::get_stop_recording_cb() != NULL)) { | 229 (Timeline::get_stop_recording_cb() != NULL)) { |
222 Timeline::get_stop_recording_cb()(); | 230 Timeline::get_stop_recording_cb()(); |
223 } | 231 } |
224 | 232 |
225 if (FLAG_timeline_dir != NULL) { | 233 if (FLAG_timeline_dir != NULL) { |
226 recorder_->WriteTo(FLAG_timeline_dir); | 234 recorder_->WriteTo(FLAG_timeline_dir); |
227 } | 235 } |
228 | 236 |
229 // Disable global streams. | 237 // Disable global streams. |
230 #define TIMELINE_STREAM_DISABLE(name, not_used) \ | 238 #define TIMELINE_STREAM_DISABLE(name, not_used) \ |
231 Timeline::stream_##name##_.set_enabled(false); | 239 Timeline::stream_##name##_.set_enabled(false); |
232 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) | 240 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) |
233 #undef TIMELINE_STREAM_DISABLE | 241 #undef TIMELINE_STREAM_DISABLE |
234 delete recorder_; | 242 delete recorder_; |
235 recorder_ = NULL; | 243 recorder_ = NULL; |
236 if (enabled_streams_ != NULL) { | 244 if (enabled_streams_ != NULL) { |
237 FreeEnabledByDefaultTimelineStreams(enabled_streams_); | 245 FreeEnabledByDefaultTimelineStreams(enabled_streams_); |
238 enabled_streams_ = NULL; | 246 enabled_streams_ = NULL; |
239 } | 247 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 JSONObject obj(js); | 279 JSONObject obj(js); |
272 obj.AddProperty("type", "TimelineFlags"); | 280 obj.AddProperty("type", "TimelineFlags"); |
273 TimelineEventRecorder* recorder = Timeline::recorder(); | 281 TimelineEventRecorder* recorder = Timeline::recorder(); |
274 if (recorder == NULL) { | 282 if (recorder == NULL) { |
275 obj.AddProperty("recorderName", "null"); | 283 obj.AddProperty("recorderName", "null"); |
276 } else { | 284 } else { |
277 obj.AddProperty("recorderName", recorder->name()); | 285 obj.AddProperty("recorderName", recorder->name()); |
278 } | 286 } |
279 { | 287 { |
280 JSONArray availableStreams(&obj, "availableStreams"); | 288 JSONArray availableStreams(&obj, "availableStreams"); |
281 #define ADD_STREAM_NAME(name, not_used) \ | 289 #define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); |
282 availableStreams.AddValue(#name); | 290 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); |
283 TIMELINE_STREAM_LIST(ADD_STREAM_NAME); | |
284 #undef ADD_STREAM_NAME | 291 #undef ADD_STREAM_NAME |
285 } | 292 } |
286 { | 293 { |
287 JSONArray recordedStreams(&obj, "recordedStreams"); | 294 JSONArray recordedStreams(&obj, "recordedStreams"); |
288 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ | 295 #define ADD_RECORDED_STREAM_NAME(name, not_used) \ |
289 if (stream_##name##_.enabled()) { \ | 296 if (stream_##name##_.enabled()) { \ |
290 recordedStreams.AddValue(#name); \ | 297 recordedStreams.AddValue(#name); \ |
291 } | 298 } |
292 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); | 299 TIMELINE_STREAM_LIST(ADD_RECORDED_STREAM_NAME); |
293 #undef ADD_RECORDED_STREAM_NAME | 300 #undef ADD_RECORDED_STREAM_NAME |
294 } | 301 } |
295 } | 302 } |
296 | 303 |
297 | 304 |
298 void Timeline::Clear() { | 305 void Timeline::Clear() { |
299 TimelineEventRecorder* recorder = Timeline::recorder(); | 306 TimelineEventRecorder* recorder = Timeline::recorder(); |
300 if (recorder == NULL) { | 307 if (recorder == NULL) { |
301 return; | 308 return; |
302 } | 309 } |
303 ReclaimCachedBlocksFromThreads(); | 310 ReclaimCachedBlocksFromThreads(); |
304 recorder->Clear(); | 311 recorder->Clear(); |
305 } | 312 } |
306 | 313 |
307 | 314 |
308 TimelineEventRecorder* Timeline::recorder_ = NULL; | 315 TimelineEventRecorder* Timeline::recorder_ = NULL; |
309 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; | 316 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL; |
310 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; | 317 Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL; |
311 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; | 318 Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL; |
312 | 319 |
313 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ | 320 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ |
314 TimelineStream Timeline::stream_##name##_; | 321 TimelineStream Timeline::stream_##name##_; |
315 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) | 322 TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) |
316 #undef TIMELINE_STREAM_DEFINE | 323 #undef TIMELINE_STREAM_DEFINE |
317 | 324 |
318 TimelineEvent::TimelineEvent() | 325 TimelineEvent::TimelineEvent() |
319 : timestamp0_(0), | 326 : timestamp0_(0), |
320 timestamp1_(0), | 327 timestamp1_(0), |
321 thread_timestamp0_(-1), | 328 thread_timestamp0_(-1), |
322 thread_timestamp1_(-1), | 329 thread_timestamp1_(-1), |
323 arguments_(NULL), | 330 arguments_(NULL), |
324 arguments_length_(0), | 331 arguments_length_(0), |
325 state_(0), | 332 state_(0), |
326 label_(NULL), | 333 label_(NULL), |
327 category_(""), | 334 category_(""), |
328 thread_(OSThread::kInvalidThreadId), | 335 thread_(OSThread::kInvalidThreadId), |
329 isolate_id_(ILLEGAL_PORT) { | 336 isolate_id_(ILLEGAL_PORT) {} |
330 } | |
331 | 337 |
332 | 338 |
333 TimelineEvent::~TimelineEvent() { | 339 TimelineEvent::~TimelineEvent() { |
334 Reset(); | 340 Reset(); |
335 } | 341 } |
336 | 342 |
337 | 343 |
338 void TimelineEvent::Reset() { | 344 void TimelineEvent::Reset() { |
339 if (owns_label() && label_ != NULL) { | 345 if (owns_label() && label_ != NULL) { |
340 free(const_cast<char*>(label_)); | 346 free(const_cast<char*>(label_)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 389 |
384 void TimelineEvent::DurationBegin(const char* label, | 390 void TimelineEvent::DurationBegin(const char* label, |
385 int64_t micros, | 391 int64_t micros, |
386 int64_t thread_micros) { | 392 int64_t thread_micros) { |
387 Init(kDuration, label); | 393 Init(kDuration, label); |
388 set_timestamp0(micros); | 394 set_timestamp0(micros); |
389 set_thread_timestamp0(thread_micros); | 395 set_thread_timestamp0(thread_micros); |
390 } | 396 } |
391 | 397 |
392 | 398 |
393 void TimelineEvent::DurationEnd(int64_t micros, | 399 void TimelineEvent::DurationEnd(int64_t micros, int64_t thread_micros) { |
394 int64_t thread_micros) { | |
395 ASSERT(timestamp1_ == 0); | 400 ASSERT(timestamp1_ == 0); |
396 set_timestamp1(micros); | 401 set_timestamp1(micros); |
397 set_thread_timestamp1(thread_micros); | 402 set_thread_timestamp1(thread_micros); |
398 } | 403 } |
399 | 404 |
400 | 405 |
401 void TimelineEvent::Instant(const char* label, | 406 void TimelineEvent::Instant(const char* label, int64_t micros) { |
402 int64_t micros) { | |
403 Init(kInstant, label); | 407 Init(kInstant, label); |
404 set_timestamp0(micros); | 408 set_timestamp0(micros); |
405 } | 409 } |
406 | 410 |
407 | 411 |
408 void TimelineEvent::Duration(const char* label, | 412 void TimelineEvent::Duration(const char* label, |
409 int64_t start_micros, | 413 int64_t start_micros, |
410 int64_t end_micros, | 414 int64_t end_micros, |
411 int64_t thread_start_micros, | 415 int64_t thread_start_micros, |
412 int64_t thread_end_micros) { | 416 int64_t thread_end_micros) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 | 474 |
471 | 475 |
472 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { | 476 void TimelineEvent::SetArgument(intptr_t i, const char* name, char* argument) { |
473 ASSERT(i >= 0); | 477 ASSERT(i >= 0); |
474 ASSERT(i < arguments_length_); | 478 ASSERT(i < arguments_length_); |
475 arguments_[i].name = name; | 479 arguments_[i].name = name; |
476 arguments_[i].value = argument; | 480 arguments_[i].value = argument; |
477 } | 481 } |
478 | 482 |
479 | 483 |
480 void TimelineEvent::FormatArgument(intptr_t i, const char* name, | 484 void TimelineEvent::FormatArgument(intptr_t i, |
481 const char* fmt, ...) { | 485 const char* name, |
| 486 const char* fmt, |
| 487 ...) { |
482 ASSERT(i >= 0); | 488 ASSERT(i >= 0); |
483 ASSERT(i < arguments_length_); | 489 ASSERT(i < arguments_length_); |
484 va_list args; | 490 va_list args; |
485 va_start(args, fmt); | 491 va_start(args, fmt); |
486 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 492 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
487 va_end(args); | 493 va_end(args); |
488 | 494 |
489 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 495 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
490 va_list args2; | 496 va_list args2; |
491 va_start(args2, fmt); | 497 va_start(args2, fmt); |
(...skipping 20 matching lines...) Expand all Loading... |
512 | 518 |
513 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 519 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
514 ASSERT(buffer != NULL); | 520 ASSERT(buffer != NULL); |
515 ASSERT(buffer_size > 0); | 521 ASSERT(buffer_size > 0); |
516 buffer[0] = '\0'; | 522 buffer[0] = '\0'; |
517 intptr_t length = 0; | 523 intptr_t length = 0; |
518 int64_t pid = OS::ProcessId(); | 524 int64_t pid = OS::ProcessId(); |
519 switch (event_type()) { | 525 switch (event_type()) { |
520 case kBegin: { | 526 case kBegin: { |
521 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); | 527 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, label()); |
522 } | 528 } break; |
523 break; | |
524 case kEnd: { | 529 case kEnd: { |
525 length = OS::SNPrint(buffer, buffer_size, "E"); | 530 length = OS::SNPrint(buffer, buffer_size, "E"); |
526 } | 531 } break; |
527 break; | |
528 case kCounter: { | 532 case kCounter: { |
529 if (arguments_length_ > 0) { | 533 if (arguments_length_ > 0) { |
530 // We only report the first counter value. | 534 // We only report the first counter value. |
531 length = OS::SNPrint(buffer, buffer_size, | 535 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, |
532 "C|%" Pd64 "|%s|%s", | 536 label(), arguments_[0].value); |
533 pid, | |
534 label(), | |
535 arguments_[0].value); | |
536 } | 537 } |
537 } | 538 } |
538 default: | 539 default: |
539 // Ignore event types that we cannot serialize to the Systrace format. | 540 // Ignore event types that we cannot serialize to the Systrace format. |
540 break; | 541 break; |
541 } | 542 } |
542 return length; | 543 return length; |
543 } | 544 } |
544 | 545 |
545 | 546 |
546 void TimelineEvent::Complete() { | 547 void TimelineEvent::Complete() { |
547 TimelineEventRecorder* recorder = Timeline::recorder(); | 548 TimelineEventRecorder* recorder = Timeline::recorder(); |
548 if (recorder != NULL) { | 549 if (recorder != NULL) { |
549 recorder->CompleteEvent(this); | 550 recorder->CompleteEvent(this); |
550 } | 551 } |
(...skipping 15 matching lines...) Expand all Loading... |
566 | 567 |
567 void TimelineEvent::StreamInit(TimelineStream* stream) { | 568 void TimelineEvent::StreamInit(TimelineStream* stream) { |
568 if (stream != NULL) { | 569 if (stream != NULL) { |
569 category_ = stream->name(); | 570 category_ = stream->name(); |
570 } else { | 571 } else { |
571 category_ = ""; | 572 category_ = ""; |
572 } | 573 } |
573 } | 574 } |
574 | 575 |
575 | 576 |
576 void TimelineEvent::Init(EventType event_type, | 577 void TimelineEvent::Init(EventType event_type, const char* label) { |
577 const char* label) { | |
578 ASSERT(label != NULL); | 578 ASSERT(label != NULL); |
579 state_ = 0; | 579 state_ = 0; |
580 timestamp0_ = 0; | 580 timestamp0_ = 0; |
581 timestamp1_ = 0; | 581 timestamp1_ = 0; |
582 thread_timestamp0_ = -1; | 582 thread_timestamp0_ = -1; |
583 thread_timestamp1_ = -1; | 583 thread_timestamp1_ = -1; |
584 OSThread* os_thread = OSThread::Current(); | 584 OSThread* os_thread = OSThread::Current(); |
585 ASSERT(os_thread != NULL); | 585 ASSERT(os_thread != NULL); |
586 thread_ = os_thread->trace_id(); | 586 thread_ = os_thread->trace_id(); |
587 Isolate* isolate = Isolate::Current(); | 587 Isolate* isolate = Isolate::Current(); |
588 if (isolate != NULL) { | 588 if (isolate != NULL) { |
589 isolate_id_ = isolate->main_port(); | 589 isolate_id_ = isolate->main_port(); |
590 } else { | 590 } else { |
591 isolate_id_ = ILLEGAL_PORT; | 591 isolate_id_ = ILLEGAL_PORT; |
592 } | 592 } |
593 label_ = label; | 593 label_ = label; |
594 FreeArguments(); | 594 FreeArguments(); |
595 set_pre_serialized_json(false); | 595 set_pre_serialized_json(false); |
596 set_event_type(event_type); | 596 set_event_type(event_type); |
597 set_owns_label(false); | 597 set_owns_label(false); |
598 } | 598 } |
599 | 599 |
600 | 600 |
601 bool TimelineEvent::Within(int64_t time_origin_micros, | 601 bool TimelineEvent::Within(int64_t time_origin_micros, |
602 int64_t time_extent_micros) { | 602 int64_t time_extent_micros) { |
603 if ((time_origin_micros == -1) || | 603 if ((time_origin_micros == -1) || (time_extent_micros == -1)) { |
604 (time_extent_micros == -1)) { | |
605 // No time range specified. | 604 // No time range specified. |
606 return true; | 605 return true; |
607 } | 606 } |
608 if (IsFinishedDuration()) { | 607 if (IsFinishedDuration()) { |
609 // Event is from e_t0 to e_t1. | 608 // Event is from e_t0 to e_t1. |
610 int64_t e_t0 = TimeOrigin(); | 609 int64_t e_t0 = TimeOrigin(); |
611 int64_t e_t1 = TimeEnd(); | 610 int64_t e_t1 = TimeEnd(); |
612 ASSERT(e_t0 <= e_t1); | 611 ASSERT(e_t0 <= e_t1); |
613 // Range is from r_t0 to r_t1. | 612 // Range is from r_t0 to r_t1. |
614 int64_t r_t0 = time_origin_micros; | 613 int64_t r_t0 = time_origin_micros; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 obj.AddProperty("cat", category_); | 645 obj.AddProperty("cat", category_); |
647 obj.AddProperty64("tid", tid); | 646 obj.AddProperty64("tid", tid); |
648 obj.AddProperty64("pid", pid); | 647 obj.AddProperty64("pid", pid); |
649 obj.AddPropertyTimeMicros("ts", TimeOrigin()); | 648 obj.AddPropertyTimeMicros("ts", TimeOrigin()); |
650 if (HasThreadCPUTime()) { | 649 if (HasThreadCPUTime()) { |
651 obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin()); | 650 obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin()); |
652 } | 651 } |
653 switch (event_type()) { | 652 switch (event_type()) { |
654 case kBegin: { | 653 case kBegin: { |
655 obj.AddProperty("ph", "B"); | 654 obj.AddProperty("ph", "B"); |
656 } | 655 } break; |
657 break; | |
658 case kEnd: { | 656 case kEnd: { |
659 obj.AddProperty("ph", "E"); | 657 obj.AddProperty("ph", "E"); |
660 } | 658 } break; |
661 break; | |
662 case kDuration: { | 659 case kDuration: { |
663 obj.AddProperty("ph", "X"); | 660 obj.AddProperty("ph", "X"); |
664 obj.AddPropertyTimeMicros("dur", TimeDuration()); | 661 obj.AddPropertyTimeMicros("dur", TimeDuration()); |
665 if (HasThreadCPUTime()) { | 662 if (HasThreadCPUTime()) { |
666 obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration()); | 663 obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration()); |
667 } | 664 } |
668 } | 665 } break; |
669 break; | |
670 case kInstant: { | 666 case kInstant: { |
671 obj.AddProperty("ph", "i"); | 667 obj.AddProperty("ph", "i"); |
672 obj.AddProperty("s", "p"); | 668 obj.AddProperty("s", "p"); |
673 } | 669 } break; |
674 break; | |
675 case kAsyncBegin: { | 670 case kAsyncBegin: { |
676 obj.AddProperty("ph", "b"); | 671 obj.AddProperty("ph", "b"); |
677 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 672 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |
678 } | 673 } break; |
679 break; | |
680 case kAsyncInstant: { | 674 case kAsyncInstant: { |
681 obj.AddProperty("ph", "n"); | 675 obj.AddProperty("ph", "n"); |
682 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 676 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |
683 } | 677 } break; |
684 break; | |
685 case kAsyncEnd: { | 678 case kAsyncEnd: { |
686 obj.AddProperty("ph", "e"); | 679 obj.AddProperty("ph", "e"); |
687 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); | 680 obj.AddPropertyF("id", "%" Px64 "", AsyncId()); |
688 } | 681 } break; |
689 break; | |
690 case kMetadata: { | 682 case kMetadata: { |
691 obj.AddProperty("ph", "M"); | 683 obj.AddProperty("ph", "M"); |
692 } | 684 } break; |
693 break; | |
694 case kCounter: { | 685 case kCounter: { |
695 obj.AddProperty("ph", "C"); | 686 obj.AddProperty("ph", "C"); |
696 } | 687 } break; |
697 break; | |
698 default: | 688 default: |
699 UNIMPLEMENTED(); | 689 UNIMPLEMENTED(); |
700 } | 690 } |
701 { | 691 { |
702 JSONObject args(&obj, "args"); | 692 JSONObject args(&obj, "args"); |
703 for (intptr_t i = 0; i < arguments_length_; i++) { | 693 for (intptr_t i = 0; i < arguments_length_; i++) { |
704 const TimelineEventArgument& arg = arguments_[i]; | 694 const TimelineEventArgument& arg = arguments_[i]; |
705 args.AddProperty(arg.name, arg.value); | 695 args.AddProperty(arg.name, arg.value); |
706 } | 696 } |
707 if (isolate_id_ != ILLEGAL_PORT) { | 697 if (isolate_id_ != ILLEGAL_PORT) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 } | 734 } |
745 return timestamp1_ - timestamp0_; | 735 return timestamp1_ - timestamp0_; |
746 } | 736 } |
747 | 737 |
748 | 738 |
749 bool TimelineEvent::HasThreadCPUTime() const { | 739 bool TimelineEvent::HasThreadCPUTime() const { |
750 return (thread_timestamp0_ != -1); | 740 return (thread_timestamp0_ != -1); |
751 } | 741 } |
752 | 742 |
753 | 743 |
754 | |
755 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { | 744 int64_t TimelineEvent::ThreadCPUTimeOrigin() const { |
756 ASSERT(HasThreadCPUTime()); | 745 ASSERT(HasThreadCPUTime()); |
757 return thread_timestamp0_; | 746 return thread_timestamp0_; |
758 } | 747 } |
759 | 748 |
760 | 749 |
761 int64_t TimelineEvent::ThreadCPUTimeDuration() const { | 750 int64_t TimelineEvent::ThreadCPUTimeDuration() const { |
762 ASSERT(HasThreadCPUTime()); | 751 ASSERT(HasThreadCPUTime()); |
763 if (thread_timestamp1_ == -1) { | 752 if (thread_timestamp1_ == -1) { |
764 // This duration is still open, use current time as end. | 753 // This duration is still open, use current time as end. |
765 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; | 754 return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_; |
766 } | 755 } |
767 return thread_timestamp1_ - thread_timestamp0_; | 756 return thread_timestamp1_ - thread_timestamp0_; |
768 } | 757 } |
769 | 758 |
770 | 759 |
771 TimelineStream::TimelineStream() | 760 TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} |
772 : name_(NULL), | |
773 enabled_(false) { | |
774 } | |
775 | 761 |
776 | 762 |
777 void TimelineStream::Init(const char* name, | 763 void TimelineStream::Init(const char* name, bool enabled) { |
778 bool enabled) { | |
779 name_ = name; | 764 name_ = name; |
780 enabled_ = enabled; | 765 enabled_ = enabled; |
781 } | 766 } |
782 | 767 |
783 | 768 |
784 TimelineEvent* TimelineStream::StartEvent() { | 769 TimelineEvent* TimelineStream::StartEvent() { |
785 TimelineEventRecorder* recorder = Timeline::recorder(); | 770 TimelineEventRecorder* recorder = Timeline::recorder(); |
786 if (!enabled() || (recorder == NULL)) { | 771 if (!enabled() || (recorder == NULL)) { |
787 return NULL; | 772 return NULL; |
788 } | 773 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 const char* argument) { | 857 const char* argument) { |
873 if (!enabled()) { | 858 if (!enabled()) { |
874 return; | 859 return; |
875 } | 860 } |
876 SetArgument(i, name, strdup(argument)); | 861 SetArgument(i, name, strdup(argument)); |
877 } | 862 } |
878 | 863 |
879 | 864 |
880 void TimelineEventScope::FormatArgument(intptr_t i, | 865 void TimelineEventScope::FormatArgument(intptr_t i, |
881 const char* name, | 866 const char* name, |
882 const char* fmt, ...) { | 867 const char* fmt, |
| 868 ...) { |
883 if (!enabled()) { | 869 if (!enabled()) { |
884 return; | 870 return; |
885 } | 871 } |
886 va_list args; | 872 va_list args; |
887 va_start(args, fmt); | 873 va_start(args, fmt); |
888 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 874 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
889 va_end(args); | 875 va_end(args); |
890 | 876 |
891 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 877 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
892 va_list args2; | 878 va_list args2; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 if (!ShouldEmitEvent()) { | 937 if (!ShouldEmitEvent()) { |
952 return; | 938 return; |
953 } | 939 } |
954 TimelineEvent* event = stream()->StartEvent(); | 940 TimelineEvent* event = stream()->StartEvent(); |
955 if (event == NULL) { | 941 if (event == NULL) { |
956 // Stream is now disabled. | 942 // Stream is now disabled. |
957 return; | 943 return; |
958 } | 944 } |
959 ASSERT(event != NULL); | 945 ASSERT(event != NULL); |
960 // Emit a duration event. | 946 // Emit a duration event. |
961 event->Duration(label(), | 947 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
962 timestamp_, | 948 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
963 OS::GetCurrentMonotonicMicros(), | |
964 thread_timestamp_, | |
965 OS::GetCurrentThreadCPUMicros()); | |
966 StealArguments(event); | 949 StealArguments(event); |
967 event->Complete(); | 950 event->Complete(); |
968 } | 951 } |
969 | 952 |
970 | 953 |
971 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 954 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |
972 const char* label) | 955 const char* label) |
973 : TimelineEventScope(stream, label) { | 956 : TimelineEventScope(stream, label) { |
974 if (!FLAG_support_timeline) { | 957 if (!FLAG_support_timeline) { |
975 return; | 958 return; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 | 1023 |
1041 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, | 1024 TimelineEventFilter::TimelineEventFilter(int64_t time_origin_micros, |
1042 int64_t time_extent_micros) | 1025 int64_t time_extent_micros) |
1043 : time_origin_micros_(time_origin_micros), | 1026 : time_origin_micros_(time_origin_micros), |
1044 time_extent_micros_(time_extent_micros) { | 1027 time_extent_micros_(time_extent_micros) { |
1045 ASSERT(time_origin_micros_ >= -1); | 1028 ASSERT(time_origin_micros_ >= -1); |
1046 ASSERT(time_extent_micros_ >= -1); | 1029 ASSERT(time_extent_micros_ >= -1); |
1047 } | 1030 } |
1048 | 1031 |
1049 | 1032 |
1050 TimelineEventFilter::~TimelineEventFilter() { | 1033 TimelineEventFilter::~TimelineEventFilter() {} |
1051 } | |
1052 | 1034 |
1053 | 1035 |
1054 IsolateTimelineEventFilter::IsolateTimelineEventFilter( | 1036 IsolateTimelineEventFilter::IsolateTimelineEventFilter( |
1055 Dart_Port isolate_id, | 1037 Dart_Port isolate_id, |
1056 int64_t time_origin_micros, | 1038 int64_t time_origin_micros, |
1057 int64_t time_extent_micros) | 1039 int64_t time_extent_micros) |
1058 : TimelineEventFilter(time_origin_micros, | 1040 : TimelineEventFilter(time_origin_micros, time_extent_micros), |
1059 time_extent_micros), | 1041 isolate_id_(isolate_id) {} |
1060 isolate_id_(isolate_id) { | |
1061 } | |
1062 | 1042 |
1063 | 1043 |
1064 TimelineEventRecorder::TimelineEventRecorder() | 1044 TimelineEventRecorder::TimelineEventRecorder() |
1065 : async_id_(0), | 1045 : async_id_(0), time_low_micros_(0), time_high_micros_(0) {} |
1066 time_low_micros_(0), | |
1067 time_high_micros_(0) { | |
1068 } | |
1069 | 1046 |
1070 | 1047 |
1071 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 1048 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
1072 if (!FLAG_support_service) { | 1049 if (!FLAG_support_service) { |
1073 return; | 1050 return; |
1074 } | 1051 } |
1075 OSThreadIterator it; | 1052 OSThreadIterator it; |
1076 while (it.HasNext()) { | 1053 while (it.HasNext()) { |
1077 OSThread* thread = it.Next(); | 1054 OSThread* thread = it.Next(); |
1078 const char* thread_name = thread->name(); | 1055 const char* thread_name = thread->name(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 // Thread has no block. Attempt to allocate one. | 1103 // Thread has no block. Attempt to allocate one. |
1127 thread_block = GetNewBlockLocked(); | 1104 thread_block = GetNewBlockLocked(); |
1128 thread->set_timeline_block(thread_block); | 1105 thread->set_timeline_block(thread_block); |
1129 } | 1106 } |
1130 if (thread_block != NULL) { | 1107 if (thread_block != NULL) { |
1131 // NOTE: We are exiting this function with the thread's block lock held. | 1108 // NOTE: We are exiting this function with the thread's block lock held. |
1132 ASSERT(!thread_block->IsFull()); | 1109 ASSERT(!thread_block->IsFull()); |
1133 TimelineEvent* event = thread_block->StartEvent(); | 1110 TimelineEvent* event = thread_block->StartEvent(); |
1134 return event; | 1111 return event; |
1135 } | 1112 } |
1136 // Drop lock here as no event is being handed out. | 1113 // Drop lock here as no event is being handed out. |
1137 #if defined(DEBUG) | 1114 #if defined(DEBUG) |
1138 if (T != NULL) { | 1115 if (T != NULL) { |
1139 T->DecrementNoSafepointScopeDepth(); | 1116 T->DecrementNoSafepointScopeDepth(); |
1140 } | 1117 } |
1141 #endif // defined(DEBUG) | 1118 #endif // defined(DEBUG) |
1142 thread_block_lock->Unlock(); | 1119 thread_block_lock->Unlock(); |
1143 return NULL; | 1120 return NULL; |
1144 } | 1121 } |
1145 | 1122 |
1146 | 1123 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 Dart_FileOpenCallback file_open = Dart::file_open_callback(); | 1180 Dart_FileOpenCallback file_open = Dart::file_open_callback(); |
1204 Dart_FileWriteCallback file_write = Dart::file_write_callback(); | 1181 Dart_FileWriteCallback file_write = Dart::file_write_callback(); |
1205 Dart_FileCloseCallback file_close = Dart::file_close_callback(); | 1182 Dart_FileCloseCallback file_close = Dart::file_close_callback(); |
1206 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 1183 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
1207 return; | 1184 return; |
1208 } | 1185 } |
1209 | 1186 |
1210 Timeline::ReclaimCachedBlocksFromThreads(); | 1187 Timeline::ReclaimCachedBlocksFromThreads(); |
1211 | 1188 |
1212 intptr_t pid = OS::ProcessId(); | 1189 intptr_t pid = OS::ProcessId(); |
1213 char* filename = OS::SCreate(NULL, | 1190 char* filename = |
1214 "%s/dart-timeline-%" Pd ".json", directory, pid); | 1191 OS::SCreate(NULL, "%s/dart-timeline-%" Pd ".json", directory, pid); |
1215 void* file = (*file_open)(filename, true); | 1192 void* file = (*file_open)(filename, true); |
1216 if (file == NULL) { | 1193 if (file == NULL) { |
1217 OS::Print("Failed to write timeline file: %s\n", filename); | 1194 OS::Print("Failed to write timeline file: %s\n", filename); |
1218 free(filename); | 1195 free(filename); |
1219 return; | 1196 return; |
1220 } | 1197 } |
1221 free(filename); | 1198 free(filename); |
1222 | 1199 |
1223 JSONStream js; | 1200 JSONStream js; |
1224 TimelineEventFilter filter; | 1201 TimelineEventFilter filter; |
1225 PrintTraceEvent(&js, &filter); | 1202 PrintTraceEvent(&js, &filter); |
1226 // Steal output from JSONStream. | 1203 // Steal output from JSONStream. |
1227 char* output = NULL; | 1204 char* output = NULL; |
1228 intptr_t output_length = 0; | 1205 intptr_t output_length = 0; |
1229 js.Steal(&output, &output_length); | 1206 js.Steal(&output, &output_length); |
1230 (*file_write)(output, output_length, file); | 1207 (*file_write)(output, output_length, file); |
1231 // Free the stolen output. | 1208 // Free the stolen output. |
1232 free(output); | 1209 free(output); |
1233 (*file_close)(file); | 1210 (*file_close)(file); |
1234 | 1211 |
1235 return; | 1212 return; |
1236 } | 1213 } |
1237 | 1214 |
1238 | 1215 |
1239 int64_t TimelineEventRecorder::GetNextAsyncId() { | 1216 int64_t TimelineEventRecorder::GetNextAsyncId() { |
1240 // TODO(johnmccutchan): Gracefully handle wrap around. | 1217 // TODO(johnmccutchan): Gracefully handle wrap around. |
1241 uint32_t next = static_cast<uint32_t>( | 1218 uint32_t next = |
1242 AtomicOperations::FetchAndIncrement(&async_id_)); | 1219 static_cast<uint32_t>(AtomicOperations::FetchAndIncrement(&async_id_)); |
1243 return static_cast<int64_t>(next); | 1220 return static_cast<int64_t>(next); |
1244 } | 1221 } |
1245 | 1222 |
1246 | 1223 |
1247 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { | 1224 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |
1248 if (block == NULL) { | 1225 if (block == NULL) { |
1249 return; | 1226 return; |
1250 } | 1227 } |
1251 MutexLocker ml(&lock_); | 1228 MutexLocker ml(&lock_); |
1252 block->Finish(); | 1229 block->Finish(); |
1253 } | 1230 } |
1254 | 1231 |
1255 | 1232 |
1256 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 1233 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
1257 MutexLocker ml(&lock_); | 1234 MutexLocker ml(&lock_); |
1258 return GetNewBlockLocked(); | 1235 return GetNewBlockLocked(); |
1259 } | 1236 } |
1260 | 1237 |
1261 | 1238 |
1262 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( | 1239 TimelineEventFixedBufferRecorder::TimelineEventFixedBufferRecorder( |
1263 intptr_t capacity) | 1240 intptr_t capacity) |
1264 : blocks_(NULL), | 1241 : blocks_(NULL), capacity_(capacity), num_blocks_(0), block_cursor_(0) { |
1265 capacity_(capacity), | |
1266 num_blocks_(0), | |
1267 block_cursor_(0) { | |
1268 // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 1242 // Capacity must be a multiple of TimelineEventBlock::kBlockSize |
1269 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 1243 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
1270 // Allocate blocks array. | 1244 // Allocate blocks array. |
1271 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 1245 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |
1272 blocks_ = | 1246 blocks_ = reinterpret_cast<TimelineEventBlock**>( |
1273 reinterpret_cast<TimelineEventBlock**>( | 1247 calloc(num_blocks_, sizeof(TimelineEventBlock*))); |
1274 calloc(num_blocks_, sizeof(TimelineEventBlock*))); | |
1275 // Allocate each block. | 1248 // Allocate each block. |
1276 for (intptr_t i = 0; i < num_blocks_; i++) { | 1249 for (intptr_t i = 0; i < num_blocks_; i++) { |
1277 blocks_[i] = new TimelineEventBlock(i); | 1250 blocks_[i] = new TimelineEventBlock(i); |
1278 } | 1251 } |
1279 // Chain blocks together. | 1252 // Chain blocks together. |
1280 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 1253 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |
1281 blocks_[i]->set_next(blocks_[i + 1]); | 1254 blocks_[i]->set_next(blocks_[i + 1]); |
1282 } | 1255 } |
1283 } | 1256 } |
1284 | 1257 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 | 1367 |
1395 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { | 1368 void TimelineEventFixedBufferRecorder::CompleteEvent(TimelineEvent* event) { |
1396 if (event == NULL) { | 1369 if (event == NULL) { |
1397 return; | 1370 return; |
1398 } | 1371 } |
1399 ThreadBlockCompleteEvent(event); | 1372 ThreadBlockCompleteEvent(event); |
1400 } | 1373 } |
1401 | 1374 |
1402 | 1375 |
1403 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | 1376 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |
1404 : TimelineEventFixedBufferRecorder(capacity), | 1377 : TimelineEventFixedBufferRecorder(capacity), systrace_fd_(-1) { |
1405 systrace_fd_(-1) { | |
1406 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) | 1378 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) |
1407 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | 1379 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; |
1408 systrace_fd_ = open(kSystracePath, O_WRONLY); | 1380 systrace_fd_ = open(kSystracePath, O_WRONLY); |
1409 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | 1381 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { |
1410 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | 1382 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |
1411 kSystracePath); | 1383 kSystracePath); |
1412 } | 1384 } |
1413 #else | 1385 #else |
1414 OS::PrintErr("Warning: The systrace timeline recorder is equivalent to the" | 1386 OS::PrintErr( |
1415 "ring recorder on this platform."); | 1387 "Warning: The systrace timeline recorder is equivalent to the" |
| 1388 "ring recorder on this platform."); |
1416 #endif | 1389 #endif |
1417 } | 1390 } |
1418 | 1391 |
1419 | 1392 |
1420 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | 1393 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { |
1421 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) | 1394 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_LINUX) |
1422 if (systrace_fd_ >= 0) { | 1395 if (systrace_fd_ >= 0) { |
1423 close(systrace_fd_); | 1396 close(systrace_fd_); |
1424 } | 1397 } |
1425 #endif | 1398 #endif |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1480 if (block_cursor_ == num_blocks_) { | 1453 if (block_cursor_ == num_blocks_) { |
1481 return NULL; | 1454 return NULL; |
1482 } | 1455 } |
1483 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1456 TimelineEventBlock* block = blocks_[block_cursor_++]; |
1484 block->Reset(); | 1457 block->Reset(); |
1485 block->Open(); | 1458 block->Open(); |
1486 return block; | 1459 return block; |
1487 } | 1460 } |
1488 | 1461 |
1489 | 1462 |
1490 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() { | 1463 TimelineEventCallbackRecorder::TimelineEventCallbackRecorder() {} |
1491 } | |
1492 | 1464 |
1493 | 1465 |
1494 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() { | 1466 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {} |
1495 } | |
1496 | 1467 |
1497 | 1468 |
1498 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, | 1469 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js, |
1499 TimelineEventFilter* filter) { | 1470 TimelineEventFilter* filter) { |
1500 if (!FLAG_support_service) { | 1471 if (!FLAG_support_service) { |
1501 return; | 1472 return; |
1502 } | 1473 } |
1503 JSONObject topLevel(js); | 1474 JSONObject topLevel(js); |
1504 topLevel.AddProperty("type", "_Timeline"); | 1475 topLevel.AddProperty("type", "_Timeline"); |
1505 { | 1476 { |
1506 JSONArray events(&topLevel, "traceEvents"); | 1477 JSONArray events(&topLevel, "traceEvents"); |
1507 PrintJSONMeta(&events); | 1478 PrintJSONMeta(&events); |
1508 } | 1479 } |
1509 } | 1480 } |
(...skipping 15 matching lines...) Expand all Loading... |
1525 } | 1496 } |
1526 | 1497 |
1527 | 1498 |
1528 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { | 1499 void TimelineEventCallbackRecorder::CompleteEvent(TimelineEvent* event) { |
1529 OnEvent(event); | 1500 OnEvent(event); |
1530 delete event; | 1501 delete event; |
1531 } | 1502 } |
1532 | 1503 |
1533 | 1504 |
1534 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 1505 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
1535 : head_(NULL), | 1506 : head_(NULL), block_index_(0) {} |
1536 block_index_(0) { | |
1537 } | |
1538 | 1507 |
1539 | 1508 |
1540 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, | 1509 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, |
1541 TimelineEventFilter* filter) { | 1510 TimelineEventFilter* filter) { |
1542 if (!FLAG_support_service) { | 1511 if (!FLAG_support_service) { |
1543 return; | 1512 return; |
1544 } | 1513 } |
1545 JSONObject topLevel(js); | 1514 JSONObject topLevel(js); |
1546 topLevel.AddProperty("type", "_Timeline"); | 1515 topLevel.AddProperty("type", "_Timeline"); |
1547 { | 1516 { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 OSThread* thread = OSThread::Current(); | 1624 OSThread* thread = OSThread::Current(); |
1656 thread->set_timeline_block(NULL); | 1625 thread->set_timeline_block(NULL); |
1657 } | 1626 } |
1658 | 1627 |
1659 | 1628 |
1660 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 1629 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
1661 : next_(NULL), | 1630 : next_(NULL), |
1662 length_(0), | 1631 length_(0), |
1663 block_index_(block_index), | 1632 block_index_(block_index), |
1664 thread_id_(OSThread::kInvalidThreadId), | 1633 thread_id_(OSThread::kInvalidThreadId), |
1665 in_use_(false) { | 1634 in_use_(false) {} |
1666 } | |
1667 | 1635 |
1668 | 1636 |
1669 TimelineEventBlock::~TimelineEventBlock() { | 1637 TimelineEventBlock::~TimelineEventBlock() { |
1670 Reset(); | 1638 Reset(); |
1671 } | 1639 } |
1672 | 1640 |
1673 | 1641 |
1674 void TimelineEventBlock::PrintJSON(JSONStream* js) const { | 1642 void TimelineEventBlock::PrintJSON(JSONStream* js) const { |
1675 ASSERT(!in_use()); | 1643 ASSERT(!in_use()); |
1676 JSONArray events(js); | 1644 JSONArray events(js); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 if (Service::timeline_stream.enabled()) { | 1721 if (Service::timeline_stream.enabled()) { |
1754 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); | 1722 ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents); |
1755 service_event.set_timeline_event_block(this); | 1723 service_event.set_timeline_event_block(this); |
1756 Service::HandleEvent(&service_event); | 1724 Service::HandleEvent(&service_event); |
1757 } | 1725 } |
1758 } | 1726 } |
1759 | 1727 |
1760 | 1728 |
1761 TimelineEventBlockIterator::TimelineEventBlockIterator( | 1729 TimelineEventBlockIterator::TimelineEventBlockIterator( |
1762 TimelineEventRecorder* recorder) | 1730 TimelineEventRecorder* recorder) |
1763 : current_(NULL), | 1731 : current_(NULL), recorder_(NULL) { |
1764 recorder_(NULL) { | |
1765 Reset(recorder); | 1732 Reset(recorder); |
1766 } | 1733 } |
1767 | 1734 |
1768 | 1735 |
1769 TimelineEventBlockIterator::~TimelineEventBlockIterator() { | 1736 TimelineEventBlockIterator::~TimelineEventBlockIterator() { |
1770 Reset(NULL); | 1737 Reset(NULL); |
1771 } | 1738 } |
1772 | 1739 |
1773 | 1740 |
1774 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { | 1741 void TimelineEventBlockIterator::Reset(TimelineEventRecorder* recorder) { |
(...skipping 22 matching lines...) Expand all Loading... |
1797 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1764 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
1798 ASSERT(current_ != NULL); | 1765 ASSERT(current_ != NULL); |
1799 TimelineEventBlock* r = current_; | 1766 TimelineEventBlock* r = current_; |
1800 current_ = current_->next(); | 1767 current_ = current_->next(); |
1801 return r; | 1768 return r; |
1802 } | 1769 } |
1803 | 1770 |
1804 } // namespace dart | 1771 } // namespace dart |
1805 | 1772 |
1806 #endif // !PRODUCT | 1773 #endif // !PRODUCT |
OLD | NEW |