Chromium Code Reviews| Index: runtime/vm/timeline.cc |
| diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc |
| index 716ac8b7b098f1f382fe3be1c0b5d1f7772d76c4..4d4737072bfc7245cc9dc45c34c5692b32167a35 100644 |
| --- a/runtime/vm/timeline.cc |
| +++ b/runtime/vm/timeline.cc |
| @@ -2,12 +2,17 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| +#include "platform/globals.h" |
| #ifndef PRODUCT |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <cstdlib> |
| +#if defined(HOST_OS_FUCHSIA) |
| +#include "apps/tracing/lib/trace/event.h" |
| +#endif |
| + |
| #include "vm/atomic.h" |
| #include "vm/isolate.h" |
| #include "vm/json_stream.h" |
| @@ -516,6 +521,97 @@ void TimelineEvent::StealArguments(intptr_t arguments_length, |
| } |
| +#if defined(HOST_OS_FUCHSIA) |
| + |
| +// TODO(zra): The functions below emit Dart's timeline events all as category |
| +// "dart". Instead, we could have finer-grained categories that make use of |
| +// the name of the timeline stream, e.g. "VM", "GC", etc. |
| + |
| +#define FUCHSIA_EVENT_ARGS_LIST(V) \ |
| + V(Begin, TRACE_DURATION_BEGIN) \ |
| + V(End, TRACE_DURATION_END) |
| + |
| +#define EMIT_FUCHSIA_EVENT(__name, __macro) \ |
| +static void EmitFuchsia##__name##Event(const char* label, \ |
| + TimelineEventArgument* arguments, \ |
| + intptr_t arguments_length) { \ |
| + if (arguments_length == 0) { \ |
| + __macro("dart", label); \ |
| + } else if (arguments_length == 1) { \ |
| + __macro("dart", label, arguments[0].name, \ |
| + const_cast<const char*>(arguments[0].value)); \ |
| + } else { \ |
| + __macro("dart", label, arguments[0].name, \ |
| + const_cast<const char*>(arguments[0].value), \ |
| + arguments[1].name, \ |
| + const_cast<const char*>(arguments[1].value)); \ |
| + } \ |
| +} |
| + |
| +FUCHSIA_EVENT_ARGS_LIST(EMIT_FUCHSIA_EVENT) |
| +#undef EMIT_FUCHSIA_EVENT |
| + |
| +#define FUCHSIA_EVENT_ID_ARGS_LIST(V) \ |
| + V(Instant, TRACE_INSTANT, ::tracing::EventScope) \ |
| + V(AsyncBegin, TRACE_ASYNC_BEGIN, int64_t) \ |
| + V(AsyncEnd, TRACE_ASYNC_END, int64_t) \ |
| + V(AsyncInstant, TRACE_ASYNC_INSTANT, int64_t) |
| + |
| +#define EMIT_FUCHSIA_EVENT(__name, __macro, __id_typ) \ |
| +static void EmitFuchsia##__name##Event(const char* label, \ |
| + __id_typ id, \ |
| + TimelineEventArgument* arguments, \ |
| + intptr_t arguments_length) { \ |
| + if (arguments_length == 0) { \ |
| + __macro("dart", label, id); \ |
| + } else if (arguments_length == 1) { \ |
| + __macro("dart", label, id, arguments[0].name, \ |
| + const_cast<const char*>(arguments[0].value)); \ |
| + } else { \ |
| + __macro("dart", label, id, arguments[0].name, \ |
| + const_cast<const char*>(arguments[0].value), \ |
| + arguments[1].name, \ |
| + const_cast<const char*>(arguments[1].value)); \ |
| + } \ |
| +} |
| + |
| +FUCHSIA_EVENT_ID_ARGS_LIST(EMIT_FUCHSIA_EVENT) |
| +#undef EMIT_FUCHSIA_EVENT |
| + |
| + |
| +void TimelineEvent::EmitFuchsiaEvent() { |
| + switch (event_type()) { |
| + case kBegin: |
| + EmitFuchsiaBeginEvent(label_, arguments_, arguments_length_); |
| + break; |
| + case kEnd: |
| + EmitFuchsiaEndEvent(label_, arguments_, arguments_length_); |
| + break; |
| + case kInstant: |
| + EmitFuchsiaInstantEvent( |
| + label_, TRACE_SCOPE_THREAD, arguments_, arguments_length_); |
| + break; |
| + case kAsyncBegin: |
| + EmitFuchsiaAsyncBeginEvent( |
| + label_, AsyncId(), arguments_, arguments_length_); |
| + break; |
| + case kAsyncEnd: |
| + EmitFuchsiaAsyncEndEvent( |
| + label_, AsyncId(), arguments_, arguments_length_); |
| + break; |
| + case kAsyncInstant: |
| + EmitFuchsiaAsyncInstantEvent( |
| + label_, AsyncId(), arguments_, arguments_length_); |
| + break; |
| + default: |
| + // TODO(zra): Figure out what to do with kDuration, kCounter, and |
|
rmacnak
2017/07/10 23:39:02
Duration is the most common event type.
zra
2017/07/11 17:38:04
Except when coming through Dart_TimelineEvent(), k
|
| + // kMetadata. |
| + break; |
| + } |
| +} |
| +#endif |
| + |
| + |
| intptr_t TimelineEvent::PrintSystrace(char* buffer, intptr_t buffer_size) { |
| ASSERT(buffer != NULL); |
| ASSERT(buffer_size > 0); |
| @@ -913,8 +1009,12 @@ TimelineDurationScope::TimelineDurationScope(TimelineStream* stream, |
| if (!FLAG_support_timeline || !enabled()) { |
| return; |
| } |
| +#if defined(HOST_OS_FUCHSIA) |
| + TRACE_DURATION_BEGIN("dart", label); |
| +#else |
| timestamp_ = OS::GetCurrentMonotonicMicros(); |
| thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| +#endif |
| } |
| @@ -925,8 +1025,12 @@ TimelineDurationScope::TimelineDurationScope(Thread* thread, |
| if (!FLAG_support_timeline || !enabled()) { |
| return; |
| } |
| +#if defined(HOST_OS_FUCHSIA) |
| + TRACE_DURATION_BEGIN("dart", label); |
| +#else |
| timestamp_ = OS::GetCurrentMonotonicMicros(); |
| thread_timestamp_ = OS::GetCurrentThreadCPUMicros(); |
| +#endif |
| } |
| @@ -937,6 +1041,9 @@ TimelineDurationScope::~TimelineDurationScope() { |
| if (!ShouldEmitEvent()) { |
| return; |
| } |
| +#if defined(HOST_OS_FUCHSIA) |
| + EmitFuchsiaEndEvent(label(), arguments(), arguments_length()); |
| +#else |
| TimelineEvent* event = stream()->StartEvent(); |
| if (event == NULL) { |
| // Stream is now disabled. |
| @@ -948,6 +1055,7 @@ TimelineDurationScope::~TimelineDurationScope() { |
| thread_timestamp_, OS::GetCurrentThreadCPUMicros()); |
| StealArguments(event); |
| event->Complete(); |
| +#endif |
| } |
| @@ -1382,6 +1490,8 @@ TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) |
| OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", |
| kSystracePath); |
| } |
| +#elif defined(HOST_OS_FUCHSIA) |
| + // Nothing to do. |
| #else |
| OS::PrintErr( |
| "Warning: The systrace timeline recorder is equivalent to the" |
| @@ -1431,6 +1541,8 @@ void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { |
| } while ((__result == -1L) && (errno == EINTR)); |
| } |
| } |
| +#elif defined(HOST_OS_FUCHSIA) |
| + event->EmitFuchsiaEvent(); |
| #endif |
| ThreadBlockCompleteEvent(event); |
| } |