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 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 | 472 |
473 TimelineEventFilter::~TimelineEventFilter() { | 473 TimelineEventFilter::~TimelineEventFilter() { |
474 } | 474 } |
475 | 475 |
476 | 476 |
477 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate) | 477 IsolateTimelineEventFilter::IsolateTimelineEventFilter(Isolate* isolate) |
478 : isolate_(isolate) { | 478 : isolate_(isolate) { |
479 } | 479 } |
480 | 480 |
481 | 481 |
| 482 DartTimelineEvent::DartTimelineEvent() |
| 483 : isolate_(NULL), |
| 484 event_as_json_(NULL) { |
| 485 } |
| 486 |
| 487 |
| 488 DartTimelineEvent::~DartTimelineEvent() { |
| 489 Clear(); |
| 490 } |
| 491 |
| 492 |
| 493 void DartTimelineEvent::Clear() { |
| 494 if (isolate_ != NULL) { |
| 495 isolate_ = NULL; |
| 496 } |
| 497 if (event_as_json_ != NULL) { |
| 498 free(event_as_json_); |
| 499 event_as_json_ = NULL; |
| 500 } |
| 501 } |
| 502 |
| 503 |
| 504 void DartTimelineEvent::Init(Isolate* isolate, const char* event) { |
| 505 ASSERT(isolate_ == NULL); |
| 506 ASSERT(event != NULL); |
| 507 isolate_ = isolate; |
| 508 event_as_json_ = strdup(event); |
| 509 } |
| 510 |
| 511 |
482 TimelineEventRecorder::TimelineEventRecorder() | 512 TimelineEventRecorder::TimelineEventRecorder() |
483 : global_block_(NULL), | 513 : global_block_(NULL), |
484 async_id_(0) { | 514 async_id_(0) { |
485 } | 515 } |
486 | 516 |
487 | 517 |
488 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { | 518 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const { |
489 } | 519 } |
490 | 520 |
491 | 521 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 ASSERT(global_block_ != NULL); | 573 ASSERT(global_block_ != NULL); |
544 } | 574 } |
545 if (global_block_ != NULL) { | 575 if (global_block_ != NULL) { |
546 ASSERT(!global_block_->IsFull()); | 576 ASSERT(!global_block_->IsFull()); |
547 return global_block_->StartEvent(); | 577 return global_block_->StartEvent(); |
548 } | 578 } |
549 return NULL; | 579 return NULL; |
550 } | 580 } |
551 | 581 |
552 | 582 |
| 583 // Trims the ']' character. |
| 584 static void TrimOutput(char* output, |
| 585 intptr_t* output_length) { |
| 586 ASSERT(output != NULL); |
| 587 ASSERT(output_length != NULL); |
| 588 ASSERT(*output_length >= 2); |
| 589 // We expect the first character to be the opening of an array. |
| 590 ASSERT(output[0] == '['); |
| 591 // We expect the last character to be the closing of an array. |
| 592 ASSERT(output[*output_length - 1] == ']'); |
| 593 // Skip the ]. |
| 594 *output_length -= 1; |
| 595 } |
| 596 |
| 597 |
553 void TimelineEventRecorder::WriteTo(const char* directory) { | 598 void TimelineEventRecorder::WriteTo(const char* directory) { |
554 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | 599 Dart_FileOpenCallback file_open = Isolate::file_open_callback(); |
555 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); | 600 Dart_FileWriteCallback file_write = Isolate::file_write_callback(); |
556 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | 601 Dart_FileCloseCallback file_close = Isolate::file_close_callback(); |
557 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 602 if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { |
558 return; | 603 return; |
559 } | 604 } |
| 605 Thread* T = Thread::Current(); |
| 606 StackZone zone(T); |
560 | 607 |
561 Timeline::ReclaimAllBlocks(); | 608 Timeline::ReclaimAllBlocks(); |
562 | 609 |
563 JSONStream js; | |
564 TimelineEventFilter filter; | |
565 PrintJSON(&js, &filter); | |
566 | |
567 intptr_t pid = OS::ProcessId(); | 610 intptr_t pid = OS::ProcessId(); |
568 char* filename = OS::SCreate(NULL, | 611 char* filename = OS::SCreate(NULL, |
569 "%s/dart-timeline-%" Pd ".json", directory, pid); | 612 "%s/dart-timeline-%" Pd ".json", directory, pid); |
570 void* file = (*file_open)(filename, true); | 613 void* file = (*file_open)(filename, true); |
571 if (file == NULL) { | 614 if (file == NULL) { |
572 OS::Print("Failed to write timeline file: %s\n", filename); | 615 OS::Print("Failed to write timeline file: %s\n", filename); |
573 free(filename); | 616 free(filename); |
574 return; | 617 return; |
575 } | 618 } |
576 free(filename); | 619 free(filename); |
577 (*file_write)(js.buffer()->buf(), js.buffer()->length(), file); | 620 |
| 621 JSONStream js; |
| 622 TimelineEventFilter filter; |
| 623 PrintTraceEvent(&js, &filter); |
| 624 // Steal output from JSONStream. |
| 625 char* output = NULL; |
| 626 intptr_t output_length = 0; |
| 627 js.Steal(const_cast<const char**>(&output), &output_length); |
| 628 TrimOutput(output, &output_length); |
| 629 ASSERT(output_length >= 1); |
| 630 (*file_write)(output, output_length, file); |
| 631 // Free the stolen output. |
| 632 free(output); |
| 633 |
| 634 const char* dart_events = |
| 635 DartTimelineEventIterator::PrintTraceEvents(this, |
| 636 zone.GetZone(), |
| 637 NULL); |
| 638 |
| 639 // If we wrote out vm events and have dart events, write out the comma. |
| 640 if ((output_length > 1) && (dart_events != NULL)) { |
| 641 // Write out the ']' character. |
| 642 const char* comma = ","; |
| 643 (*file_write)(comma, 1, file); |
| 644 } |
| 645 |
| 646 // Write out the Dart events. |
| 647 if (dart_events != NULL) { |
| 648 (*file_write)(dart_events, strlen(dart_events), file); |
| 649 } |
| 650 |
| 651 // Write out the ']' character. |
| 652 const char* array_close = "]"; |
| 653 (*file_write)(array_close, 1, file); |
578 (*file_close)(file); | 654 (*file_close)(file); |
| 655 |
| 656 return; |
579 } | 657 } |
580 | 658 |
581 | 659 |
582 void TimelineEventRecorder::ReclaimGlobalBlock() { | 660 void TimelineEventRecorder::ReclaimGlobalBlock() { |
583 MutexLocker ml(&lock_); | 661 MutexLocker ml(&lock_); |
584 if (global_block_ != NULL) { | 662 if (global_block_ != NULL) { |
585 global_block_->Finish(); | 663 global_block_->Finish(); |
586 global_block_ = NULL; | 664 global_block_ = NULL; |
587 } | 665 } |
588 } | 666 } |
(...skipping 19 matching lines...) Expand all Loading... |
608 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { | 686 TimelineEventBlock* TimelineEventRecorder::GetNewBlock() { |
609 MutexLocker ml(&lock_); | 687 MutexLocker ml(&lock_); |
610 return GetNewBlockLocked(Isolate::Current()); | 688 return GetNewBlockLocked(Isolate::Current()); |
611 } | 689 } |
612 | 690 |
613 | 691 |
614 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) | 692 TimelineEventRingRecorder::TimelineEventRingRecorder(intptr_t capacity) |
615 : blocks_(NULL), | 693 : blocks_(NULL), |
616 capacity_(capacity), | 694 capacity_(capacity), |
617 num_blocks_(0), | 695 num_blocks_(0), |
618 block_cursor_(0) { | 696 block_cursor_(0), |
| 697 dart_events_(NULL), |
| 698 dart_events_capacity_(capacity), |
| 699 dart_events_cursor_(0) { |
619 // Capacity must be a multiple of TimelineEventBlock::kBlockSize | 700 // Capacity must be a multiple of TimelineEventBlock::kBlockSize |
620 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); | 701 ASSERT((capacity % TimelineEventBlock::kBlockSize) == 0); |
621 // Allocate blocks array. | 702 // Allocate blocks array. |
622 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; | 703 num_blocks_ = capacity / TimelineEventBlock::kBlockSize; |
623 blocks_ = | 704 blocks_ = |
624 reinterpret_cast<TimelineEventBlock**>( | 705 reinterpret_cast<TimelineEventBlock**>( |
625 calloc(num_blocks_, sizeof(TimelineEventBlock*))); | 706 calloc(num_blocks_, sizeof(TimelineEventBlock*))); |
626 // Allocate each block. | 707 // Allocate each block. |
627 for (intptr_t i = 0; i < num_blocks_; i++) { | 708 for (intptr_t i = 0; i < num_blocks_; i++) { |
628 blocks_[i] = new TimelineEventBlock(i); | 709 blocks_[i] = new TimelineEventBlock(i); |
629 } | 710 } |
630 // Chain blocks together. | 711 // Chain blocks together. |
631 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { | 712 for (intptr_t i = 0; i < num_blocks_ - 1; i++) { |
632 blocks_[i]->set_next(blocks_[i + 1]); | 713 blocks_[i]->set_next(blocks_[i + 1]); |
633 } | 714 } |
| 715 // Pre-allocate DartTimelineEvents. |
| 716 dart_events_ = |
| 717 reinterpret_cast<DartTimelineEvent**>( |
| 718 calloc(dart_events_capacity_, sizeof(DartTimelineEvent*))); |
| 719 for (intptr_t i = 0; i < dart_events_capacity_; i++) { |
| 720 dart_events_[i] = new DartTimelineEvent(); |
| 721 } |
634 } | 722 } |
635 | 723 |
636 | 724 |
637 TimelineEventRingRecorder::~TimelineEventRingRecorder() { | 725 TimelineEventRingRecorder::~TimelineEventRingRecorder() { |
638 // Delete all blocks. | 726 // Delete all blocks. |
639 for (intptr_t i = 0; i < num_blocks_; i++) { | 727 for (intptr_t i = 0; i < num_blocks_; i++) { |
640 TimelineEventBlock* block = blocks_[i]; | 728 TimelineEventBlock* block = blocks_[i]; |
641 delete block; | 729 delete block; |
642 } | 730 } |
643 free(blocks_); | 731 free(blocks_); |
| 732 // Delete all DartTimelineEvents. |
| 733 for (intptr_t i = 0; i < dart_events_capacity_; i++) { |
| 734 DartTimelineEvent* event = dart_events_[i]; |
| 735 delete event; |
| 736 } |
| 737 free(dart_events_); |
644 } | 738 } |
645 | 739 |
646 | 740 |
647 void TimelineEventRingRecorder::PrintJSONEvents( | 741 void TimelineEventRingRecorder::PrintJSONEvents( |
648 JSONArray* events, | 742 JSONArray* events, |
649 TimelineEventFilter* filter) const { | 743 TimelineEventFilter* filter) const { |
650 intptr_t block_offset = FindOldestBlockIndex(); | 744 intptr_t block_offset = FindOldestBlockIndex(); |
651 if (block_offset == -1) { | 745 if (block_offset == -1) { |
652 // All blocks are empty. | 746 // All blocks are empty. |
653 return; | 747 return; |
(...skipping 20 matching lines...) Expand all Loading... |
674 JSONObject topLevel(js); | 768 JSONObject topLevel(js); |
675 topLevel.AddProperty("type", "_Timeline"); | 769 topLevel.AddProperty("type", "_Timeline"); |
676 { | 770 { |
677 JSONArray events(&topLevel, "traceEvents"); | 771 JSONArray events(&topLevel, "traceEvents"); |
678 PrintJSONMeta(&events); | 772 PrintJSONMeta(&events); |
679 PrintJSONEvents(&events, filter); | 773 PrintJSONEvents(&events, filter); |
680 } | 774 } |
681 } | 775 } |
682 | 776 |
683 | 777 |
| 778 void TimelineEventRingRecorder::AppendDartEvent(Isolate* isolate, |
| 779 const char* event) { |
| 780 MutexLocker ml(&lock_); |
| 781 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store |
| 782 // the events. |
| 783 if (dart_events_cursor_ == dart_events_capacity_) { |
| 784 dart_events_cursor_ = 0; |
| 785 } |
| 786 ASSERT(dart_events_[dart_events_cursor_] != NULL); |
| 787 dart_events_[dart_events_cursor_]->Clear(); |
| 788 dart_events_[dart_events_cursor_]->Init(isolate, event); |
| 789 dart_events_cursor_++; |
| 790 } |
| 791 |
| 792 |
| 793 intptr_t TimelineEventRingRecorder::NumDartEventsLocked() { |
| 794 return dart_events_capacity_; |
| 795 } |
| 796 |
| 797 |
| 798 DartTimelineEvent* TimelineEventRingRecorder::DartEventAtLocked(intptr_t i) { |
| 799 ASSERT(i >= 0); |
| 800 ASSERT(i < dart_events_capacity_); |
| 801 return dart_events_[i]; |
| 802 } |
| 803 |
| 804 |
684 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, | 805 void TimelineEventRingRecorder::PrintTraceEvent(JSONStream* js, |
685 TimelineEventFilter* filter) { | 806 TimelineEventFilter* filter) { |
686 JSONArray events(js); | 807 JSONArray events(js); |
687 PrintJSONEvents(&events, filter); | 808 PrintJSONEvents(&events, filter); |
688 } | 809 } |
689 | 810 |
690 | 811 |
691 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { | 812 TimelineEventBlock* TimelineEventRingRecorder::GetHeadBlockLocked() { |
692 return blocks_[0]; | 813 return blocks_[0]; |
693 } | 814 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 } | 875 } |
755 | 876 |
756 | 877 |
757 void TimelineEventStreamingRecorder::PrintTraceEvent( | 878 void TimelineEventStreamingRecorder::PrintTraceEvent( |
758 JSONStream* js, | 879 JSONStream* js, |
759 TimelineEventFilter* filter) { | 880 TimelineEventFilter* filter) { |
760 JSONArray events(js); | 881 JSONArray events(js); |
761 } | 882 } |
762 | 883 |
763 | 884 |
| 885 void TimelineEventStreamingRecorder::AppendDartEvent(Isolate* isolate, |
| 886 const char* event) { |
| 887 if (event != NULL) { |
| 888 StreamDartEvent(event); |
| 889 } |
| 890 } |
| 891 |
| 892 |
| 893 intptr_t TimelineEventStreamingRecorder::NumDartEventsLocked() { |
| 894 return 0; |
| 895 } |
| 896 |
| 897 |
| 898 DartTimelineEvent* TimelineEventStreamingRecorder::DartEventAtLocked( |
| 899 intptr_t i) { |
| 900 return NULL; |
| 901 } |
| 902 |
| 903 |
764 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { | 904 TimelineEvent* TimelineEventStreamingRecorder::StartEvent() { |
765 TimelineEvent* event = new TimelineEvent(); | 905 TimelineEvent* event = new TimelineEvent(); |
766 return event; | 906 return event; |
767 } | 907 } |
768 | 908 |
769 | 909 |
770 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { | 910 void TimelineEventStreamingRecorder::CompleteEvent(TimelineEvent* event) { |
771 StreamEvent(event); | 911 StreamEvent(event); |
772 delete event; | 912 delete event; |
773 } | 913 } |
774 | 914 |
775 | 915 |
776 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() | 916 TimelineEventEndlessRecorder::TimelineEventEndlessRecorder() |
777 : head_(NULL), | 917 : head_(NULL), |
778 block_index_(0) { | 918 block_index_(0), |
| 919 dart_events_(NULL), |
| 920 dart_events_capacity_(0), |
| 921 dart_events_cursor_(0) { |
779 } | 922 } |
780 | 923 |
781 | 924 |
782 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, | 925 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js, |
783 TimelineEventFilter* filter) { | 926 TimelineEventFilter* filter) { |
784 MutexLocker ml(&lock_); | 927 MutexLocker ml(&lock_); |
785 JSONObject topLevel(js); | 928 JSONObject topLevel(js); |
786 topLevel.AddProperty("type", "_Timeline"); | 929 topLevel.AddProperty("type", "_Timeline"); |
787 { | 930 { |
788 JSONArray events(&topLevel, "traceEvents"); | 931 JSONArray events(&topLevel, "traceEvents"); |
789 PrintJSONMeta(&events); | 932 PrintJSONMeta(&events); |
790 PrintJSONEvents(&events, filter); | 933 PrintJSONEvents(&events, filter); |
791 } | 934 } |
792 } | 935 } |
793 | 936 |
794 | 937 |
795 void TimelineEventEndlessRecorder::PrintTraceEvent( | 938 void TimelineEventEndlessRecorder::PrintTraceEvent( |
796 JSONStream* js, | 939 JSONStream* js, |
797 TimelineEventFilter* filter) { | 940 TimelineEventFilter* filter) { |
798 JSONArray events(js); | 941 JSONArray events(js); |
799 PrintJSONEvents(&events, filter); | 942 PrintJSONEvents(&events, filter); |
800 } | 943 } |
801 | 944 |
802 | 945 |
| 946 void TimelineEventEndlessRecorder::AppendDartEvent(Isolate* isolate, |
| 947 const char* event) { |
| 948 MutexLocker ml(&lock_); |
| 949 // TODO(johnmccutchan): If locking becomes an issue, use the Isolate to store |
| 950 // the events. |
| 951 if (dart_events_cursor_ == dart_events_capacity_) { |
| 952 // Grow. |
| 953 intptr_t new_capacity = |
| 954 (dart_events_capacity_ == 0) ? 16 : dart_events_capacity_ * 2; |
| 955 dart_events_ = reinterpret_cast<DartTimelineEvent**>( |
| 956 realloc(dart_events_, new_capacity * sizeof(DartTimelineEvent*))); |
| 957 for (intptr_t i = dart_events_capacity_; i < new_capacity; i++) { |
| 958 // Fill with NULLs. |
| 959 dart_events_[i] = NULL; |
| 960 } |
| 961 dart_events_capacity_ = new_capacity; |
| 962 } |
| 963 ASSERT(dart_events_cursor_ < dart_events_capacity_); |
| 964 DartTimelineEvent* dart_event = new DartTimelineEvent(); |
| 965 dart_event->Init(isolate, event); |
| 966 ASSERT(dart_events_[dart_events_cursor_] == NULL); |
| 967 dart_events_[dart_events_cursor_++] = dart_event; |
| 968 } |
| 969 |
| 970 |
803 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { | 971 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() { |
804 return head_; | 972 return head_; |
805 } | 973 } |
806 | 974 |
807 | 975 |
808 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { | 976 TimelineEvent* TimelineEventEndlessRecorder::StartEvent() { |
809 return ThreadBlockStartEvent(); | 977 return ThreadBlockStartEvent(); |
810 } | 978 } |
811 | 979 |
812 | 980 |
(...skipping 13 matching lines...) Expand all Loading... |
826 OS::Print("Created new isolate block %p for %s\n", | 994 OS::Print("Created new isolate block %p for %s\n", |
827 block, isolate->name()); | 995 block, isolate->name()); |
828 } else { | 996 } else { |
829 OS::Print("Created new global block %p\n", block); | 997 OS::Print("Created new global block %p\n", block); |
830 } | 998 } |
831 } | 999 } |
832 return head_; | 1000 return head_; |
833 } | 1001 } |
834 | 1002 |
835 | 1003 |
| 1004 intptr_t TimelineEventEndlessRecorder::NumDartEventsLocked() { |
| 1005 return dart_events_cursor_; |
| 1006 } |
| 1007 |
| 1008 |
| 1009 DartTimelineEvent* TimelineEventEndlessRecorder::DartEventAtLocked( |
| 1010 intptr_t i) { |
| 1011 ASSERT(i >= 0); |
| 1012 ASSERT(i < dart_events_cursor_); |
| 1013 return dart_events_[i]; |
| 1014 } |
| 1015 |
| 1016 |
836 void TimelineEventEndlessRecorder::PrintJSONEvents( | 1017 void TimelineEventEndlessRecorder::PrintJSONEvents( |
837 JSONArray* events, | 1018 JSONArray* events, |
838 TimelineEventFilter* filter) const { | 1019 TimelineEventFilter* filter) const { |
839 TimelineEventBlock* current = head_; | 1020 TimelineEventBlock* current = head_; |
840 | 1021 |
841 while (current != NULL) { | 1022 while (current != NULL) { |
842 if (!filter->IncludeBlock(current)) { | 1023 if (!filter->IncludeBlock(current)) { |
843 current = current->next(); | 1024 current = current->next(); |
844 continue; | 1025 continue; |
845 } | 1026 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 } | 1174 } |
994 | 1175 |
995 | 1176 |
996 TimelineEventBlock* TimelineEventBlockIterator::Next() { | 1177 TimelineEventBlock* TimelineEventBlockIterator::Next() { |
997 ASSERT(current_ != NULL); | 1178 ASSERT(current_ != NULL); |
998 TimelineEventBlock* r = current_; | 1179 TimelineEventBlock* r = current_; |
999 current_ = current_->next(); | 1180 current_ = current_->next(); |
1000 return r; | 1181 return r; |
1001 } | 1182 } |
1002 | 1183 |
| 1184 |
| 1185 DartTimelineEventIterator::DartTimelineEventIterator( |
| 1186 TimelineEventRecorder* recorder) |
| 1187 : cursor_(0), |
| 1188 num_events_(0), |
| 1189 recorder_(NULL) { |
| 1190 Reset(recorder); |
| 1191 } |
| 1192 |
| 1193 |
| 1194 DartTimelineEventIterator::~DartTimelineEventIterator() { |
| 1195 Reset(NULL); |
| 1196 } |
| 1197 |
| 1198 |
| 1199 void DartTimelineEventIterator::Reset(TimelineEventRecorder* recorder) { |
| 1200 // Clear state. |
| 1201 cursor_ = 0; |
| 1202 num_events_ = 0; |
| 1203 if (recorder_ != NULL) { |
| 1204 // Unlock old recorder. |
| 1205 recorder_->lock_.Unlock(); |
| 1206 } |
| 1207 recorder_ = recorder; |
| 1208 if (recorder_ == NULL) { |
| 1209 return; |
| 1210 } |
| 1211 // Lock new recorder. |
| 1212 recorder_->lock_.Lock(); |
| 1213 cursor_ = 0; |
| 1214 num_events_ = recorder_->NumDartEventsLocked(); |
| 1215 } |
| 1216 |
| 1217 |
| 1218 bool DartTimelineEventIterator::HasNext() const { |
| 1219 return cursor_ < num_events_; |
| 1220 } |
| 1221 |
| 1222 |
| 1223 DartTimelineEvent* DartTimelineEventIterator::Next() { |
| 1224 ASSERT(cursor_ < num_events_); |
| 1225 DartTimelineEvent* r = recorder_->DartEventAtLocked(cursor_); |
| 1226 cursor_++; |
| 1227 return r; |
| 1228 } |
| 1229 |
| 1230 const char* DartTimelineEventIterator::PrintTraceEvents( |
| 1231 TimelineEventRecorder* recorder, |
| 1232 Zone* zone, |
| 1233 Isolate* isolate) { |
| 1234 if (recorder == NULL) { |
| 1235 return NULL; |
| 1236 } |
| 1237 |
| 1238 if (zone == NULL) { |
| 1239 return NULL; |
| 1240 } |
| 1241 |
| 1242 char* result = NULL; |
| 1243 DartTimelineEventIterator iterator(recorder); |
| 1244 while (iterator.HasNext()) { |
| 1245 DartTimelineEvent* event = iterator.Next(); |
| 1246 if (!event->IsValid()) { |
| 1247 // Skip invalid |
| 1248 continue; |
| 1249 } |
| 1250 if ((isolate != NULL) && (isolate != event->isolate())) { |
| 1251 // If an isolate was specified, skip events from other isolates. |
| 1252 continue; |
| 1253 } |
| 1254 ASSERT(event->event_as_json() != NULL); |
| 1255 result = zone->ConcatStrings(result, event->event_as_json()); |
| 1256 } |
| 1257 return result; |
| 1258 } |
| 1259 |
1003 } // namespace dart | 1260 } // namespace dart |
OLD | NEW |