| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <cstdlib> | 5 #include <cstdlib> |
| 6 | 6 |
| 7 #include "vm/atomic.h" | 7 #include "vm/atomic.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/json_stream.h" | 9 #include "vm/json_stream.h" |
| 10 #include "vm/lockers.h" | 10 #include "vm/lockers.h" |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG | 150 #undef ISOLATE_TIMELINE_STREAM_DEFINE_FLAG |
| 151 | 151 |
| 152 TimelineEvent::TimelineEvent() | 152 TimelineEvent::TimelineEvent() |
| 153 : timestamp0_(0), | 153 : timestamp0_(0), |
| 154 timestamp1_(0), | 154 timestamp1_(0), |
| 155 arguments_(NULL), | 155 arguments_(NULL), |
| 156 arguments_length_(0), | 156 arguments_length_(0), |
| 157 state_(0), | 157 state_(0), |
| 158 label_(NULL), | 158 label_(NULL), |
| 159 category_(""), | 159 category_(""), |
| 160 thread_(OSThread::kInvalidThreadId) { | 160 thread_(OSThread::kInvalidThreadId), |
| 161 isolate_id_(ILLEGAL_PORT) { |
| 161 } | 162 } |
| 162 | 163 |
| 163 | 164 |
| 164 TimelineEvent::~TimelineEvent() { | 165 TimelineEvent::~TimelineEvent() { |
| 165 Reset(); | 166 Reset(); |
| 166 } | 167 } |
| 167 | 168 |
| 168 | 169 |
| 169 void TimelineEvent::Reset() { | 170 void TimelineEvent::Reset() { |
| 170 set_event_type(kNone); | 171 set_event_type(kNone); |
| 171 thread_ = OSThread::kInvalidThreadId; | 172 thread_ = OSThread::kInvalidThreadId; |
| 172 isolate_ = NULL; | 173 isolate_id_ = ILLEGAL_PORT; |
| 173 category_ = ""; | 174 category_ = ""; |
| 174 label_ = NULL; | 175 label_ = NULL; |
| 175 FreeArguments(); | 176 FreeArguments(); |
| 176 } | 177 } |
| 177 | 178 |
| 178 | 179 |
| 179 void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) { | 180 void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) { |
| 180 Init(kAsyncBegin, label); | 181 Init(kAsyncBegin, label); |
| 181 timestamp0_ = OS::GetCurrentTraceMicros(); | 182 timestamp0_ = OS::GetCurrentTraceMicros(); |
| 182 // Overload timestamp1_ with the async_id. | 183 // Overload timestamp1_ with the async_id. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 } | 236 } |
| 236 | 237 |
| 237 | 238 |
| 238 void TimelineEvent::End(const char* label, | 239 void TimelineEvent::End(const char* label, |
| 239 int64_t micros) { | 240 int64_t micros) { |
| 240 Init(kEnd, label); | 241 Init(kEnd, label); |
| 241 timestamp0_ = micros; | 242 timestamp0_ = micros; |
| 242 } | 243 } |
| 243 | 244 |
| 244 | 245 |
| 246 void TimelineEvent::SerializedJSON(const char* json) { |
| 247 Init(kSerializedJSON, "Dart"); |
| 248 SetNumArguments(1); |
| 249 CopyArgument(0, "Dart", json); |
| 250 } |
| 251 |
| 252 |
| 245 void TimelineEvent::SetNumArguments(intptr_t length) { | 253 void TimelineEvent::SetNumArguments(intptr_t length) { |
| 246 // Cannot call this twice. | 254 // Cannot call this twice. |
| 247 ASSERT(arguments_ == NULL); | 255 ASSERT(arguments_ == NULL); |
| 248 ASSERT(arguments_length_ == 0); | 256 ASSERT(arguments_length_ == 0); |
| 249 if (length == 0) { | 257 if (length == 0) { |
| 250 return; | 258 return; |
| 251 } | 259 } |
| 252 arguments_length_ = length; | 260 arguments_length_ = length; |
| 253 arguments_ = reinterpret_cast<TimelineEventArgument*>( | 261 arguments_ = reinterpret_cast<TimelineEventArgument*>( |
| 254 calloc(sizeof(TimelineEventArgument), length)); | 262 calloc(sizeof(TimelineEventArgument), length)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 } | 334 } |
| 327 | 335 |
| 328 | 336 |
| 329 void TimelineEvent::Init(EventType event_type, | 337 void TimelineEvent::Init(EventType event_type, |
| 330 const char* label) { | 338 const char* label) { |
| 331 ASSERT(label != NULL); | 339 ASSERT(label != NULL); |
| 332 set_event_type(event_type); | 340 set_event_type(event_type); |
| 333 timestamp0_ = 0; | 341 timestamp0_ = 0; |
| 334 timestamp1_ = 0; | 342 timestamp1_ = 0; |
| 335 thread_ = OSThread::GetCurrentThreadTraceId(); | 343 thread_ = OSThread::GetCurrentThreadTraceId(); |
| 336 isolate_ = Isolate::Current(); | 344 Isolate* isolate = Isolate::Current(); |
| 345 if (isolate != NULL) { |
| 346 isolate_id_ = isolate->main_port(); |
| 347 } else { |
| 348 isolate_id_ = ILLEGAL_PORT; |
| 349 } |
| 337 label_ = label; | 350 label_ = label; |
| 338 FreeArguments(); | 351 FreeArguments(); |
| 339 } | 352 } |
| 340 | 353 |
| 341 | 354 |
| 355 const char* TimelineEvent::GetSerializedJSON() const { |
| 356 ASSERT(event_type() == kSerializedJSON); |
| 357 ASSERT(arguments_length_ == 1); |
| 358 ASSERT(arguments_ != NULL); |
| 359 return arguments_[0].value; |
| 360 } |
| 361 |
| 362 |
| 342 void TimelineEvent::PrintJSON(JSONStream* stream) const { | 363 void TimelineEvent::PrintJSON(JSONStream* stream) const { |
| 364 if (event_type() == kSerializedJSON) { |
| 365 // Event has already been serialized into JSON- just append the |
| 366 // raw data. |
| 367 stream->AppendSerializedObject(GetSerializedJSON()); |
| 368 return; |
| 369 } |
| 343 JSONObject obj(stream); | 370 JSONObject obj(stream); |
| 344 int64_t pid = OS::ProcessId(); | 371 int64_t pid = OS::ProcessId(); |
| 345 int64_t tid = OSThread::ThreadIdToIntPtr(thread_); | 372 int64_t tid = OSThread::ThreadIdToIntPtr(thread_); |
| 346 obj.AddProperty("name", label_); | 373 obj.AddProperty("name", label_); |
| 347 obj.AddProperty("cat", category_); | 374 obj.AddProperty("cat", category_); |
| 348 obj.AddProperty64("tid", tid); | 375 obj.AddProperty64("tid", tid); |
| 349 obj.AddProperty64("pid", pid); | 376 obj.AddProperty64("pid", pid); |
| 350 obj.AddPropertyTimeMicros("ts", TimeOrigin()); | 377 obj.AddPropertyTimeMicros("ts", TimeOrigin()); |
| 351 | 378 |
| 352 switch (event_type()) { | 379 switch (event_type()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 break; | 412 break; |
| 386 default: | 413 default: |
| 387 UNIMPLEMENTED(); | 414 UNIMPLEMENTED(); |
| 388 } | 415 } |
| 389 { | 416 { |
| 390 JSONObject args(&obj, "args"); | 417 JSONObject args(&obj, "args"); |
| 391 for (intptr_t i = 0; i < arguments_length_; i++) { | 418 for (intptr_t i = 0; i < arguments_length_; i++) { |
| 392 const TimelineEventArgument& arg = arguments_[i]; | 419 const TimelineEventArgument& arg = arguments_[i]; |
| 393 args.AddProperty(arg.name, arg.value); | 420 args.AddProperty(arg.name, arg.value); |
| 394 } | 421 } |
| 422 if (isolate_id_ != ILLEGAL_PORT) { |
| 423 // If we have one, append the isolate id. |
| 424 args.AddProperty("isolateNumber", isolate_id_); |
| 425 } |
| 395 } | 426 } |
| 396 } | 427 } |
| 397 | 428 |
| 398 | 429 |
| 399 int64_t TimelineEvent::TimeOrigin() const { | 430 int64_t TimelineEvent::TimeOrigin() const { |
| 400 return timestamp0_; | 431 return timestamp0_; |
| 401 } | 432 } |
| 402 | 433 |
| 403 | 434 |
| 404 int64_t TimelineEvent::AsyncId() const { | 435 int64_t TimelineEvent::AsyncId() const { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 | 612 |
| 582 | 613 |
| 583 TimelineEventFilter::TimelineEventFilter() { | 614 TimelineEventFilter::TimelineEventFilter() { |
| 584 } | 615 } |
| 585 | 616 |
| 586 | 617 |
| 587 TimelineEventFilter::~TimelineEventFilter() { | 618 TimelineEventFilter::~TimelineEventFilter() { |
| 588 } | 619 } |
| 589 | 620 |
| 590 | 621 |
| 591 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate) | 622 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Dart_Port isolate_id) |
| 592 : isolate_(isolate) { | 623 : isolate_id_(isolate_id) { |
| 593 } | 624 } |
| 594 | 625 |
| 595 | 626 |
| 596 DartTimelineEvent::DartTimelineEvent() | |
| 597 : isolate_(NULL), | |
| 598 event_as_json_(NULL) { | |
| 599 } | |
| 600 | |
| 601 | |
| 602 DartTimelineEvent::~DartTimelineEvent() { | |
| 603 Clear(); | |
| 604 } | |
| 605 | |
| 606 | |
| 607 void DartTimelineEvent::Clear() { | |
| 608 if (isolate_ != NULL) { | |
| 609 isolate_ = NULL; | |
| 610 } | |
| 611 if (event_as_json_ != NULL) { | |
| 612 free(event_as_json_); | |
| 613 event_as_json_ = NULL; | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 | |
| 618 void DartTimelineEvent::Init(Isolate* isolate, const char* event) { | |
| 619 ASSERT(isolate_ == NULL); | |
| 620 ASSERT(event != NULL); | |
| 621 isolate_ = isolate; | |
| 622 event_as_json_ = strdup(event); | |
| 623 } | |
| 624 | |
| 625 | |
| 626 TimelineEventRecorder::TimelineEventRecorder() | 627 TimelineEventRecorder::TimelineEventRecorder() |
| 627 : async_id_(0) { | 628 : async_id_(0) { |
| 628 } | 629 } |
| 629 | 630 |
| 630 | 631 |
| 631 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 632 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
| 632 } | 633 } |
| 633 | 634 |
| 634 | 635 |
| 635 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { | 636 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() { |
| 636 // Grab the current thread. | 637 // Grab the current thread. |
| 637 Thread* thread = Thread::Current(); | 638 Thread* thread = Thread::Current(); |
| 638 ASSERT(thread != NULL); | 639 ASSERT(thread != NULL); |
| 639 ASSERT(thread->isolate() != NULL); | |
| 640 Mutex* thread_block_lock = thread->timeline_block_lock(); | 640 Mutex* thread_block_lock = thread->timeline_block_lock(); |
| 641 ASSERT(thread_block_lock != NULL); | 641 ASSERT(thread_block_lock != NULL); |
| 642 // We are accessing the thread's timeline block- so take the lock here. | 642 // We are accessing the thread's timeline block- so take the lock here. |
| 643 // This lock will be held until the call to |CompleteEvent| is made. | 643 // This lock will be held until the call to |CompleteEvent| is made. |
| 644 thread_block_lock->Lock(); | 644 thread_block_lock->Lock(); |
| 645 | 645 |
| 646 TimelineEventBlock* thread_block = thread->timeline_block(); | 646 TimelineEventBlock* thread_block = thread->timeline_block(); |
| 647 | 647 |
| 648 if ((thread_block != NULL) && thread_block->IsFull()) { | 648 if ((thread_block != NULL) && thread_block->IsFull()) { |
| 649 MutexLocker ml(&lock_); | 649 MutexLocker ml(&lock_); |
| 650 // Thread has a block and it is full: | 650 // Thread has a block and it is full: |
| 651 // 1) Mark it as finished. | 651 // 1) Mark it as finished. |
| 652 thread_block->Finish(); | 652 thread_block->Finish(); |
| 653 // 2) Allocate a new block. | 653 // 2) Allocate a new block. |
| 654 thread_block = GetNewBlockLocked(thread->isolate()); | 654 thread_block = GetNewBlockLocked(); |
| 655 thread->set_timeline_block(thread_block); | 655 thread->set_timeline_block(thread_block); |
| 656 } else if (thread_block == NULL) { | 656 } else if (thread_block == NULL) { |
| 657 MutexLocker ml(&lock_); | 657 MutexLocker ml(&lock_); |
| 658 // Thread has no block. Attempt to allocate one. | 658 // Thread has no block. Attempt to allocate one. |
| 659 thread_block = GetNewBlockLocked(thread->isolate()); | 659 thread_block = GetNewBlockLocked(); |
| 660 thread->set_timeline_block(thread_block); | 660 thread->set_timeline_block(thread_block); |
| 661 } | 661 } |
| 662 if (thread_block != NULL) { | 662 if (thread_block != NULL) { |
| 663 // NOTE: We are exiting this function with the thread's block lock held. | 663 // NOTE: We are exiting this function with the thread's block lock held. |
| 664 ASSERT(!thread_block->IsFull()); | 664 ASSERT(!thread_block->IsFull()); |
| 665 TimelineEvent* event = thread_block->StartEvent(); | 665 TimelineEvent* event = thread_block->StartEvent(); |
| 666 return event; | 666 return event; |
| 667 } | 667 } |
| 668 // Drop lock here as no event is being handed out. | 668 // Drop lock here as no event is being handed out. |
| 669 thread_block_lock->Unlock(); | 669 thread_block_lock->Unlock(); |
| 670 return NULL; | 670 return NULL; |
| 671 } | 671 } |
| 672 | 672 |
| 673 | 673 |
| 674 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { | 674 void TimelineEventRecorder::ThreadBlockCompleteEvent(TimelineEvent* event) { |
| 675 if (event == NULL) { | 675 if (event == NULL) { |
| 676 return; | 676 return; |
| 677 } | 677 } |
| 678 // Grab the current thread. | 678 // Grab the current thread. |
| 679 Thread* thread = Thread::Current(); | 679 Thread* thread = Thread::Current(); |
| 680 ASSERT(thread != NULL); | 680 ASSERT(thread != NULL); |
| 681 // Unlock the thread's block lock. | 681 // Unlock the thread's block lock. |
| 682 Mutex* thread_block_lock = thread->timeline_block_lock(); | 682 Mutex* thread_block_lock = thread->timeline_block_lock(); |
| 683 ASSERT(thread_block_lock != NULL); | 683 ASSERT(thread_block_lock != NULL); |
| 684 thread_block_lock->Unlock(); | 684 thread_block_lock->Unlock(); |
| 685 } | 685 } |
| 686 | 686 |
| 687 | 687 |
| 688 // Trims the ']' character. | |
| 689 static void TrimOutput(char* output, | |
| 690 intptr_t* output_length) { | |
| 691 ASSERT(output != NULL); | |
| 692 ASSERT(output_length != NULL); | |
| 693 ASSERT(*output_length >= 2); | |
| 694 // We expect the first character to be the opening of an array. | |
| 695 ASSERT(output[0] == '['); | |
| 696 // We expect the last character to be the closing of an array. | |
| 697 ASSERT(output[*output_length - 1] == ']'); | |
| 698 // Skip the ]. | |
| 699 *output_length -= 1; | |
| 700 } | |
| 701 | |
| 702 | |
| 703 void TimelineEventRecorder::WriteTo(const char* directory) { | 688 void TimelineEventRecorder::WriteTo(const char* directory) { |
| 704 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | 689 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); |
| 705 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); | 690 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); |
| 706 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | 691 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); |
| 707 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 692 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
| 708 return; | 693 return; |
| 709 } | 694 } |
| 710 Thread* T = Thread::Current(); | 695 Thread* T = Thread::Current(); |
| 711 StackZone zone(T); | 696 StackZone zone(T); |
| 712 | 697 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 723 } | 708 } |
| 724 free(filename); | 709 free(filename); |
| 725 | 710 |
| 726 JSONStream js; | 711 JSONStream js; |
| 727 TimelineEventFilter filter; | 712 TimelineEventFilter filter; |
| 728 PrintTraceEvent(&js, &filter); | 713 PrintTraceEvent(&js, &filter); |
| 729 // Steal output from JSONStream. | 714 // Steal output from JSONStream. |
| 730 char* output = NULL; | 715 char* output = NULL; |
| 731 intptr_t output_length = 0; | 716 intptr_t output_length = 0; |
| 732 js.Steal(const_cast<const char**>(&output), &output_length); | 717 js.Steal(const_cast<const char**>(&output), &output_length); |
| 733 TrimOutput(output, &output_length); | |
| 734 ASSERT(output_length >= 1); | |
| 735 (*file_write)(output, output_length, file); | 718 (*file_write)(output, output_length, file); |
| 736 // Free the stolen output. | 719 // Free the stolen output. |
| 737 free(output); | 720 free(output); |
| 738 | |
| 739 const char* dart_events = | |
| 740 DartTimelineEventIterator::PrintTraceEvents(this, | |
| 741 zone.GetZone(), | |
| 742 NULL); | |
| 743 | |
| 744 // If we wrote out vm events and have dart events, write out the comma. | |
| 745 if ((output_length > 1) && (dart_events != NULL)) { | |
| 746 // Write out the ',' character. | |
| 747 const char* comma = ","; | |
| 748 (*file_write)(comma, 1, file); | |
| 749 } | |
| 750 | |
| 751 // Write out the Dart events. | |
| 752 if (dart_events != NULL) { | |
| 753 (*file_write)(dart_events, strlen(dart_events), file); | |
| 754 } | |
| 755 | |
| 756 // Write out the ']' character. | |
| 757 const char* array_close = "]"; | |
| 758 (*file_write)(array_close, 1, file); | |
| 759 (*file_close)(file); | 721 (*file_close)(file); |
| 760 | 722 |
| 761 return; | 723 return; |
| 762 } | 724 } |
| 763 | 725 |
| 764 | 726 |
| 765 int64_t TimelineEventRecorder::GetNextAsyncId() { | 727 int64_t TimelineEventRecorder::GetNextAsyncId() { |
| 766 // TODO(johnmccutchan): Gracefully handle wrap around. | 728 // TODO(johnmccutchan): Gracefully handle wrap around. |
| 767 uint32_t next = static_cast<uint32_t>( | 729 uint32_t next = static_cast<uint32_t>( |
| 768 AtomicOperations::FetchAndIncrement(&async_id_)); | 730 AtomicOperations::FetchAndIncrement(&async_id_)); |
| 769 return static_cast<int64_t>(next); | 731 return static_cast<int64_t>(next); |
| 770 } | 732 } |
| 771 | 733 |
| 772 | 734 |
| 773 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { | 735 void TimelineEventRecorder::FinishBlock(TimelineEventBlock* block) { |
| 774 if (block == NULL) { | 736 if (block == NULL) { |
| 775 return; | 737 return; |
| 776 } | 738 } |
| 777 MutexLocker ml(&lock_); | 739 MutexLocker ml(&lock_); |
| 778 block->Finish(); | 740 block->Finish(); |
| 779 } | 741 } |
| 780 | 742 |
| 781 | 743 |
| 782 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 744 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
| 783 MutexLocker ml(&lock_); | 745 MutexLocker ml(&lock_); |
| 784 return GetNewBlockLocked(Isolate::Current()); | 746 return GetNewBlockLocked(); |
| 785 } | 747 } |
| 786 | 748 |
| 787 | 749 |
| 788 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) | 750 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) |
| 789 : blocks_(NULL), | 751 : blocks_(NULL), |
| 790 capacity_(capacity), | 752 capacity_(capacity), |
| 791 num_blocks_(0), | 753 num_blocks_(0), |
| 792 block_cursor_(0), | 754 block_cursor_(0) { |
| 793 dart_events_(NULL), | |
| 794 dart_events_capacity_(capacity), | |
| 795 dart_events_cursor_(0) { | |
| 796 // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 755 // Capacity must be a multiple of TimelineEventBlock::kBlockSize |
| 797 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 756 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
| 798 // Allocate blocks array. | 757 // Allocate blocks array. |
| 799 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 758 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |
| 800 blocks_ = | 759 blocks_ = |
| 801 reinterpret_cast<TimelineEventBlock**>( | 760 reinterpret_cast<TimelineEventBlock**>( |
| 802 calloc(num_blocks_, sizeof(TimelineEventBlock*))); | 761 calloc(num_blocks_, sizeof(TimelineEventBlock*))); |
| 803 // Allocate each block. | 762 // Allocate each block. |
| 804 for (intptr_t i = 0; i < num_blocks_; i++) { | 763 for (intptr_t i = 0; i < num_blocks_; i++) { |
| 805 blocks_[i] = new TimelineEventBlock(i); | 764 blocks_[i] = new TimelineEventBlock(i); |
| 806 } | 765 } |
| 807 // Chain blocks together. | 766 // Chain blocks together. |
| 808 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 767 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |
| 809 blocks_[i]->set_next(blocks_[i + 1]); | 768 blocks_[i]->set_next(blocks_[i + 1]); |
| 810 } | 769 } |
| 811 // Pre-allocate DartTimelineEvents. | |
| 812 dart_events_ = | |
| 813 reinterpret_cast<DartTimelineEvent**>( | |
| 814 calloc(dart_events_capacity_, sizeof(DartTimelineEvent*))); | |
| 815 for (intptr_t i = 0; i < dart_events_capacity_; i++) { | |
| 816 dart_events_[i] = new DartTimelineEvent(); | |
| 817 } | |
| 818 } | 770 } |
| 819 | 771 |
| 820 | 772 |
| 821 TimelineEventRingRecorder::~TimelineEventRingRecorder() { | 773 TimelineEventRingRecorder::~TimelineEventRingRecorder() { |
| 822 // Delete all blocks. | 774 // Delete all blocks. |
| 823 for (intptr_t i = 0; i < num_blocks_; i++) { | 775 for (intptr_t i = 0; i < num_blocks_; i++) { |
| 824 TimelineEventBlock* block = blocks_[i]; | 776 TimelineEventBlock* block = blocks_[i]; |
| 825 delete block; | 777 delete block; |
| 826 } | 778 } |
| 827 free(blocks_); | 779 free(blocks_); |
| 828 // Delete all DartTimelineEvents. | |
| 829 for (intptr_t i = 0; i < dart_events_capacity_; i++) { | |
| 830 DartTimelineEvent* event = dart_events_[i]; | |
| 831 delete event; | |
| 832 } | |
| 833 free(dart_events_); | |
| 834 } | 780 } |
| 835 | 781 |
| 836 | 782 |
| 837 void TimelineEventRingRecorder::PrintJSONEvents( | 783 void TimelineEventRingRecorder::PrintJSONEvents( |
| 838 JSONArray* events, | 784 JSONArray* events, |
| 839 TimelineEventFilter* filter) const { | 785 TimelineEventFilter* filter) const { |
| 840 intptr_t block_offset = FindOldestBlockIndex(); | 786 intptr_t block_offset = FindOldestBlockIndex(); |
| 841 if (block_offset == -1) { | 787 if (block_offset == -1) { |
| 842 // All blocks are empty. | 788 // All blocks are empty. |
| 843 return; | 789 return; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 864 JSONObject topLevel(js); | 810 JSONObject topLevel(js); |
| 865 topLevel.AddProperty("type", "_Timeline"); | 811 topLevel.AddProperty("type", "_Timeline"); |
| 866 { | 812 { |
| 867 JSONArray events(&topLevel, "traceEvents"); | 813 JSONArray events(&topLevel, "traceEvents"); |
| 868 PrintJSONMeta(&events); | 814 PrintJSONMeta(&events); |
| 869 PrintJSONEvents(&events, filter); | 815 PrintJSONEvents(&events, filter); |
| 870 } | 816 } |
| 871 } | 817 } |
| 872 | 818 |
| 873 | 819 |
| 874 void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate, | |
| 875 const char* event) { | |
| 876 MutexLocker ml(&lock_); | |
| 877 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store | |
| 878 // the events. | |
| 879 if (dart_events_cursor_ == dart_events_capacity_) { | |
| 880 dart_events_cursor_ = 0; | |
| 881 } | |
| 882 ASSERT(dart_events_[dart_events_cursor_] != NULL); | |
| 883 dart_events_[dart_events_cursor_]->Clear(); | |
| 884 dart_events_[dart_events_cursor_]->Init(isolate, event); | |
| 885 dart_events_cursor_++; | |
| 886 } | |
| 887 | |
| 888 | |
| 889 intptr_t TimelineEventRingRecorder::NumDartEventsLocked() { | |
| 890 return dart_events_capacity_; | |
| 891 } | |
| 892 | |
| 893 | |
| 894 DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) { | |
| 895 ASSERT(i >= 0); | |
| 896 ASSERT(i < dart_events_capacity_); | |
| 897 return dart_events_[i]; | |
| 898 } | |
| 899 | |
| 900 | |
| 901 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, | 820 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, |
| 902 TimelineEventFilter* filter) { | 821 TimelineEventFilter* filter) { |
| 903 JSONArray events(js); | 822 JSONArray events(js); |
| 904 PrintJSONEvents(&events, filter); | 823 PrintJSONEvents(&events, filter); |
| 905 } | 824 } |
| 906 | 825 |
| 907 | 826 |
| 908 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { | 827 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { |
| 909 return blocks_[0]; | 828 return blocks_[0]; |
| 910 } | 829 } |
| 911 | 830 |
| 912 | 831 |
| 913 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked( | 832 TimelineEventBlock* TimelineEventRingRecorder::GetNewBlockLocked() { |
| 914 Isolate* isolate) { | |
| 915 // TODO(johnmccutchan): This function should only hand out blocks | 833 // TODO(johnmccutchan): This function should only hand out blocks |
| 916 // which have been marked as finished. | 834 // which have been marked as finished. |
| 917 if (block_cursor_ == num_blocks_) { | 835 if (block_cursor_ == num_blocks_) { |
| 918 block_cursor_ = 0; | 836 block_cursor_ = 0; |
| 919 } | 837 } |
| 920 TimelineEventBlock* block = blocks_[block_cursor_++]; | 838 TimelineEventBlock* block = blocks_[block_cursor_++]; |
| 921 block->Reset(); | 839 block->Reset(); |
| 922 block->Open(isolate); | 840 block->Open(); |
| 923 return block; | 841 return block; |
| 924 } | 842 } |
| 925 | 843 |
| 926 | 844 |
| 927 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const { | 845 intptr_t TimelineEventRingRecorder::FindOldestBlockIndex() const { |
| 928 int64_t earliest_time = kMaxInt64; | 846 int64_t earliest_time = kMaxInt64; |
| 929 intptr_t earliest_index = -1; | 847 intptr_t earliest_index = -1; |
| 930 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { | 848 for (intptr_t block_idx = 0; block_idx < num_blocks_; block_idx++) { |
| 931 TimelineEventBlock* block = blocks_[block_idx]; | 849 TimelineEventBlock* block = blocks_[block_idx]; |
| 932 if (block->IsEmpty()) { | 850 if (block->IsEmpty()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 } | 895 } |
| 978 | 896 |
| 979 | 897 |
| 980 void TimelineEventStreamingRecorder::PrintTraceEvent( | 898 void TimelineEventStreamingRecorder::PrintTraceEvent( |
| 981 JSONStream* js, | 899 JSONStream* js, |
| 982 TimelineEventFilter* filter) { | 900 TimelineEventFilter* filter) { |
| 983 JSONArray events(js); | 901 JSONArray events(js); |
| 984 } | 902 } |
| 985 | 903 |
| 986 | 904 |
| 987 void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate, | |
| 988 const char* event) { | |
| 989 if (event != NULL) { | |
| 990 StreamDartEvent(event); | |
| 991 } | |
| 992 } | |
| 993 | |
| 994 | |
| 995 intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() { | |
| 996 return 0; | |
| 997 } | |
| 998 | |
| 999 | |
| 1000 DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked( | |
| 1001 intptr_t i) { | |
| 1002 return NULL; | |
| 1003 } | |
| 1004 | |
| 1005 | |
| 1006 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { | 905 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { |
| 1007 TimelineEvent* event = new TimelineEvent(); | 906 TimelineEvent* event = new TimelineEvent(); |
| 1008 return event; | 907 return event; |
| 1009 } | 908 } |
| 1010 | 909 |
| 1011 | 910 |
| 1012 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { | 911 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { |
| 1013 StreamEvent(event); | 912 StreamEvent(event); |
| 1014 delete event; | 913 delete event; |
| 1015 } | 914 } |
| 1016 | 915 |
| 1017 | 916 |
| 1018 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 917 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
| 1019 : head_(NULL), | 918 : head_(NULL), |
| 1020 block_index_(0), | 919 block_index_(0) { |
| 1021 dart_events_(NULL), | |
| 1022 dart_events_capacity_(0), | |
| 1023 dart_events_cursor_(0) { | |
| 1024 } | 920 } |
| 1025 | 921 |
| 1026 | 922 |
| 1027 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, | 923 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, |
| 1028 TimelineEventFilter* filter) { | 924 TimelineEventFilter* filter) { |
| 1029 MutexLocker ml(&lock_); | 925 MutexLocker ml(&lock_); |
| 1030 JSONObject topLevel(js); | 926 JSONObject topLevel(js); |
| 1031 topLevel.AddProperty("type", "_Timeline"); | 927 topLevel.AddProperty("type", "_Timeline"); |
| 1032 { | 928 { |
| 1033 JSONArray events(&topLevel, "traceEvents"); | 929 JSONArray events(&topLevel, "traceEvents"); |
| 1034 PrintJSONMeta(&events); | 930 PrintJSONMeta(&events); |
| 1035 PrintJSONEvents(&events, filter); | 931 PrintJSONEvents(&events, filter); |
| 1036 } | 932 } |
| 1037 } | 933 } |
| 1038 | 934 |
| 1039 | 935 |
| 1040 void TimelineEventEndlessRecorder::PrintTraceEvent( | 936 void TimelineEventEndlessRecorder::PrintTraceEvent( |
| 1041 JSONStream* js, | 937 JSONStream* js, |
| 1042 TimelineEventFilter* filter) { | 938 TimelineEventFilter* filter) { |
| 1043 JSONArray events(js); | 939 JSONArray events(js); |
| 1044 PrintJSONEvents(&events, filter); | 940 PrintJSONEvents(&events, filter); |
| 1045 } | 941 } |
| 1046 | 942 |
| 1047 | 943 |
| 1048 void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate, | |
| 1049 const char* event) { | |
| 1050 MutexLocker ml(&lock_); | |
| 1051 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store | |
| 1052 // the events. | |
| 1053 if (dart_events_cursor_ == dart_events_capacity_) { | |
| 1054 // Grow. | |
| 1055 intptr_t new_capacity = | |
| 1056 (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2; | |
| 1057 dart_events_ = reinterpret_cast<DartTimelineEvent**>( | |
| 1058 realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*))); | |
| 1059 for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) { | |
| 1060 // Fill with NULLs. | |
| 1061 dart_events_[i] = NULL; | |
| 1062 } | |
| 1063 dart_events_capacity_ = new_capacity; | |
| 1064 } | |
| 1065 ASSERT(dart_events_cursor_ < dart_events_capacity_); | |
| 1066 DartTimelineEvent* dart_event = new DartTimelineEvent(); | |
| 1067 dart_event->Init(isolate, event); | |
| 1068 ASSERT(dart_events_[dart_events_cursor_] == NULL); | |
| 1069 dart_events_[dart_events_cursor_++] = dart_event; | |
| 1070 } | |
| 1071 | |
| 1072 | |
| 1073 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 944 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
| 1074 return head_; | 945 return head_; |
| 1075 } | 946 } |
| 1076 | 947 |
| 1077 | 948 |
| 1078 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 949 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
| 1079 // Grab the current thread. | 950 // Grab the current thread. |
| 1080 Thread* thread = Thread::Current(); | 951 Thread* thread = Thread::Current(); |
| 1081 ASSERT(thread != NULL); | 952 ASSERT(thread != NULL); |
| 1082 return ThreadBlockStartEvent(); | 953 return ThreadBlockStartEvent(); |
| 1083 } | 954 } |
| 1084 | 955 |
| 1085 | 956 |
| 1086 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { | 957 void TimelineEventEndlessRecorder::CompleteEvent(TimelineEvent* event) { |
| 1087 if (event == NULL) { | 958 if (event == NULL) { |
| 1088 return; | 959 return; |
| 1089 } | 960 } |
| 1090 ThreadBlockCompleteEvent(event); | 961 ThreadBlockCompleteEvent(event); |
| 1091 } | 962 } |
| 1092 | 963 |
| 1093 | 964 |
| 1094 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked( | 965 TimelineEventBlock* TimelineEventEndlessRecorder::GetNewBlockLocked() { |
| 1095 Isolate* isolate) { | |
| 1096 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); | 966 TimelineEventBlock* block = new TimelineEventBlock(block_index_++); |
| 1097 block->set_next(head_); | 967 block->set_next(head_); |
| 1098 block->Open(isolate); | 968 block->Open(); |
| 1099 head_ = block; | 969 head_ = block; |
| 1100 if (FLAG_trace_timeline) { | 970 if (FLAG_trace_timeline) { |
| 1101 if (isolate != NULL) { | 971 OS::Print("Created new block %p\n", block); |
| 1102 OS::Print("Created new isolate block %p for %s\n", | |
| 1103 block, isolate->name()); | |
| 1104 } else { | |
| 1105 OS::Print("Created new global block %p\n", block); | |
| 1106 } | |
| 1107 } | 972 } |
| 1108 return head_; | 973 return head_; |
| 1109 } | 974 } |
| 1110 | 975 |
| 1111 | 976 |
| 1112 intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() { | |
| 1113 return dart_events_cursor_; | |
| 1114 } | |
| 1115 | |
| 1116 | |
| 1117 DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked( | |
| 1118 intptr_t i) { | |
| 1119 ASSERT(i >= 0); | |
| 1120 ASSERT(i < dart_events_cursor_); | |
| 1121 return dart_events_[i]; | |
| 1122 } | |
| 1123 | |
| 1124 | |
| 1125 void TimelineEventEndlessRecorder::PrintJSONEvents( | 977 void TimelineEventEndlessRecorder::PrintJSONEvents( |
| 1126 JSONArray* events, | 978 JSONArray* events, |
| 1127 TimelineEventFilter* filter) const { | 979 TimelineEventFilter* filter) const { |
| 1128 TimelineEventBlock* current = head_; | 980 TimelineEventBlock* current = head_; |
| 1129 | 981 |
| 1130 while (current != NULL) { | 982 while (current != NULL) { |
| 1131 if (!filter->IncludeBlock(current)) { | 983 if (!filter->IncludeBlock(current)) { |
| 1132 current = current->next(); | 984 current = current->next(); |
| 1133 continue; | 985 continue; |
| 1134 } | 986 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1156 block_index_ = 0; | 1008 block_index_ = 0; |
| 1157 Thread* thread = Thread::Current(); | 1009 Thread* thread = Thread::Current(); |
| 1158 thread->set_timeline_block(NULL); | 1010 thread->set_timeline_block(NULL); |
| 1159 } | 1011 } |
| 1160 | 1012 |
| 1161 | 1013 |
| 1162 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) | 1014 TimelineEventBlock::TimelineEventBlock(intptr_t block_index) |
| 1163 : next_(NULL), | 1015 : next_(NULL), |
| 1164 length_(0), | 1016 length_(0), |
| 1165 block_index_(block_index), | 1017 block_index_(block_index), |
| 1166 isolate_(NULL), | 1018 thread_id_(OSThread::kInvalidThreadId), |
| 1167 in_use_(false) { | 1019 in_use_(false) { |
| 1168 } | 1020 } |
| 1169 | 1021 |
| 1170 | 1022 |
| 1171 TimelineEventBlock::~TimelineEventBlock() { | 1023 TimelineEventBlock::~TimelineEventBlock() { |
| 1172 Reset(); | 1024 Reset(); |
| 1173 } | 1025 } |
| 1174 | 1026 |
| 1175 | 1027 |
| 1176 TimelineEvent* TimelineEventBlock::StartEvent() { | 1028 TimelineEvent* TimelineEventBlock::StartEvent() { |
| 1177 ASSERT(!IsFull()); | 1029 ASSERT(!IsFull()); |
| 1178 if (FLAG_trace_timeline) { | 1030 if (FLAG_trace_timeline) { |
| 1179 OS::Print("StartEvent in block %p for thread %" Px "\n", | 1031 OS::Print("StartEvent in block %p for thread %" Px "\n", |
| 1180 this, OSThread::CurrentCurrentThreadIdAsIntPtr()); | 1032 this, OSThread::CurrentCurrentThreadIdAsIntPtr()); |
| 1181 } | 1033 } |
| 1182 return &events_[length_++]; | 1034 return &events_[length_++]; |
| 1183 } | 1035 } |
| 1184 | 1036 |
| 1185 | 1037 |
| 1186 ThreadId TimelineEventBlock::thread() const { | |
| 1187 ASSERT(length_ > 0); | |
| 1188 return events_[0].thread(); | |
| 1189 } | |
| 1190 | |
| 1191 | |
| 1192 int64_t TimelineEventBlock::LowerTimeBound() const { | 1038 int64_t TimelineEventBlock::LowerTimeBound() const { |
| 1039 if (length_ == 0) { |
| 1040 return kMaxInt64; |
| 1041 } |
| 1193 ASSERT(length_ > 0); | 1042 ASSERT(length_ > 0); |
| 1194 return events_[0].TimeOrigin(); | 1043 return events_[0].TimeOrigin(); |
| 1195 } | 1044 } |
| 1196 | 1045 |
| 1197 | 1046 |
| 1198 bool TimelineEventBlock::CheckBlock() { | 1047 bool TimelineEventBlock::CheckBlock() { |
| 1199 if (length() == 0) { | 1048 if (length() == 0) { |
| 1200 return true; | 1049 return true; |
| 1201 } | 1050 } |
| 1202 | 1051 |
| 1203 // - events in the block come from one thread. | |
| 1204 ThreadId tid = thread(); | |
| 1205 for (intptr_t i = 0; i < length(); i++) { | 1052 for (intptr_t i = 0; i < length(); i++) { |
| 1206 if (At(i)->thread() != tid) { | 1053 if (At(i)->thread() != thread_id()) { |
| 1207 return false; | 1054 return false; |
| 1208 } | 1055 } |
| 1209 } | 1056 } |
| 1210 | 1057 |
| 1211 // - events have monotonically increasing timestamps. | 1058 // - events have monotonically increasing timestamps. |
| 1212 int64_t last_time = LowerTimeBound(); | 1059 int64_t last_time = LowerTimeBound(); |
| 1213 for (intptr_t i = 0; i < length(); i++) { | 1060 for (intptr_t i = 0; i < length(); i++) { |
| 1214 if (last_time > At(i)->TimeOrigin()) { | 1061 if (last_time > At(i)->TimeOrigin()) { |
| 1215 return false; | 1062 return false; |
| 1216 } | 1063 } |
| 1217 last_time = At(i)->TimeOrigin(); | 1064 last_time = At(i)->TimeOrigin(); |
| 1218 } | 1065 } |
| 1219 | 1066 |
| 1220 return true; | 1067 return true; |
| 1221 } | 1068 } |
| 1222 | 1069 |
| 1223 | 1070 |
| 1224 void TimelineEventBlock::Reset() { | 1071 void TimelineEventBlock::Reset() { |
| 1225 for (intptr_t i = 0; i < kBlockSize; i++) { | 1072 for (intptr_t i = 0; i < kBlockSize; i++) { |
| 1226 // Clear any extra data. | 1073 // Clear any extra data. |
| 1227 events_[i].Reset(); | 1074 events_[i].Reset(); |
| 1228 } | 1075 } |
| 1229 length_ = 0; | 1076 length_ = 0; |
| 1230 isolate_ = NULL; | 1077 thread_id_ = OSThread::kInvalidThreadId; |
| 1231 in_use_ = false; | 1078 in_use_ = false; |
| 1232 } | 1079 } |
| 1233 | 1080 |
| 1234 | 1081 |
| 1235 void TimelineEventBlock::Open(Isolate* isolate) { | 1082 void TimelineEventBlock::Open() { |
| 1236 isolate_ = isolate; | 1083 thread_id_ = OSThread::GetCurrentThreadTraceId(); |
| 1237 in_use_ = true; | 1084 in_use_ = true; |
| 1238 } | 1085 } |
| 1239 | 1086 |
| 1240 | 1087 |
| 1241 void TimelineEventBlock::Finish() { | 1088 void TimelineEventBlock::Finish() { |
| 1242 if (FLAG_trace_timeline) { | 1089 if (FLAG_trace_timeline) { |
| 1243 OS::Print("Finish block %p\n", this); | 1090 OS::Print("Finish block %p\n", this); |
| 1244 } | 1091 } |
| 1245 in_use_ = false; | 1092 in_use_ = false; |
| 1246 } | 1093 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 } | 1129 } |
| 1283 | 1130 |
| 1284 | 1131 |
| 1285 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1132 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
| 1286 ASSERT(current_ != NULL); | 1133 ASSERT(current_ != NULL); |
| 1287 TimelineEventBlock* r = current_; | 1134 TimelineEventBlock* r = current_; |
| 1288 current_ = current_->next(); | 1135 current_ = current_->next(); |
| 1289 return r; | 1136 return r; |
| 1290 } | 1137 } |
| 1291 | 1138 |
| 1292 | |
| 1293 DartTimelineEventIterator::DartTimelineEventIterator( | |
| 1294 TimelineEventRecorder* recorder) | |
| 1295 : cursor_(0), | |
| 1296 num_events_(0), | |
| 1297 recorder_(NULL) { | |
| 1298 Reset(recorder); | |
| 1299 } | |
| 1300 | |
| 1301 | |
| 1302 DartTimelineEventIterator::~DartTimelineEventIterator() { | |
| 1303 Reset(NULL); | |
| 1304 } | |
| 1305 | |
| 1306 | |
| 1307 void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) { | |
| 1308 // Clear state. | |
| 1309 cursor_ = 0; | |
| 1310 num_events_ = 0; | |
| 1311 if (recorder_ != NULL) { | |
| 1312 // Unlock old recorder. | |
| 1313 recorder_->lock_.Unlock(); | |
| 1314 } | |
| 1315 recorder_ = recorder; | |
| 1316 if (recorder_ == NULL) { | |
| 1317 return; | |
| 1318 } | |
| 1319 // Lock new recorder. | |
| 1320 recorder_->lock_.Lock(); | |
| 1321 cursor_ = 0; | |
| 1322 num_events_ = recorder_->NumDartEventsLocked(); | |
| 1323 } | |
| 1324 | |
| 1325 | |
| 1326 bool DartTimelineEventIterator::HasNext() const { | |
| 1327 return cursor_ < num_events_; | |
| 1328 } | |
| 1329 | |
| 1330 | |
| 1331 DartTimelineEvent* DartTimelineEventIterator::Next() { | |
| 1332 ASSERT(cursor_ < num_events_); | |
| 1333 DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_); | |
| 1334 cursor_++; | |
| 1335 return r; | |
| 1336 } | |
| 1337 | |
| 1338 const char* DartTimelineEventIterator::PrintTraceEvents( | |
| 1339 TimelineEventRecorder* recorder, | |
| 1340 Zone* zone, | |
| 1341 Isolate* isolate) { | |
| 1342 if (recorder == NULL) { | |
| 1343 return NULL; | |
| 1344 } | |
| 1345 | |
| 1346 if (zone == NULL) { | |
| 1347 return NULL; | |
| 1348 } | |
| 1349 | |
| 1350 char* result = NULL; | |
| 1351 DartTimelineEventIterator iterator(recorder); | |
| 1352 while (iterator.HasNext()) { | |
| 1353 DartTimelineEvent* event = iterator.Next(); | |
| 1354 if (!event->IsValid()) { | |
| 1355 // Skip invalid | |
| 1356 continue; | |
| 1357 } | |
| 1358 if ((isolate != NULL) && (isolate != event->isolate())) { | |
| 1359 // If an isolate was specified, skip events from other isolates. | |
| 1360 continue; | |
| 1361 } | |
| 1362 ASSERT(event->event_as_json() != NULL); | |
| 1363 result = zone->ConcatStrings(result, event->event_as_json()); | |
| 1364 } | |
| 1365 return result; | |
| 1366 } | |
| 1367 | |
| 1368 } // namespace dart | 1139 } // namespace dart |
| OLD | NEW |