Chromium Code Reviews| 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/event.h" | 13 #include "apps/tracing/lib/trace/event.h" |
| 14 #include "apps/tracing/lib/trace/cwriter.h" | |
|
zra
2017/07/19 21:26:23
Alphabetize includes
konkers
2017/07/19 21:52:32
Done.
| |
| 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" |
| 23 #include "vm/thread.h" | 24 #include "vm/thread.h" |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 SetArgument(i, name, strdup(argument)); | 519 SetArgument(i, name, strdup(argument)); |
| 519 } | 520 } |
| 520 | 521 |
| 521 void TimelineEvent::StealArguments(intptr_t arguments_length, | 522 void TimelineEvent::StealArguments(intptr_t arguments_length, |
| 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 void TimelineEvent::EmitFuchsiaEvent() { |
| 529 // "dart". Instead, we could have finer-grained categories that make use of | 530 if (!ctrace_is_enabled()) { |
| 530 // the name of the timeline stream, e.g. "VM", "GC", etc. | 531 return; |
| 532 } | |
| 533 auto writer = ctrace_writer_acquire(); | |
| 531 | 534 |
| 532 #define FUCHSIA_EVENT_ARGS_LIST(V) \ | 535 // XXX: use ctrace_register_category_string(); |
| 533 V(Begin, TRACE_DURATION_BEGIN) \ | 536 ctrace_stringref_t category; |
| 534 V(End, TRACE_DURATION_END) | 537 ctrace_register_string(writer, "dart", &category); |
| 535 | 538 |
| 536 #define EMIT_FUCHSIA_EVENT(__name, __macro) \ | 539 ctrace_stringref_t name; |
| 537 static void EmitFuchsia##__name##Event(const char* label, \ | 540 ctrace_register_string(writer, label_, &name); |
| 538 TimelineEventArgument* arguments, \ | 541 |
| 539 intptr_t arguments_length) { \ | 542 ctrace_threadref_t thread; |
| 540 if (arguments_length == 0) { \ | 543 ctrace_register_current_thread(writer, &thread); |
| 541 __macro("dart", label); \ | 544 |
| 542 } else if (arguments_length == 1) { \ | 545 ctrace_argspec_t args[2]; |
| 543 __macro("dart", label, arguments[0].name, \ | 546 ctrace_arglist_t arglist = {0, args}; |
| 544 const_cast<const char*>(arguments[0].value)); \ | 547 |
| 545 } else { \ | 548 if (arguments_length_ >= 1) { |
| 546 __macro("dart", label, arguments[0].name, \ | 549 args[0].type = CTRACE_ARGUMENT_STRING; |
| 547 const_cast<const char*>(arguments[0].value), arguments[1].name, \ | 550 args[0].name = arguments_[0].name; |
| 548 const_cast<const char*>(arguments[1].value)); \ | 551 args[0].u.s = arguments_[0].value; |
| 549 } \ | 552 arglist.n_args += 1; |
| 553 } | |
| 554 if (arguments_length_ >= 2) { | |
| 555 args[1].type = CTRACE_ARGUMENT_STRING; | |
| 556 args[1].name = arguments_[1].name; | |
| 557 args[1].u.s = arguments_[1].value; | |
| 558 arglist.n_args += 1; | |
| 550 } | 559 } |
| 551 | 560 |
| 552 FUCHSIA_EVENT_ARGS_LIST(EMIT_FUCHSIA_EVENT) | 561 uint64_t time_scale = mx_ticks_per_second() / kMicrosecondsPerSecond; |
|
zra
2017/07/19 21:26:23
const
konkers
2017/07/19 21:52:32
Done.
| |
| 553 #undef EMIT_FUCHSIA_EVENT | 562 uint64_t start_time = LowTime() * time_scale; |
|
zra
2017/07/19 21:26:23
const
konkers
2017/07/19 21:52:32
Done.
| |
| 563 uint64_t end_time = HighTime() * time_scale; | |
|
zra
2017/07/19 21:26:23
const
konkers
2017/07/19 21:52:31
Done.
| |
| 554 | 564 |
| 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()) { | 565 switch (event_type()) { |
| 585 case kBegin: | 566 case kBegin: |
| 586 EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); | 567 ctrace_write_duration_begin_event_record(writer, start_time, &thread, |
| 568 &category, &name, &arglist); | |
| 587 break; | 569 break; |
| 588 case kEnd: | 570 case kEnd: |
| 589 EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); | 571 ctrace_write_duration_end_event_record(writer, end_time, &thread, |
| 572 &category, &name, &arglist); | |
| 590 break; | 573 break; |
| 591 case kInstant: | 574 case kInstant: |
| 592 EmitFuchsiaInstantEvent(label_, TRACE_SCOPE_THREAD, arguments_, | 575 ctrace_write_instant_event_record(writer, start_time, &thread, |
| 593 arguments_length_); | 576 &category, &name, |
| 577 CTRACE_SCOPE_THREAD, &arglist); | |
| 594 break; | 578 break; |
| 595 case kAsyncBegin: | 579 case kAsyncBegin: |
| 596 EmitFuchsiaAsyncBeginEvent(label_, AsyncId(), arguments_, | 580 ctrace_write_async_begin_event_record(writer, start_time, &thread, |
| 597 arguments_length_); | 581 &category, &name, |
| 582 AsyncId(), &arglist); | |
| 598 break; | 583 break; |
| 599 case kAsyncEnd: | 584 case kAsyncEnd: |
| 600 EmitFuchsiaAsyncEndEvent(label_, AsyncId(), arguments_, | 585 ctrace_write_async_end_event_record(writer, end_time, &thread, |
| 601 arguments_length_); | 586 &category, &name, |
| 587 AsyncId(), &arglist); | |
| 602 break; | 588 break; |
| 603 case kAsyncInstant: | 589 case kAsyncInstant: |
| 604 EmitFuchsiaAsyncInstantEvent(label_, AsyncId(), arguments_, | 590 ctrace_write_async_instant_event_record(writer, start_time, &thread, |
| 605 arguments_length_); | 591 &category, &name, |
| 592 AsyncId(), &arglist); | |
| 593 break; | |
| 594 case kDuration: | |
| 595 ctrace_write_duration_event_record(writer, start_time, end_time, &thread, | |
| 596 &category, &name, &arglist); | |
| 606 break; | 597 break; |
| 607 case kFlowBegin: | 598 case kFlowBegin: |
| 608 EmitFuchsiaFlowBeginEvent(label_, AsyncId(), arguments_, | 599 ctrace_write_flow_begin_event_record(writer, start_time, &thread, |
| 609 arguments_length_); | 600 &category, &name, |
| 601 AsyncId(), &arglist); | |
| 610 break; | 602 break; |
| 611 case kFlowStep: | 603 case kFlowStep: |
| 612 EmitFuchsiaFlowStepEvent(label_, AsyncId(), arguments_, | 604 ctrace_write_flow_step_event_record(writer, start_time, &thread, |
| 613 arguments_length_); | 605 &category, &name, |
| 606 AsyncId(), &arglist); | |
| 614 break; | 607 break; |
| 615 case kFlowEnd: | 608 case kFlowEnd: |
| 616 EmitFuchsiaFlowEndEvent(label_, AsyncId(), arguments_, arguments_length_); | 609 ctrace_write_flow_end_event_record(writer, start_time, &thread, |
| 610 &category, &name, | |
| 611 AsyncId(), &arglist); | |
| 617 break; | 612 break; |
| 618 default: | 613 default: |
| 619 // TODO(zra): Figure out what to do with kDuration, kCounter, and | 614 // TODO(zra): Figure out what to do with kCounter and kMetadata. |
| 620 // kMetadata. | |
| 621 break; | 615 break; |
| 622 } | 616 } |
| 617 ctrace_writer_release(writer); | |
| 623 } | 618 } |
| 624 #endif | 619 #endif |
| 625 | 620 |
| 626 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { | 621 intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
| 627 ASSERT(buffer != NULL); | 622 ASSERT(buffer != NULL); |
| 628 ASSERT(buffer_size > 0); | 623 ASSERT(buffer_size > 0); |
| 629 buffer[0] = '\0'; | 624 buffer[0] = '\0'; |
| 630 intptr_t length = 0; | 625 intptr_t length = 0; |
| 631 int64_t pid = OS::ProcessId(); | 626 int64_t pid = OS::ProcessId(); |
| 632 switch (event_type()) { | 627 switch (event_type()) { |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 997 arguments_length_ = 0; | 992 arguments_length_ = 0; |
| 998 arguments_ = NULL; | 993 arguments_ = NULL; |
| 999 } | 994 } |
| 1000 | 995 |
| 1001 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, | 996 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
| 1002 const char* label) | 997 const char* label) |
| 1003 : TimelineEventScope(stream, label) { | 998 : TimelineEventScope(stream, label) { |
| 1004 if (!FLAG_support_timeline || !enabled()) { | 999 if (!FLAG_support_timeline || !enabled()) { |
| 1005 return; | 1000 return; |
| 1006 } | 1001 } |
| 1007 #if defined(HOST_OS_FUCHSIA) | 1002 #if defined(HOST_OS_FUCHSIA) |
|
zra
2017/07/19 21:26:23
Since EmitFuchsiaEvent now does the right thing fo
konkers
2017/07/19 21:52:32
Done.
| |
| 1008 TRACE_DURATION_BEGIN("dart", label); | 1003 // XXX |
| 1004 // TRACE_DURATION_BEGIN("dart", label); | |
| 1009 #else | 1005 #else |
| 1010 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1006 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1011 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1007 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1012 #endif | 1008 #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) | 1018 #if defined(HOST_OS_FUCHSIA) |
| 1023 TRACE_DURATION_BEGIN("dart", label); | 1019 // XXX |
| 1020 // TRACE_DURATION_BEGIN("dart", label); | |
| 1024 #else | 1021 #else |
| 1025 timestamp_ = OS::GetCurrentMonotonicMicros(); | 1022 timestamp_ = OS::GetCurrentMonotonicMicros(); |
| 1026 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); | 1023 thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| 1027 #endif | 1024 #endif |
| 1028 } | 1025 } |
| 1029 | 1026 |
| 1030 TimelineDurationScope::~TimelineDurationScope() { | 1027 TimelineDurationScope::~TimelineDurationScope() { |
| 1031 if (!FLAG_support_timeline) { | 1028 if (!FLAG_support_timeline) { |
| 1032 return; | 1029 return; |
| 1033 } | 1030 } |
| 1034 if (!ShouldEmitEvent()) { | 1031 if (!ShouldEmitEvent()) { |
| 1035 return; | 1032 return; |
| 1036 } | 1033 } |
| 1037 #if defined(HOST_OS_FUCHSIA) | 1034 #if defined(HOST_OS_FUCHSIA) |
| 1038 EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | 1035 // XXX |
| 1036 // EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); | |
| 1039 #else | 1037 #else |
| 1040 TimelineEvent* event = stream()->StartEvent(); | 1038 TimelineEvent* event = stream()->StartEvent(); |
| 1041 if (event == NULL) { | 1039 if (event == NULL) { |
| 1042 // Stream is now disabled. | 1040 // Stream is now disabled. |
| 1043 return; | 1041 return; |
| 1044 } | 1042 } |
| 1045 ASSERT(event != NULL); | 1043 ASSERT(event != NULL); |
| 1046 // Emit a duration event. | 1044 // Emit a duration event. |
| 1047 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), | 1045 event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros(), |
| 1048 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); | 1046 thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1498 __result = write(systrace_fd_, buffer, event_length); | 1496 __result = write(systrace_fd_, buffer, event_length); |
| 1499 } while ((__result == -1L) && (errno == EINTR)); | 1497 } while ((__result == -1L) && (errno == EINTR)); |
| 1500 } | 1498 } |
| 1501 } | 1499 } |
| 1502 #endif | 1500 #endif |
| 1503 ThreadBlockCompleteEvent(event); | 1501 ThreadBlockCompleteEvent(event); |
| 1504 } | 1502 } |
| 1505 | 1503 |
| 1506 #if defined(HOST_OS_FUCHSIA) | 1504 #if defined(HOST_OS_FUCHSIA) |
| 1507 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) | 1505 TimelineEventFuchsiaRecorder::TimelineEventFuchsiaRecorder(intptr_t capacity) |
| 1508 : TimelineEventFixedBufferRecorder(capacity) {} | 1506 : TimelineEventFixedBufferRecorder(capacity) { |
| 1507 } | |
| 1509 | 1508 |
| 1509 TimelineEventFuchsiaRecorder::~TimelineEventFuchsiaRecorder() { | |
| 1510 } | |
| 1510 | 1511 |
| 1511 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { | 1512 TimelineEventBlock* TimelineEventFuchsiaRecorder::GetNewBlockLocked() { |
| 1512 // TODO(johnmccutchan): This function should only hand out blocks | 1513 // TODO(johnmccutchan): This function should only hand out blocks |
| 1513 // which have been marked as finished. | 1514 // which have been marked as finished. |
| 1514 if (block_cursor_ == num_blocks_) { | 1515 if (block_cursor_ == num_blocks_) { |
| 1515 block_cursor_ = 0; | 1516 block_cursor_ = 0; |
| 1516 } | 1517 } |
| 1517 TimelineEventBlock* block = blocks_[block_cursor_++]; | 1518 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 1518 block->Reset(); | 1519 block->Reset(); |
| 1519 block->Open(); | 1520 block->Open(); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1838 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1839 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
| 1839 ASSERT(current_ != NULL); | 1840 ASSERT(current_ != NULL); |
| 1840 TimelineEventBlock* r = current_; | 1841 TimelineEventBlock* r = current_; |
| 1841 current_ = current_->next(); | 1842 current_ = current_->next(); |
| 1842 return r; | 1843 return r; |
| 1843 } | 1844 } |
| 1844 | 1845 |
| 1845 } // namespace dart | 1846 } // namespace dart |
| 1846 | 1847 |
| 1847 #endif // !PRODUCT | 1848 #endif // !PRODUCT |
| OLD | NEW |