diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 0665729e520..3678fa9c248 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -221,6 +221,12 @@ library_for_all_configs("libdart") { "third_party/double-conversion/src:libdouble_conversion", ":generate_version_cc_file", ] + if (is_fuchsia) { + extra_deps += [ + "//zircon/public/lib/fbl", + "//zircon/public/lib/trace-engine", + ] + } configurable_deps = [ "platform:libdart_platform", "vm:libdart_lib", diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn index e27f88616aa..192b5e0b787 100644 --- a/runtime/vm/BUILD.gn +++ b/runtime/vm/BUILD.gn @@ -67,8 +67,6 @@ library_for_all_configs("libdart_vm") { "//garnet/public/lib/component/cpp", "//sdk/fidl/fuchsia.timezone", - # TODO(zra): When the platform-specific timeline code is moved out to - # the embedder, this can go away. "//zircon/public/lib/fbl", "//zircon/public/lib/trace-engine", ] @@ -85,6 +83,12 @@ library_for_all_configs("libdart_vm") { library_for_all_configs("libdart_lib") { target_type = "source_set" + if (is_fuchsia) { + extra_deps = [ + "//zircon/public/lib/fbl", + "//zircon/public/lib/trace-engine", + ] + } include_dirs = [ ".." ] allsources = async_runtime_sources + collection_runtime_sources + diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc index 1f96aac441f..158c1c3c59c 100644 --- a/runtime/vm/timeline.cc +++ b/runtime/vm/timeline.cc @@ -205,8 +205,8 @@ void Timeline::Init() { ASSERT(recorder_ != NULL); enabled_streams_ = GetEnabledByDefaultTimelineStreams(); // Global overrides. -#define TIMELINE_STREAM_FLAG_DEFAULT(name, not_used) \ - stream_##name##_.Init(#name, HasStream(enabled_streams_, #name)); +#define TIMELINE_STREAM_FLAG_DEFAULT(name, fuchsia_name) \ + stream_##name##_.set_enabled(HasStream(enabled_streams_, #name)); TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT) #undef TIMELINE_STREAM_FLAG_DEFAULT } @@ -221,7 +221,7 @@ void Timeline::Cleanup() { #endif // Disable global streams. -#define TIMELINE_STREAM_DISABLE(name, not_used) \ +#define TIMELINE_STREAM_DISABLE(name, fuchsia_name) \ Timeline::stream_##name##_.set_enabled(false); TIMELINE_STREAM_LIST(TIMELINE_STREAM_DISABLE) #undef TIMELINE_STREAM_DISABLE @@ -270,13 +270,13 @@ void Timeline::PrintFlagsToJSON(JSONStream* js) { } { JSONArray availableStreams(&obj, "availableStreams"); -#define ADD_STREAM_NAME(name, not_used) availableStreams.AddValue(#name); +#define ADD_STREAM_NAME(name, fuchsia_name) availableStreams.AddValue(#name); TIMELINE_STREAM_LIST(ADD_STREAM_NAME); #undef ADD_STREAM_NAME } { JSONArray recordedStreams(&obj, "recordedStreams"); -#define ADD_RECORDED_STREAM_NAME(name, not_used) \ +#define ADD_RECORDED_STREAM_NAME(name, fuchsia_name) \ if (stream_##name##_.enabled()) { \ recordedStreams.AddValue(#name); \ } @@ -377,8 +377,8 @@ void TimelineEventArguments::Free() { TimelineEventRecorder* Timeline::recorder_ = NULL; MallocGrowableArray* Timeline::enabled_streams_ = NULL; -#define TIMELINE_STREAM_DEFINE(name, enabled_by_default) \ - TimelineStream Timeline::stream_##name##_; +#define TIMELINE_STREAM_DEFINE(name, fuchsia_name) \ + TimelineStream Timeline::stream_##name##_(#name, fuchsia_name, false); TIMELINE_STREAM_LIST(TIMELINE_STREAM_DEFINE) #undef TIMELINE_STREAM_DEFINE @@ -389,7 +389,7 @@ TimelineEvent::TimelineEvent() thread_timestamp1_(-1), state_(0), label_(NULL), - category_(""), + stream_(NULL), thread_(OSThread::kInvalidThreadId), isolate_id_(ILLEGAL_PORT) {} @@ -404,7 +404,7 @@ void TimelineEvent::Reset() { state_ = 0; thread_ = OSThread::kInvalidThreadId; isolate_id_ = ILLEGAL_PORT; - category_ = ""; + stream_ = NULL; label_ = NULL; arguments_.Free(); set_event_type(kNone); @@ -546,14 +546,6 @@ void TimelineEvent::Complete() { } } -void TimelineEvent::StreamInit(TimelineStream* stream) { - if (stream != NULL) { - category_ = stream->name(); - } else { - category_ = ""; - } -} - void TimelineEvent::Init(EventType event_type, const char* label) { ASSERT(label != NULL); state_ = 0; @@ -607,7 +599,7 @@ void TimelineEvent::PrintJSON(JSONStream* stream) const { int64_t pid = OS::ProcessId(); int64_t tid = OSThread::ThreadIdToIntPtr(thread_); obj.AddProperty("name", label_); - obj.AddProperty("cat", category_); + obj.AddProperty("cat", stream_ != NULL ? stream_->name() : NULL); obj.AddProperty64("tid", tid); obj.AddProperty64("pid", pid); obj.AddPropertyTimeMicros("ts", TimeOrigin()); @@ -738,11 +730,16 @@ int64_t TimelineEvent::ThreadCPUTimeDuration() const { return thread_timestamp1_ - thread_timestamp0_; } -TimelineStream::TimelineStream() : name_(NULL), enabled_(false) {} - -void TimelineStream::Init(const char* name, bool enabled) { - name_ = name; - enabled_ = enabled; +TimelineStream::TimelineStream(const char* name, + const char* fuchsia_name, + bool enabled) + : name_(name), + fuchsia_name_(fuchsia_name), +#if defined(HOST_OS_FUCHSIA) + enabled_(true) { // For generated code. +#else + enabled_(enabled) { +#endif } TimelineEvent* TimelineStream::StartEvent() { @@ -1111,10 +1108,13 @@ void TimelineEventRecorder::WriteTo(const char* directory) { int64_t TimelineEventRecorder::GetNextAsyncId() { // TODO(johnmccutchan): Gracefully handle wrap around. - // TODO(rmacnak): Use TRACE_NONCE() on Fuchsia? +#if defined(HOST_OS_FUCHSIA) + return trace_generate_nonce(); +#else uint32_t next = static_cast(AtomicOperations::FetchAndIncrement(&async_id_)); return static_cast(next); +#endif } void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h index 0f50fbd77d6..bcfbe1e5d22 100644 --- a/runtime/vm/timeline.h +++ b/runtime/vm/timeline.h @@ -9,10 +9,16 @@ #include "vm/allocation.h" #include "vm/bitfield.h" +#include "vm/globals.h" #include "vm/growable_array.h" #include "vm/os.h" #include "vm/os_thread.h" +#if defined(HOST_OS_FUCHSIA) +#include +#include +#endif + namespace dart { class JSONArray; @@ -30,29 +36,34 @@ class TimelineStream; class VirtualMemory; class Zone; -// (name, enabled by default for isolate). +// (name, fuchsia_name). #define TIMELINE_STREAM_LIST(V) \ - V(API, false) \ - V(Compiler, false) \ - V(CompilerVerbose, false) \ - V(Dart, false) \ - V(Debugger, false) \ - V(Embedder, false) \ - V(GC, false) \ - V(Isolate, false) \ - V(VM, false) + V(API, "dart:api") \ + V(Compiler, "dart:compiler") \ + V(CompilerVerbose, "dart:compiler.verbose") \ + V(Dart, "dart:dart") \ + V(Debugger, "dart:debugger") \ + V(Embedder, "dart:embedder") \ + V(GC, "dart:gc") \ + V(Isolate, "dart:isolate") \ + V(VM, "dart:vm") // A stream of timeline events. A stream has a name and can be enabled or // disabled (globally and per isolate). class TimelineStream { public: - TimelineStream(); - - void Init(const char* name, bool enabled); + TimelineStream(const char* name, const char* fuchsia_name, bool enabled); const char* name() const { return name_; } + const char* fuchsia_name() const { return fuchsia_name_; } - bool enabled() const { return enabled_ != 0; } + bool enabled() { +#if defined(HOST_OS_FUCHSIA) + return trace_is_category_enabled(fuchsia_name_); +#else + return enabled_ != 0; +#endif + } void set_enabled(bool enabled) { enabled_ = enabled ? 1 : 0; } @@ -66,12 +77,21 @@ class TimelineStream { return OFFSET_OF(TimelineStream, enabled_); } +#if defined(HOST_OS_FUCHSIA) + trace_site_t* trace_site() { return &trace_site_; } +#endif + private: - const char* name_; + const char* const name_; + const char* const fuchsia_name_; // This field is accessed by generated code (intrinsic) and expects to see // 0 or 1. If this becomes a BitField, the generated code must be updated. uintptr_t enabled_; + +#if defined(HOST_OS_FUCHSIA) + trace_site_t trace_site_ = {}; +#endif }; class Timeline : public AllStatic { @@ -95,12 +115,12 @@ class Timeline : public AllStatic { static void PrintFlagsToJSON(JSONStream* json); #endif -#define TIMELINE_STREAM_ACCESSOR(name, not_used) \ +#define TIMELINE_STREAM_ACCESSOR(name, fuchsia_name) \ static TimelineStream* Get##name##Stream() { return &stream_##name##_; } TIMELINE_STREAM_LIST(TIMELINE_STREAM_ACCESSOR) #undef TIMELINE_STREAM_ACCESSOR -#define TIMELINE_STREAM_FLAGS(name, not_used) \ +#define TIMELINE_STREAM_FLAGS(name, fuchsia_name) \ static void SetStream##name##Enabled(bool enabled) { \ stream_##name##_.set_enabled(enabled); \ } @@ -111,8 +131,7 @@ class Timeline : public AllStatic { static TimelineEventRecorder* recorder_; static MallocGrowableArray* enabled_streams_; -#define TIMELINE_STREAM_DECLARE(name, not_used) \ - static bool stream_##name##_enabled_; \ +#define TIMELINE_STREAM_DECLARE(name, fuchsia_name) \ static TimelineStream stream_##name##_; TIMELINE_STREAM_LIST(TIMELINE_STREAM_DECLARE) #undef TIMELINE_STREAM_DECLARE @@ -358,7 +377,7 @@ class TimelineEvent { intptr_t arguments_length() const { return arguments_.length(); } private: - void StreamInit(TimelineStream* stream); + void StreamInit(TimelineStream* stream) { stream_ = stream; } void Init(EventType event_type, const char* label); void set_event_type(EventType event_type) { @@ -415,7 +434,7 @@ class TimelineEvent { TimelineEventArguments arguments_; uword state_; const char* label_; - const char* category_; + TimelineStream* stream_; ThreadId thread_; Dart_Port isolate_id_; diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc index 9c0dab495b7..0110166f507 100644 --- a/runtime/vm/timeline_fuchsia.cc +++ b/runtime/vm/timeline_fuchsia.cc @@ -19,9 +19,10 @@ 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("dart", &category); + trace_context_t* context = trace_acquire_context_for_category_cached( + stream->fuchsia_name(), stream->trace_site(), &category); if (context == NULL) { return; } diff --git a/runtime/vm/timeline_test.cc b/runtime/vm/timeline_test.cc index 6e59425b53f..eaf09f6a6b9 100644 --- a/runtime/vm/timeline_test.cc +++ b/runtime/vm/timeline_test.cc @@ -100,8 +100,7 @@ class TimelineTestHelper : public AllStatic { TEST_CASE(TimelineEventIsValid) { // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); TimelineEvent event; TimelineTestHelper::SetStream(&event, &stream); @@ -120,8 +119,7 @@ TEST_CASE(TimelineEventIsValid) { TEST_CASE(TimelineEventDuration) { // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); // Create a test event. TimelineEvent event; @@ -136,8 +134,7 @@ TEST_CASE(TimelineEventDuration) { TEST_CASE(TimelineEventDurationPrintJSON) { // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); // Create a test event. TimelineEvent event; @@ -167,8 +164,7 @@ TEST_CASE(TimelineEventPrintSystrace) { char buffer[kBufferLength]; // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); // Create a test event. TimelineEvent event; @@ -212,8 +208,7 @@ TEST_CASE(TimelineEventPrintSystrace) { TEST_CASE(TimelineEventArguments) { // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); // Create a test event. TimelineEvent event; @@ -233,8 +228,7 @@ TEST_CASE(TimelineEventArguments) { TEST_CASE(TimelineEventArgumentsPrintJSON) { // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); // Create a test event. TimelineEvent event; @@ -296,8 +290,7 @@ TEST_CASE(TimelineEventCallbackRecorderBasic) { } // Create a test stream. - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); TimelineEvent* event = NULL; @@ -468,8 +461,7 @@ TEST_CASE(TimelineAnalysis_ThreadBlockCount) { } TEST_CASE(TimelineRingRecorderJSONOrder) { - TimelineStream stream; - stream.Init("testStream", true); + TimelineStream stream("testStream", "testStream", true); TimelineEventRingRecorder* recorder = new TimelineEventRingRecorder(TimelineEventBlock::kBlockSize * 2);