Index: runtime/vm/timeline.cc |
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc |
index a603b037de1e8e1743e84b59464b73db09090337..3481b45d396a2bad2c5bf97c5537b914b3f32461 100644 |
--- a/runtime/vm/timeline.cc |
+++ b/runtime/vm/timeline.cc |
@@ -157,7 +157,8 @@ TimelineEvent::TimelineEvent() |
state_(0), |
label_(NULL), |
category_(""), |
- thread_(OSThread::kInvalidThreadId) { |
+ thread_(OSThread::kInvalidThreadId), |
+ isolate_id_(ILLEGAL_PORT) { |
} |
@@ -169,7 +170,7 @@ TimelineEvent::~TimelineEvent() { |
void TimelineEvent::Reset() { |
set_event_type(kNone); |
thread_ = OSThread::kInvalidThreadId; |
- isolate_ = NULL; |
+ isolate_id_ = ILLEGAL_PORT; |
category_ = ""; |
label_ = NULL; |
FreeArguments(); |
@@ -242,6 +243,13 @@ void TimelineEvent::End(const char* label, |
} |
+void TimelineEvent::SerializedJSON(const char* json) { |
+ Init(kSerializedJSON, "Dart"); |
+ SetNumArguments(1); |
+ CopyArgument(0, "Dart", json); |
+} |
+ |
+ |
void TimelineEvent::SetNumArguments(intptr_t length) { |
// Cannot call this twice. |
ASSERT(arguments_ == NULL); |
@@ -333,13 +341,32 @@ void TimelineEvent::Init(EventType event_type, |
timestamp0_ = 0; |
timestamp1_ = 0; |
thread_ = OSThread::GetCurrentThreadTraceId(); |
- isolate_ = Isolate::Current(); |
+ Isolate* isolate = Isolate::Current(); |
+ if (isolate != NULL) { |
+ isolate_id_ = isolate->main_port(); |
+ } else { |
+ isolate_id_ = ILLEGAL_PORT; |
+ } |
label_ = label; |
FreeArguments(); |
} |
+const char* TimelineEvent::GetSerializedJSON() const { |
+ ASSERT(event_type() == kSerializedJSON); |
+ ASSERT(arguments_length_ == 1); |
+ ASSERT(arguments_ != NULL); |
+ return arguments_[0].value; |
+} |
+ |
+ |
void TimelineEvent::PrintJSON(JSONStream* stream) const { |
+ if (event_type() == kSerializedJSON) { |
+ // Event has already been serialized into JSON- just append the |
+ // raw data. |
+ stream->AppendSerializedObject(GetSerializedJSON()); |
+ return; |
+ } |
JSONObject obj(stream); |
int64_t pid = OS::ProcessId(); |
int64_t tid = OSThread::ThreadIdToIntPtr(thread_); |
@@ -392,6 +419,10 @@ void TimelineEvent::PrintJSON(JSONStream* stream) const { |
const TimelineEventArgument& arg = arguments_[i]; |
args.AddProperty(arg.name, arg.value); |
} |
+ if (isolate_id_ != ILLEGAL_PORT) { |
+ // If we have one, append the isolate id. |
+ args.AddProperty("isolateNumber", isolate_id_); |
+ } |
} |
} |
@@ -588,38 +619,8 @@ TimelineEventFilter::~TimelineEventFilter() { |
} |
-IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate) |
- : 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); |
+IsolateTimelineEventFilter::IsolateTimelineEventFilter(Dart_Port isolate_id) |
+ : isolate_id_(isolate_id) { |
} |
@@ -636,7 +637,6 @@ TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
// Grab the current thread. |
Thread* thread = Thread::Current(); |
ASSERT(thread != NULL); |
- ASSERT(thread->isolate() != NULL); |
Mutex* thread_block_lock = thread->timeline_block_lock(); |
ASSERT(thread_block_lock != NULL); |
// We are accessing the thread's timeline block- so take the lock here. |
@@ -651,12 +651,12 @@ TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
// 1) Mark it as finished. |
thread_block->Finish(); |
// 2) Allocate a new block. |
- thread_block = GetNewBlockLocked(thread->isolate()); |
+ thread_block = GetNewBlockLocked(); |
thread->set_timeline_block(thread_block); |
} else if (thread_block == NULL) { |
MutexLocker ml(&lock_); |
// Thread has no block. Attempt to allocate one. |
- thread_block = GetNewBlockLocked(thread->isolate()); |
+ thread_block = GetNewBlockLocked(); |
thread->set_timeline_block(thread_block); |
} |
if (thread_block != NULL) { |
@@ -685,21 +685,6 @@ void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { |
} |
-// 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(); |
@@ -730,32 +715,9 @@ void TimelineEventRecorder::WriteTo(const char* directory) { |
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; |
@@ -781,7 +743,7 @@ void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |
TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
MutexLocker ml(&lock_); |
- return GetNewBlockLocked(Isolate::Current()); |
+ return GetNewBlockLocked(); |
} |
@@ -789,10 +751,7 @@ TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) |
: blocks_(NULL), |
capacity_(capacity), |
num_blocks_(0), |
- block_cursor_(0), |
- dart_events_(NULL), |
- dart_events_capacity_(capacity), |
- dart_events_cursor_(0) { |
+ block_cursor_(0) { |
// Capacity must be a multiple of TimelineEventBlock::kBlockSize |
ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
// Allocate blocks array. |
@@ -808,13 +767,6 @@ 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(); |
- } |
} |
@@ -825,12 +777,6 @@ 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_); |
} |
@@ -871,33 +817,6 @@ 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); |
@@ -910,8 +829,7 @@ TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { |
} |
-TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked( |
- Isolate* isolate) { |
+TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
// TODO(johnmccutchan): This function should only hand out blocks |
// which have been marked as finished. |
if (block_cursor_ == num_blocks_) { |
@@ -919,7 +837,7 @@ TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked( |
} |
TimelineEventBlock* block = blocks_[block_cursor_++]; |
block->Reset(); |
- block->Open(isolate); |
+ block->Open(); |
return block; |
} |
@@ -984,25 +902,6 @@ 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; |
@@ -1017,10 +916,7 @@ void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { |
TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
: head_(NULL), |
- block_index_(0), |
- dart_events_(NULL), |
- dart_events_capacity_(0), |
- dart_events_cursor_(0) { |
+ block_index_(0) { |
} |
@@ -1045,31 +941,6 @@ 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_; |
} |
@@ -1091,37 +962,18 @@ void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { |
} |
-TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked( |
- Isolate* isolate) { |
+TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { |
TimelineEventBlock* block = new TimelineEventBlock(block_index_++); |
block->set_next(head_); |
- block->Open(isolate); |
+ block->Open(); |
head_ = block; |
if (FLAG_trace_timeline) { |
- if (isolate != NULL) { |
- OS::Print("Created new isolate block %p for %s\n", |
- block, isolate->name()); |
- } else { |
- OS::Print("Created new global block %p\n", block); |
- } |
+ OS::Print("Created new block %p\n", block); |
} |
return head_; |
} |
-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 { |
@@ -1163,7 +1015,7 @@ TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
: next_(NULL), |
length_(0), |
block_index_(block_index), |
- isolate_(NULL), |
+ thread_id_(OSThread::kInvalidThreadId), |
in_use_(false) { |
} |
@@ -1183,13 +1035,10 @@ TimelineEvent* TimelineEventBlock::StartEvent() { |
} |
-ThreadId TimelineEventBlock::thread() const { |
- ASSERT(length_ > 0); |
- return events_[0].thread(); |
-} |
- |
- |
int64_t TimelineEventBlock::LowerTimeBound() const { |
+ if (length_ == 0) { |
+ return kMaxInt64; |
+ } |
ASSERT(length_ > 0); |
return events_[0].TimeOrigin(); |
} |
@@ -1200,10 +1049,8 @@ bool TimelineEventBlock::CheckBlock() { |
return true; |
} |
- // - events in the block come from one thread. |
- ThreadId tid = thread(); |
for (intptr_t i = 0; i < length(); i++) { |
- if (At(i)->thread() != tid) { |
+ if (At(i)->thread() != thread_id()) { |
return false; |
} |
} |
@@ -1227,13 +1074,13 @@ void TimelineEventBlock::Reset() { |
events_[i].Reset(); |
} |
length_ = 0; |
- isolate_ = NULL; |
+ thread_id_ = OSThread::kInvalidThreadId; |
in_use_ = false; |
} |
-void TimelineEventBlock::Open(Isolate* isolate) { |
- isolate_ = isolate; |
+void TimelineEventBlock::Open() { |
+ thread_id_ = OSThread::GetCurrentThreadTraceId(); |
in_use_ = true; |
} |
@@ -1289,80 +1136,4 @@ 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 |