OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Tests for heap profiler | 3 // Tests for heap profiler |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "cctest.h" | 7 #include "cctest.h" |
8 #include "heap-profiler.h" | 8 #include "heap-profiler.h" |
9 #include "snapshot.h" | 9 #include "snapshot.h" |
10 #include "utils-inl.h" | 10 #include "utils-inl.h" |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
697 } | 697 } |
698 | 698 |
699 namespace { | 699 namespace { |
700 | 700 |
701 class TestStatsStream : public v8::OutputStream { | 701 class TestStatsStream : public v8::OutputStream { |
702 public: | 702 public: |
703 TestStatsStream() | 703 TestStatsStream() |
704 : eos_signaled_(0), | 704 : eos_signaled_(0), |
705 numbers_written_(0), | 705 numbers_written_(0), |
706 entries_count_(0), | 706 entries_count_(0), |
707 entries_size_(0), | |
707 intervals_count_(0), | 708 intervals_count_(0), |
708 first_interval_index_(-1) { } | 709 first_interval_index_(-1) { } |
709 TestStatsStream(const TestStatsStream& stream) | 710 TestStatsStream(const TestStatsStream& stream) |
710 : v8::OutputStream(stream), | 711 : v8::OutputStream(stream), |
711 eos_signaled_(stream.eos_signaled_), | 712 eos_signaled_(stream.eos_signaled_), |
712 numbers_written_(stream.numbers_written_), | 713 numbers_written_(stream.numbers_written_), |
713 entries_count_(stream.entries_count_), | 714 entries_count_(stream.entries_count_), |
715 entries_size_(stream.entries_size_), | |
714 intervals_count_(stream.intervals_count_), | 716 intervals_count_(stream.intervals_count_), |
715 first_interval_index_(stream.first_interval_index_) { } | 717 first_interval_index_(stream.first_interval_index_) { } |
716 virtual ~TestStatsStream() {} | 718 virtual ~TestStatsStream() {} |
717 virtual void EndOfStream() { ++eos_signaled_; } | 719 virtual void EndOfStream() { ++eos_signaled_; } |
718 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { | 720 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { |
719 ASSERT(false); | 721 ASSERT(false); |
720 return kAbort; | 722 return kAbort; |
721 } | 723 } |
722 virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int numbers_written) { | 724 virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int numbers_written) { |
723 ++intervals_count_; | 725 ++intervals_count_; |
724 ASSERT(numbers_written); | 726 ASSERT(numbers_written); |
725 numbers_written_ += numbers_written; | 727 numbers_written_ += numbers_written; |
726 entries_count_ = 0; | 728 entries_count_ = 0; |
727 if (first_interval_index_ == -1 && numbers_written != 0) | 729 if (first_interval_index_ == -1 && numbers_written != 0) |
728 first_interval_index_ = buffer[0]; | 730 first_interval_index_ = buffer[0]; |
729 for (int i = 1; i < numbers_written; i += 2) | 731 for (int i = 0; i < numbers_written; i += 3) { |
730 entries_count_ += buffer[i]; | 732 entries_count_ += buffer[i+1]; |
733 entries_size_ += buffer[i+2]; | |
734 } | |
731 | 735 |
732 return kContinue; | 736 return kContinue; |
733 } | 737 } |
734 int eos_signaled() { return eos_signaled_; } | 738 int eos_signaled() { return eos_signaled_; } |
735 int numbers_written() { return numbers_written_; } | 739 int numbers_written() { return numbers_written_; } |
736 uint32_t entries_count() const { return entries_count_; } | 740 uint32_t entries_count() const { return entries_count_; } |
741 uint32_t entries_size() const { return entries_size_; } | |
737 int intervals_count() const { return intervals_count_; } | 742 int intervals_count() const { return intervals_count_; } |
738 int first_interval_index() const { return first_interval_index_; } | 743 int first_interval_index() const { return first_interval_index_; } |
739 | 744 |
740 private: | 745 private: |
741 int eos_signaled_; | 746 int eos_signaled_; |
742 int numbers_written_; | 747 int numbers_written_; |
743 uint32_t entries_count_; | 748 uint32_t entries_count_; |
749 uint32_t entries_size_; | |
744 int intervals_count_; | 750 int intervals_count_; |
745 int first_interval_index_; | 751 int first_interval_index_; |
746 }; | 752 }; |
747 | 753 |
748 } // namespace | 754 } // namespace |
749 | 755 |
750 static TestStatsStream GetHeapStatsUpdate() { | 756 static TestStatsStream GetHeapStatsUpdate() { |
751 TestStatsStream stream; | 757 TestStatsStream stream; |
752 v8::HeapProfiler::PushHeapObjectsStats(&stream); | 758 v8::HeapProfiler::PushHeapObjectsStats(&stream); |
753 CHECK_EQ(1, stream.eos_signaled()); | 759 CHECK_EQ(1, stream.eos_signaled()); |
754 return stream; | 760 return stream; |
755 } | 761 } |
756 | 762 |
757 | 763 |
758 TEST(HeapSnapshotObjectsStats) { | 764 TEST(HeapSnapshotObjectsStats) { |
759 v8::HandleScope scope; | 765 v8::HandleScope scope; |
760 LocalContext env; | 766 LocalContext env; |
761 | 767 |
762 v8::HeapProfiler::StartHeapObjectsTracking(); | 768 v8::HeapProfiler::StartHeapObjectsTracking(); |
763 // We have to call GC 5 times. In other case the garbage will be | 769 // We have to call GC 5 times. In other case the garbage will be |
764 // the reason of flakiness. | 770 // the reason of flakiness. |
765 for (int i = 0; i < 5; ++i) { | 771 for (int i = 0; i < 5; ++i) { |
766 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 772 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
767 } | 773 } |
768 | 774 |
769 { | 775 { |
770 // Single chunk of data expected in update. Initial data. | 776 // Single chunk of data expected in update. Initial data. |
771 TestStatsStream stats_update = GetHeapStatsUpdate(); | 777 TestStatsStream stats_update = GetHeapStatsUpdate(); |
772 CHECK_EQ(1, stats_update.intervals_count()); | 778 CHECK_EQ(1, stats_update.intervals_count()); |
773 CHECK_EQ(2, stats_update.numbers_written()); | 779 CHECK_EQ(3, stats_update.numbers_written()); |
780 CHECK_LT(0, stats_update.entries_size()); | |
774 CHECK_EQ(0, stats_update.first_interval_index()); | 781 CHECK_EQ(0, stats_update.first_interval_index()); |
775 } | 782 } |
776 | 783 |
777 // No data expected in update because nothing has happened. | 784 // No data expected in update because nothing has happened. |
778 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); | 785 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); |
779 { | 786 { |
780 v8::HandleScope inner_scope_1; | 787 v8::HandleScope inner_scope_1; |
781 v8::Local<v8::String> string1 = v8_str("string1"); | 788 v8::Local<v8::String> string1 = v8_str("string1"); |
782 { | 789 { |
783 // Single chunk of data with one new entry expected in update. | 790 // Single chunk of data with one new entry expected in update. |
784 TestStatsStream stats_update = GetHeapStatsUpdate(); | 791 TestStatsStream stats_update = GetHeapStatsUpdate(); |
785 CHECK_EQ(1, stats_update.intervals_count()); | 792 CHECK_EQ(1, stats_update.intervals_count()); |
786 CHECK_EQ(2, stats_update.numbers_written()); | 793 CHECK_EQ(3, stats_update.numbers_written()); |
794 CHECK_LT(0, stats_update.entries_size()); | |
787 CHECK_EQ(1, stats_update.entries_count()); | 795 CHECK_EQ(1, stats_update.entries_count()); |
788 CHECK_EQ(2, stats_update.first_interval_index()); | 796 CHECK_EQ(2, stats_update.first_interval_index()); |
789 } | 797 } |
790 | 798 |
791 // No data expected in update because nothing happened. | 799 // No data expected in update because nothing happened. |
792 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); | 800 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); |
793 | 801 |
794 { | 802 { |
795 v8::HandleScope inner_scope_2; | 803 v8::HandleScope inner_scope_2; |
796 v8::Local<v8::String> string2 = v8_str("string2"); | 804 v8::Local<v8::String> string2 = v8_str("string2"); |
797 | 805 |
806 uint32_t entries_size; | |
798 { | 807 { |
799 v8::HandleScope inner_scope_3; | 808 v8::HandleScope inner_scope_3; |
800 v8::Handle<v8::String> string3 = v8::String::New("string3"); | 809 v8::Handle<v8::String> string3 = v8::String::New("string3"); |
801 v8::Handle<v8::String> string4 = v8::String::New("string4"); | 810 v8::Handle<v8::String> string4 = v8::String::New("string4"); |
802 | 811 |
803 { | 812 { |
804 // Single chunk of data with three new entries expected in update. | 813 // Single chunk of data with three new entries expected in update. |
805 TestStatsStream stats_update = GetHeapStatsUpdate(); | 814 TestStatsStream stats_update = GetHeapStatsUpdate(); |
806 CHECK_EQ(1, stats_update.intervals_count()); | 815 CHECK_EQ(1, stats_update.intervals_count()); |
807 CHECK_EQ(2, stats_update.numbers_written()); | 816 CHECK_EQ(3, stats_update.numbers_written()); |
817 CHECK_LT(0, stats_update.entries_size()); | |
818 entries_size = stats_update.entries_size(); | |
mnaganov (inactive)
2012/04/16 08:13:54
I'd transpose these two lines to reuse entries_siz
| |
808 CHECK_EQ(3, stats_update.entries_count()); | 819 CHECK_EQ(3, stats_update.entries_count()); |
809 CHECK_EQ(4, stats_update.first_interval_index()); | 820 CHECK_EQ(4, stats_update.first_interval_index()); |
810 } | 821 } |
811 } | 822 } |
812 | 823 |
813 { | 824 { |
814 // Single chunk of data with two left entries expected in update. | 825 // Single chunk of data with two left entries expected in update. |
815 TestStatsStream stats_update = GetHeapStatsUpdate(); | 826 TestStatsStream stats_update = GetHeapStatsUpdate(); |
816 CHECK_EQ(1, stats_update.intervals_count()); | 827 CHECK_EQ(1, stats_update.intervals_count()); |
817 CHECK_EQ(2, stats_update.numbers_written()); | 828 CHECK_EQ(3, stats_update.numbers_written()); |
829 CHECK_LT(stats_update.entries_size(), entries_size); | |
mnaganov (inactive)
2012/04/16 08:13:54
Transpose arguments, CHECK_LT -> CHECK_GT
| |
818 CHECK_EQ(1, stats_update.entries_count()); | 830 CHECK_EQ(1, stats_update.entries_count()); |
819 // Two strings from forth interval were released. | 831 // Two strings from forth interval were released. |
820 CHECK_EQ(4, stats_update.first_interval_index()); | 832 CHECK_EQ(4, stats_update.first_interval_index()); |
821 } | 833 } |
822 } | 834 } |
823 | 835 |
824 { | 836 { |
825 // Single chunk of data with 0 left entries expected in update. | 837 // Single chunk of data with 0 left entries expected in update. |
826 TestStatsStream stats_update = GetHeapStatsUpdate(); | 838 TestStatsStream stats_update = GetHeapStatsUpdate(); |
827 CHECK_EQ(1, stats_update.intervals_count()); | 839 CHECK_EQ(1, stats_update.intervals_count()); |
828 CHECK_EQ(2, stats_update.numbers_written()); | 840 CHECK_EQ(3, stats_update.numbers_written()); |
841 CHECK_EQ(0, stats_update.entries_size()); | |
829 CHECK_EQ(0, stats_update.entries_count()); | 842 CHECK_EQ(0, stats_update.entries_count()); |
830 // The last string from forth interval was released. | 843 // The last string from forth interval was released. |
831 CHECK_EQ(4, stats_update.first_interval_index()); | 844 CHECK_EQ(4, stats_update.first_interval_index()); |
832 } | 845 } |
833 } | 846 } |
834 { | 847 { |
835 // Single chunk of data with 0 left entries expected in update. | 848 // Single chunk of data with 0 left entries expected in update. |
836 TestStatsStream stats_update = GetHeapStatsUpdate(); | 849 TestStatsStream stats_update = GetHeapStatsUpdate(); |
837 CHECK_EQ(1, stats_update.intervals_count()); | 850 CHECK_EQ(1, stats_update.intervals_count()); |
838 CHECK_EQ(2, stats_update.numbers_written()); | 851 CHECK_EQ(3, stats_update.numbers_written()); |
852 CHECK_EQ(0, stats_update.entries_size()); | |
839 CHECK_EQ(0, stats_update.entries_count()); | 853 CHECK_EQ(0, stats_update.entries_count()); |
840 // The only string from the second interval was released. | 854 // The only string from the second interval was released. |
841 CHECK_EQ(2, stats_update.first_interval_index()); | 855 CHECK_EQ(2, stats_update.first_interval_index()); |
842 } | 856 } |
843 | 857 |
858 v8::Local<v8::Array> array = v8::Array::New(); | |
859 CHECK_EQ(0, array->Length()); | |
860 // Force array's buffer allocation. | |
861 array->Set(2, v8_num(7)); | |
862 | |
863 uint32_t entries_size; | |
864 { | |
865 // Single chunk of data with 2 entries expected in update. | |
866 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
867 CHECK_EQ(1, stats_update.intervals_count()); | |
868 CHECK_EQ(3, stats_update.numbers_written()); | |
869 CHECK_LT(0, stats_update.entries_size()); | |
870 entries_size = stats_update.entries_size(); | |
mnaganov (inactive)
2012/04/16 08:13:54
Also transpose lines
| |
871 // It were the array and it's buffer. | |
mnaganov (inactive)
2012/04/16 08:13:54
nit: "It were" -> "There are", "it's" -> "its"
| |
872 CHECK_EQ(2, stats_update.entries_count()); | |
873 CHECK_EQ(8, stats_update.first_interval_index()); | |
874 } | |
875 | |
876 for (int i = 0; i < 100; ++i) | |
877 array->Set(i, v8_num(i)); | |
878 | |
879 { | |
880 // Single chunk of data with 1 entry expected in update. | |
881 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
882 CHECK_EQ(1, stats_update.intervals_count()); | |
883 // The first interval was changed because old buffer was collected. | |
884 // The second interval was changed because new buffer was allocated. | |
885 CHECK_EQ(6, stats_update.numbers_written()); | |
886 CHECK_LT(entries_size, stats_update.entries_size()); | |
887 CHECK_EQ(2, stats_update.entries_count()); | |
888 CHECK_EQ(8, stats_update.first_interval_index()); | |
889 } | |
890 | |
844 v8::HeapProfiler::StopHeapObjectsTracking(); | 891 v8::HeapProfiler::StopHeapObjectsTracking(); |
845 } | 892 } |
846 | 893 |
847 | 894 |
848 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 895 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
849 const v8::HeapGraphNode* node, | 896 const v8::HeapGraphNode* node, |
850 int level, int max_level) { | 897 int level, int max_level) { |
851 if (level > max_level) return; | 898 if (level > max_level) return; |
852 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 899 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
853 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 900 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1518 // Dipose the persistent handles in a different order. | 1565 // Dipose the persistent handles in a different order. |
1519 p_AAA.Dispose(); | 1566 p_AAA.Dispose(); |
1520 CHECK_EQ(global_handle_count + 2, | 1567 CHECK_EQ(global_handle_count + 2, |
1521 v8::HeapProfiler::GetPersistentHandleCount()); | 1568 v8::HeapProfiler::GetPersistentHandleCount()); |
1522 p_CCC.Dispose(); | 1569 p_CCC.Dispose(); |
1523 CHECK_EQ(global_handle_count + 1, | 1570 CHECK_EQ(global_handle_count + 1, |
1524 v8::HeapProfiler::GetPersistentHandleCount()); | 1571 v8::HeapProfiler::GetPersistentHandleCount()); |
1525 p_BBB.Dispose(); | 1572 p_BBB.Dispose(); |
1526 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1573 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
1527 } | 1574 } |
OLD | NEW |