dart-sdk/runtime/vm/timeline_fuchsia.cc
Chinmay Garde aa64d1d2e6 Allow building Dart with Fuchsia SDK enabled buildroots.
The Fuchsia SDK can now be consumed by non-Fuchsia buildroots to produce
Fuchsia artifacts.

The Fuchsia SDK comes with a JSON manifest that describes the various SDK
"parts". GN targets are stamped for each of these parts. The location of these
GN targets can be configured. That location is set to |fuchsia_sdk_root| in
each buildroot. This variable is defined in //build/fuchsia/sdk.gni in each
buildroot. For buildroots that don't care or know about the Fuchsia SDK, that
file may not exist. This is why, the import of that file is guarded behind
the is_fuchsia flag. When the Fuchsia SDK is enabled, that file will define
values for two required variable |using_fuchsia_sdk| and |fuchsia_sdk_root|.

The first flag defines if the SDK is being used. If unset (but defined), the
builds are in-tree. Eventually we want only SDK builds. |fuchsia_sdk_root|
is set to the spot in the buildroot where the GN targets for the SDK parts
are stamped.

Change-Id: I604612c8d6a21efb07b323610e80b596abc1a6dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101540
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Chinmay Garde <chinmaygarde@google.com>
2019-05-07 00:43:33 +00:00

127 lines
4.7 KiB
C++

// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// 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 "vm/globals.h"
#if defined(HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE) && \
!defined(FUCHSIA_SDK)
#include <trace-engine/context.h>
#include <trace-engine/instrumentation.h>
#include <zircon/syscalls.h>
#include "platform/utils.h"
#include "vm/object.h"
#include "vm/timeline.h"
namespace dart {
void TimelineEventFuchsiaRecorder::OnEvent(TimelineEvent* event) {
if (event == NULL) {
return;
}
TimelineStream* stream = event->stream_;
trace_string_ref_t category;
trace_context_t* context = trace_acquire_context_for_category_cached(
stream->fuchsia_name(), stream->trace_site(), &category);
if (context == NULL) {
return;
}
trace_string_ref_t name;
if (event->owns_label()) {
// If the event owns the name, then the name will be deallocated, so
// instruct the system trace to make a copy.
name = trace_context_make_registered_string_copy(
context, event->label(), strlen(event->label()));
} else {
// If the event doesn't own the name, then it is a string literal, and
// the system trace can use the pointer and not a copy.
name = trace_context_make_registered_string_literal(
context, event->label());
}
trace_thread_ref_t thread;
trace_context_register_current_thread(context, &thread);
trace_arg_t args[TRACE_MAX_ARGS];
const intptr_t num_args = Utils::Minimum(
event->arguments_length(), static_cast<intptr_t>(TRACE_MAX_ARGS));
for (intptr_t i = 0; i < num_args; i++) {
const char* name = event->arguments()[i].name;
const char* value = event->arguments()[i].value;
trace_string_ref_t arg_name =
trace_context_make_registered_string_literal(context, name);
trace_string_ref_t arg_value =
trace_make_inline_string_ref(value, strlen(value));
args[i] = trace_make_arg(arg_name, trace_make_string_arg_value(arg_value));
}
const uint64_t time_scale = zx_ticks_per_second() / kMicrosecondsPerSecond;
const uint64_t start_time = event->LowTime() * time_scale;
const uint64_t end_time = event->HighTime() * time_scale;
// 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.
switch (event->event_type()) {
case TimelineEvent::kBegin:
trace_context_write_duration_begin_event_record(
context, start_time, &thread, &category, &name, args, num_args);
break;
case TimelineEvent::kEnd:
trace_context_write_duration_end_event_record(
context, start_time, &thread, &category, &name, args, num_args);
break;
case TimelineEvent::kInstant:
trace_context_write_instant_event_record(
context, start_time, &thread, &category, &name, TRACE_SCOPE_THREAD,
args, num_args);
break;
case TimelineEvent::kAsyncBegin:
trace_context_write_async_begin_event_record(
context, start_time, &thread, &category, &name, event->AsyncId(),
args, num_args);
break;
case TimelineEvent::kAsyncEnd:
trace_context_write_async_end_event_record(
context, end_time, &thread, &category, &name, event->AsyncId(), args,
num_args);
break;
case TimelineEvent::kAsyncInstant:
trace_context_write_async_instant_event_record(
context, start_time, &thread, &category, &name, event->AsyncId(),
args, num_args);
break;
case TimelineEvent::kDuration:
trace_context_write_duration_event_record(context, start_time, end_time,
&thread, &category, &name, args,
num_args);
break;
case TimelineEvent::kFlowBegin:
trace_context_write_flow_begin_event_record(
context, start_time, &thread, &category, &name, event->AsyncId(),
args, num_args);
break;
case TimelineEvent::kFlowStep:
trace_context_write_flow_step_event_record(
context, start_time, &thread, &category, &name, event->AsyncId(),
args, num_args);
break;
case TimelineEvent::kFlowEnd:
trace_context_write_flow_end_event_record(
context, start_time, &thread, &category, &name, event->AsyncId(),
args, num_args);
break;
default:
// TODO(zra): Figure out what to do with kCounter and kMetadata.
break;
}
trace_release_context(context);
}
} // namespace dart
#endif // defined(HOST_OS_FUCHSIA) && !defined(PRODUCT)