Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1118)

Unified Diff: runtime/vm/timeline.cc

Issue 1377663002: Add Timeline to dart:developer (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/timeline.h ('k') | runtime/vm/timeline_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/timeline.cc
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index d55a8dcd9b6ff949ade135d668c4213168268963..1a8536a8c0d5c39832ed1da5c48e5078e336cf64 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -479,6 +479,36 @@ IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate)
}
+DartTimelineEvent::DartTimelineEvent()
+ : isolate_(NULL),
+ event_as_json_(NULL) {
+}
+
+
+DartTimelineEvent::~DartTimelineEvent() {
+ Clear();
+}
+
+
+void DartTimelineEvent::Clear() {
+ if (isolate_ != NULL) {
+ isolate_ = NULL;
+ }
+ if (event_as_json_ != NULL) {
+ free(event_as_json_);
+ event_as_json_ = NULL;
+ }
+}
+
+
+void DartTimelineEvent::Init(Isolate* isolate, const char* event) {
+ ASSERT(isolate_ == NULL);
+ ASSERT(event != NULL);
+ isolate_ = isolate;
+ event_as_json_ = strdup(event);
+}
+
+
TimelineEventRecorder::TimelineEventRecorder()
: global_block_(NULL),
async_id_(0) {
@@ -550,6 +580,21 @@ TimelineEvent* TimelineEventRecorder::GlobalBlockStartEvent() {
}
+// Trims the ']' character.
+static void TrimOutput(char* output,
+ intptr_t* output_length) {
+ ASSERT(output != NULL);
+ ASSERT(output_length != NULL);
+ ASSERT(*output_length >= 2);
+ // We expect the first character to be the opening of an array.
+ ASSERT(output[0] == '[');
+ // We expect the last character to be the closing of an array.
+ ASSERT(output[*output_length - 1] == ']');
+ // Skip the ].
+ *output_length -= 1;
+}
+
+
void TimelineEventRecorder::WriteTo(const char* directory) {
Dart_FileOpenCallback file_open = Isolate::file_open_callback();
Dart_FileWriteCallback file_write = Isolate::file_write_callback();
@@ -557,13 +602,11 @@ void TimelineEventRecorder::WriteTo(const char* directory) {
if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
return;
}
+ Thread* T = Thread::Current();
+ StackZone zone(T);
Timeline::ReclaimAllBlocks();
- JSONStream js;
- TimelineEventFilter filter;
- PrintJSON(&js, &filter);
-
intptr_t pid = OS::ProcessId();
char* filename = OS::SCreate(NULL,
"%s/dart-timeline-%" Pd ".json", directory, pid);
@@ -574,8 +617,43 @@ void TimelineEventRecorder::WriteTo(const char* directory) {
return;
}
free(filename);
- (*file_write)(js.buffer()->buf(), js.buffer()->length(), file);
+
+ JSONStream js;
+ TimelineEventFilter filter;
+ PrintTraceEvent(&js, &filter);
+ // Steal output from JSONStream.
+ char* output = NULL;
+ intptr_t output_length = 0;
+ js.Steal(const_cast<const char**>(&output), &output_length);
+ TrimOutput(output, &output_length);
+ ASSERT(output_length >= 1);
+ (*file_write)(output, output_length, file);
+ // Free the stolen output.
+ free(output);
+
+ const char* dart_events =
+ DartTimelineEventIterator::PrintTraceEvents(this,
+ zone.GetZone(),
+ NULL);
+
+ // If we wrote out vm events and have dart events, write out the comma.
+ if ((output_length > 1) && (dart_events != NULL)) {
+ // Write out the ',' character.
+ const char* comma = ",";
+ (*file_write)(comma, 1, file);
+ }
+
+ // Write out the Dart events.
+ if (dart_events != NULL) {
+ (*file_write)(dart_events, strlen(dart_events), file);
+ }
+
+ // Write out the ']' character.
+ const char* array_close = "]";
+ (*file_write)(array_close, 1, file);
(*file_close)(file);
+
+ return;
}
@@ -615,7 +693,10 @@ TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity)
: blocks_(NULL),
capacity_(capacity),
num_blocks_(0),
- block_cursor_(0) {
+ block_cursor_(0),
+ dart_events_(NULL),
+ dart_events_capacity_(capacity),
+ dart_events_cursor_(0) {
// Capacity must be a multiple of TimelineEventBlock::kBlockSize
ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0);
// Allocate blocks array.
@@ -631,6 +712,13 @@ TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity)
for (intptr_t i = 0; i < num_blocks_ - 1; i++) {
blocks_[i]->set_next(blocks_[i + 1]);
}
+ // Pre-allocate DartTimelineEvents.
+ dart_events_ =
+ reinterpret_cast<DartTimelineEvent**>(
+ calloc(dart_events_capacity_, sizeof(DartTimelineEvent*)));
+ for (intptr_t i = 0; i < dart_events_capacity_; i++) {
+ dart_events_[i] = new DartTimelineEvent();
+ }
}
@@ -641,6 +729,12 @@ TimelineEventRingRecorder::~TimelineEventRingRecorder() {
delete block;
}
free(blocks_);
+ // Delete all DartTimelineEvents.
+ for (intptr_t i = 0; i < dart_events_capacity_; i++) {
+ DartTimelineEvent* event = dart_events_[i];
+ delete event;
+ }
+ free(dart_events_);
}
@@ -681,6 +775,33 @@ void TimelineEventRingRecorder::PrintJSON(JSONStream* js,
}
+void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate,
+ const char* event) {
+ MutexLocker ml(&lock_);
+ // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
+ // the events.
+ if (dart_events_cursor_ == dart_events_capacity_) {
+ dart_events_cursor_ = 0;
+ }
+ ASSERT(dart_events_[dart_events_cursor_] != NULL);
+ dart_events_[dart_events_cursor_]->Clear();
+ dart_events_[dart_events_cursor_]->Init(isolate, event);
+ dart_events_cursor_++;
+}
+
+
+intptr_t TimelineEventRingRecorder::NumDartEventsLocked() {
+ return dart_events_capacity_;
+}
+
+
+DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) {
+ ASSERT(i >= 0);
+ ASSERT(i < dart_events_capacity_);
+ return dart_events_[i];
+}
+
+
void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js,
TimelineEventFilter* filter) {
JSONArray events(js);
@@ -761,6 +882,25 @@ void TimelineEventStreamingRecorder::PrintTraceEvent(
}
+void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate,
+ const char* event) {
+ if (event != NULL) {
+ StreamDartEvent(event);
+ }
+}
+
+
+intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() {
+ return 0;
+}
+
+
+DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked(
+ intptr_t i) {
+ return NULL;
+}
+
+
TimelineEvent* TimelineEventStreamingRecorder::StartEvent() {
TimelineEvent* event = new TimelineEvent();
return event;
@@ -775,7 +915,10 @@ void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) {
TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
: head_(NULL),
- block_index_(0) {
+ block_index_(0),
+ dart_events_(NULL),
+ dart_events_capacity_(0),
+ dart_events_cursor_(0) {
}
@@ -800,6 +943,31 @@ void TimelineEventEndlessRecorder::PrintTraceEvent(
}
+void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate,
+ const char* event) {
+ MutexLocker ml(&lock_);
+ // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store
+ // the events.
+ if (dart_events_cursor_ == dart_events_capacity_) {
+ // Grow.
+ intptr_t new_capacity =
+ (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2;
+ dart_events_ = reinterpret_cast<DartTimelineEvent**>(
+ realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*)));
+ for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) {
+ // Fill with NULLs.
+ dart_events_[i] = NULL;
+ }
+ dart_events_capacity_ = new_capacity;
+ }
+ ASSERT(dart_events_cursor_ < dart_events_capacity_);
+ DartTimelineEvent* dart_event = new DartTimelineEvent();
+ dart_event->Init(isolate, event);
+ ASSERT(dart_events_[dart_events_cursor_] == NULL);
+ dart_events_[dart_events_cursor_++] = dart_event;
+}
+
+
TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
return head_;
}
@@ -833,6 +1001,19 @@ TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked(
}
+intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() {
+ return dart_events_cursor_;
+}
+
+
+DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked(
+ intptr_t i) {
+ ASSERT(i >= 0);
+ ASSERT(i < dart_events_cursor_);
+ return dart_events_[i];
+}
+
+
void TimelineEventEndlessRecorder::PrintJSONEvents(
JSONArray* events,
TimelineEventFilter* filter) const {
@@ -1000,4 +1181,80 @@ TimelineEventBlock* TimelineEventBlockIterator::Next() {
return r;
}
+
+DartTimelineEventIterator::DartTimelineEventIterator(
+ TimelineEventRecorder* recorder)
+ : cursor_(0),
+ num_events_(0),
+ recorder_(NULL) {
+ Reset(recorder);
+}
+
+
+DartTimelineEventIterator::~DartTimelineEventIterator() {
+ Reset(NULL);
+}
+
+
+void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) {
+ // Clear state.
+ cursor_ = 0;
+ num_events_ = 0;
+ if (recorder_ != NULL) {
+ // Unlock old recorder.
+ recorder_->lock_.Unlock();
+ }
+ recorder_ = recorder;
+ if (recorder_ == NULL) {
+ return;
+ }
+ // Lock new recorder.
+ recorder_->lock_.Lock();
+ cursor_ = 0;
+ num_events_ = recorder_->NumDartEventsLocked();
+}
+
+
+bool DartTimelineEventIterator::HasNext() const {
+ return cursor_ < num_events_;
+}
+
+
+DartTimelineEvent* DartTimelineEventIterator::Next() {
+ ASSERT(cursor_ < num_events_);
+ DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_);
+ cursor_++;
+ return r;
+}
+
+const char* DartTimelineEventIterator::PrintTraceEvents(
+ TimelineEventRecorder* recorder,
+ Zone* zone,
+ Isolate* isolate) {
+ if (recorder == NULL) {
+ return NULL;
+ }
+
+ if (zone == NULL) {
+ return NULL;
+ }
+
+ char* result = NULL;
+ DartTimelineEventIterator iterator(recorder);
+ while (iterator.HasNext()) {
+ DartTimelineEvent* event = iterator.Next();
+ if (!event->IsValid()) {
+ // Skip invalid
+ continue;
+ }
+ if ((isolate != NULL) && (isolate != event->isolate())) {
+ // If an isolate was specified, skip events from other isolates.
+ continue;
+ }
+ ASSERT(event->event_as_json() != NULL);
+ result = zone->ConcatStrings(result, event->event_as_json());
+ }
+ return result;
+}
+
} // namespace dart
« no previous file with comments | « runtime/vm/timeline.h ('k') | runtime/vm/timeline_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698