| 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> |
| 11 | 11 |
| 12 #if defined(HOST_OS_FUCHSIA) | 12 #if defined(HOST_OS_FUCHSIA) |
| 13 #include "apps/tracing/lib/trace/cwriter.h" |
| 13 #include "apps/tracing/lib/trace/event.h" | 14 #include "apps/tracing/lib/trace/event.h" |
| 14 #endif | 15 #endif |
| 15 | 16 |
| 16 #include "vm/atomic.h" | 17 #include "vm/atomic.h" |
| 17 #include "vm/isolate.h" | 18 #include "vm/isolate.h" |
| 18 #include "vm/json_stream.h" | 19 #include "vm/json_stream.h" |
| 19 #include "vm/lockers.h" | 20 #include "vm/lockers.h" |
| 20 #include "vm/log.h" | 21 #include "vm/log.h" |
| 21 #include "vm/object.h" | 22 #include "vm/object.h" |
| 22 #include "vm/service_event.h" | 23 #include "vm/service_event.h" |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 TimelineEventArgument* arguments) { | 523 TimelineEventArgument* arguments) { |
| 523 arguments_length_ = arguments_length; | 524 arguments_length_ = arguments_length; |
| 524 arguments_ = arguments; | 525 arguments_ = arguments; |
| 525 } | 526 } |
| 526 | 527 |
| 527 #if defined(HOST_OS_FUCHSIA) | 528 #if defined(HOST_OS_FUCHSIA) |
| 528 // TODO(zra): The functions below emit Dart's timeline events all as category | 529 // TODO(zra): The functions below emit Dart's timeline events all as category |
| 529 // "dart". Instead, we could have finer-grained categories that make use of | 530 // "dart". Instead, we could have finer-grained categories that make use of |
| 530 // the name of the timeline stream, e.g. "VM", "GC", etc. | 531 // the name of the timeline stream, e.g. "VM", "GC", etc. |
| 531 | 532 |
| 532 #define FUCHSIA_EVENT_ARGS_LIST(V) \ | |
| 533 V(Begin, TRACE_DURATION_BEGIN) \ | |
| 534 V(End, TRACE_DURATION_END) | |
| 535 | 533 |
| 536 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ | 534 void TimelineEvent::EmitFuchsiaEvent() { |
| 537 static void EmitFuchsia##__name##Event(const char* label, \ | 535 if (!ctrace_is_enabled()) { |
| 538 TimelineEventArgument* arguments, \ | 536 return; |
| 539 intptr_t arguments_length) { \ | 537 } |
| 540 if (arguments_length == 0) { \ | 538 auto writer = ctrace_writer_acquire(); |
| 541 __macro("dart", label); \ | 539 |
| 542 } else if (arguments_length == 1) { \ | 540 // XXX: use ctrace_register_category_string(); |
| 543 __macro("dart", label, arguments[0].name, \ | 541 ctrace_stringref_t category; |
| 544 const_cast<const char*>(arguments[0].value)); \ | 542 ctrace_register_string(writer, "dart", &category); |
| 545 } else { \ | 543 |
| 546 __macro("dart", label, arguments[0].name, \ | 544 ctrace_stringref_t name; |
| 547 const_cast<const char*>(arguments[0].value), arguments[1].name, \ | 545 ctrace_register_string(writer, label_, &name); |
| 548 const_cast<const char*>(arguments[1].value)); \ | 546 |
| 549 } \ | 547 ctrace_threadref_t thread; |
| 548 ctrace_register_current_thread(writer, &thread); |
| 549 |
| 550 ctrace_argspec_t args[2]; |
| 551 ctrace_arglist_t arglist = {0, args}; |
| 552 |
| 553 if (arguments_length_ >= 1) { |
| 554 args[0].type = CTRACE_ARGUMENT_STRING; |
| 555 args[0].name = arguments_[0].name; |
| 556 args[0].u.s = arguments_[0].value; |
| 557 arglist.n_args += 1; |
| 558 } |
| 559 if (arguments_length_ >= 2) { |
| 560 args[1].type = CTRACE_ARGUMENT_STRING; |
| 561 args[1].name = arguments_[1].name; |
| 562 args[1].u.s = arguments_[1].value; |
| 563 arglist.n_args += 1; |
| 550 } | 564 } |
| 551 | 565 |
| 552 FUCHSIA_EVENT_ARGS_LIST(EMIT_FUCHSIA_EVENT) | 566 const uint64_t time_scale = mx_ticks_per_second() / kMicrosecondsPerSecond; |
| 553 #undef EMIT_FUCHSIA_EVENT | 567 const uint64_t start_time = LowTime() * time_scale; |
| 568 const uint64_t end_time = HighTime() * time_scale; |
| 554 | 569 |
| 555 #define FUCHSIA_EVENT_ID_ARGS_LIST(V) \ | |
| 556 V(Instant, TRACE_INSTANT, ::tracing::EventScope) \ | |
| 557 V(AsyncBegin, TRACE_ASYNC_BEGIN, int64_t) \ | |
| 558 V(AsyncEnd, TRACE_ASYNC_END, int64_t) \ | |
| 559 V(AsyncInstant, TRACE_ASYNC_INSTANT, int64_t) \ | |
| 560 V(FlowBegin, TRACE_FLOW_BEGIN, int64_t) \ | |
| 561 V(FlowStep, TRACE_FLOW_STEP, int64_t) \ | |
| 562 V(FlowEnd, TRACE_FLOW_END, int64_t) | |
| 563 | |
| 564 #define EMIT_FUCHSIA_EVENT(__name, __macro, __id_typ) \ | |
| 565 static void EmitFuchsia##__name##Event(const char* label, __id_typ id, \ | |
| 566 TimelineEventArgument* arguments, \ | |
| 567 intptr_t arguments_length) { \ | |
| 568 if (arguments_length == 0) { \ | |
| 569 __macro("dart", label, id); \ | |
| 570 } else if (arguments_length == 1) { \ | |
| 571 __macro("dart", label, id, arguments[0].name, \ | |
| 572 const_cast<const char*>(arguments[0].value)); \ | |
| 573 } else { \ | |
| 574 __macro("dart", label, id, arguments[0].name, \ | |
| 575 const_cast<const char*>(arguments[0].value), arguments[1].name, \ | |
| 576 const_cast<const char*>(arguments[1].value)); \ | |
| 577 } \ | |
| 578 } | |
| 579 | |
| 580 FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) | |
| 581 #undef EMIT_FUCHSIA_EVENT | |
| 582 | |
| 583 void TimelineEvent::EmitFuchsiaEvent() { | |
| 584 switch (event_type()) { | 570 switch (event_type()) { |
| 585 case kBegin: | 571 case kBegin: |
| 586 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); | 572 ctrace_write_duration_begin_event_record(writer, start_time, &thread, |
| 573 &category, &name, &arglist); |
| 587 break; | 574 break; |
| 588 case kEnd: | 575 case kEnd: |
| 589 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); | 576 ctrace_write_duration_end_event_record(writer, end_time, &thread, |
| 577 &category, &name, &arglist); |
| 590 break; | 578 break; |
| 591 case kInstant: | 579 case kInstant: |
| 592 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, | 580 ctrace_write_instant_event_record(writer, start_time, &thread, |
| 593 arguments_length_); | 581 &category, &name, |
| 582 CTRACE_SCOPE_THREAD, &arglist); |
| 594 break; | 583 break; |
| 595 case kAsyncBegin: | 584 case kAsyncBegin: |
| 596 EmitFuchsiaAsyncBeginEvent(label_, AsyncId(), arguments_, | 585 ctrace_write_async_begin_event_record(writer, start_time, &thread, |
| 597 arguments_length_); | 586 &category, &name, |
| 587 AsyncId(), &arglist); |
| 598 break; | 588 break; |
| 599 case kAsyncEnd: | 589 case kAsyncEnd: |
| 600 EmitFuchsiaAsyncEndEvent(label_, AsyncId(), arguments_, | 590 ctrace_write_async_end_event_record(writer, end_time, &thread, |
| 601 arguments_length_); | 591 &category, &name, |
| 592 AsyncId(), &arglist); |
| 602 break; | 593 break; |
| 603 case kAsyncInstant: | 594 case kAsyncInstant: |
| 604 EmitFuchsiaAsyncInstantEvent(label_, AsyncId(), arguments_, | 595 ctrace_write_async_instant_event_record(writer, start_time, &thread, |
| 605 arguments_length_); | 596 &category, &name, |
| 597 AsyncId(), &arglist); |
| 598 break; |
| 599 case kDuration: |
| 600 ctrace_write_duration_event_record(writer, start_time, end_time, &thread, |
| 601 &category, &name, &arglist); |
| 606 break; | 602 break; |
| 607 case kFlowBegin: | 603 case kFlowBegin: |
| 608 EmitFuchsiaFlowBeginEvent(label_, AsyncId(), arguments_, | 604 ctrace_write_flow_begin_event_record(writer, start_time, &thread, |
| 609 arguments_length_); | 605 &category, &name, |
| 606 AsyncId(), &arglist); |
| 610 break; | 607 break; |
| 611 case kFlowStep: | 608 case kFlowStep: |
| 612 EmitFuchsiaFlowStepEvent(label_, AsyncId(), arguments_, | 609 ctrace_write_flow_step_event_record(writer, start_time, &thread, |
| 613 arguments_length_); | 610 &category, &name, |
| 611 AsyncId(), &arglist); |
| 614 break; | 612 break; |
| 615 case kFlowEnd: | 613 case kFlowEnd: |
| 616 EmitFuchsiaFlowEndEvent(label_, AsyncId(), arguments_, arguments_length_); | 614 ctrace_write_flow_end_event_record(writer, start_time, &thread, |
| 615 &category, &name, |
| 616 AsyncId(), &arglist); |
| 617 break; | 617 break; |
| 618 default: | 618 default: |
| 619 // TODO(zra): Figure out what to do with kDuration, kCounter, and | 619 // TODO(zra): Figure out what to do with kCounter and kMetadata. |
| 620 // kMetadata. | |
| 621 break; | 620 break; |
| 622 } | 621 } |
| 622 ctrace_writer_release(writer); |
| 623 } | 623 } |
| 624 #endif | 624 #endif |
| 625 | 625 |
| 626 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 626 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
| 627 ASSERT(buffer != NULL); | 627 ASSERT(buffer != NULL); |
| 628 ASSERT(buffer_size > 0); | 628 ASSERT(buffer_size > 0); |
| 629 buffer[0] = '\0'; | 629 buffer[0] = '\0'; |
| 630 intptr_t length = 0; | 630 intptr_t length = 0; |
| 631 int64_t pid = OS::ProcessId(); | 631 int64_t pid = OS::ProcessId(); |
| 632 switch (event_type()) { | 632 switch (event_type()) { |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 arguments_length_ = 0; | 997 arguments_length_ = 0; |
| 998 arguments_ = NULL; | 998 arguments_ = NULL; |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, | 1001 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
| 1002 const char* label) | 1002 const char* label) |
| 1003 : TimelineEventScope(stream, label) { | 1003 : TimelineEventScope(stream, label) { |
| 1004 if (!FLAG_support_timeline || !enabled()) { | 1004 if (!FLAG_support_timeline || !enabled()) { |
| 1005 return; | 1005 return; |
| 1006 } | 1006 } |
| 1007 #if defined(HOST_OS_FUCHSIA) | |
| 1008 TRACE_DURATION_BEGIN("dart", label); | |
| 1009 #else | |
| 1010 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1007 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1011 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1008 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1012 #endif | |
| 1013 } | 1009 } |
| 1014 | 1010 |
| 1015 TimelineDurationScope::TimelineDurationScope(Thread* thread, | 1011 TimelineDurationScope::TimelineDurationScope(Thread* thread, |
| 1016 TimelineStream* stream, | 1012 TimelineStream* stream, |
| 1017 const char* label) | 1013 const char* label) |
| 1018 : TimelineEventScope(thread, stream, label) { | 1014 : TimelineEventScope(thread, stream, label) { |
| 1019 if (!FLAG_support_timeline || !enabled()) { | 1015 if (!FLAG_support_timeline || !enabled()) { |
| 1020 return; | 1016 return; |
| 1021 } | 1017 } |
| 1022 #if defined(HOST_OS_FUCHSIA) | |
| 1023 TRACE_DURATION_BEGIN("dart", label); | |
| 1024 #else | |
| 1025 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1018 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1026 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1019 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1027 #endif | |
| 1028 } | 1020 } |
| 1029 | 1021 |
| 1030 TimelineDurationScope::~TimelineDurationScope() { | 1022 TimelineDurationScope::~TimelineDurationScope() { |
| 1031 if (!FLAG_support_timeline) { | 1023 if (!FLAG_support_timeline) { |
| 1032 return; | 1024 return; |
| 1033 } | 1025 } |
| 1034 if (!ShouldEmitEvent()) { | 1026 if (!ShouldEmitEvent()) { |
| 1035 return; | 1027 return; |
| 1036 } | 1028 } |
| 1037 #if defined(HOST_OS_FUCHSIA) | |
| 1038 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | |
| 1039 #else | |
| 1040 TimelineEvent* event = stream()->StartEvent(); | 1029 TimelineEvent* event = stream()->StartEvent(); |
| 1041 if (event == NULL) { | 1030 if (event == NULL) { |
| 1042 // Stream is now disabled. | 1031 // Stream is now disabled. |
| 1043 return; | 1032 return; |
| 1044 } | 1033 } |
| 1045 ASSERT(event != NULL); | 1034 ASSERT(event != NULL); |
| 1046 // Emit a duration event. | 1035 // Emit a duration event. |
| 1047 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 1036 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
| 1048 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 1037 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
| 1049 StealArguments(event); | 1038 StealArguments(event); |
| 1050 event->Complete(); | 1039 event->Complete(); |
| 1051 #endif | |
| 1052 } | 1040 } |
| 1053 | 1041 |
| 1054 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, | 1042 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream, |
| 1055 const char* label) | 1043 const char* label) |
| 1056 : TimelineEventScope(stream, label) { | 1044 : TimelineEventScope(stream, label) { |
| 1057 if (!FLAG_support_timeline) { | 1045 if (!FLAG_support_timeline) { |
| 1058 return; | 1046 return; |
| 1059 } | 1047 } |
| 1060 EmitBegin(); | 1048 EmitBegin(); |
| 1061 } | 1049 } |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1826 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
| 1839 ASSERT(current_ != NULL); | 1827 ASSERT(current_ != NULL); |
| 1840 TimelineEventBlock* r = current_; | 1828 TimelineEventBlock* r = current_; |
| 1841 current_ = current_->next(); | 1829 current_ = current_->next(); |
| 1842 return r; | 1830 return r; |
| 1843 } | 1831 } |
| 1844 | 1832 |
| 1845 } // namespace dart | 1833 } // namespace dart |
| 1846 | 1834 |
| 1847 #endif // !PRODUCT | 1835 #endif // !PRODUCT |
| OLD | NEW |