| 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, entries_size = stats_update.entries_size()); |
| 808 CHECK_EQ(3, stats_update.entries_count()); | 818 CHECK_EQ(3, stats_update.entries_count()); |
| 809 CHECK_EQ(4, stats_update.first_interval_index()); | 819 CHECK_EQ(4, stats_update.first_interval_index()); |
| 810 } | 820 } |
| 811 } | 821 } |
| 812 | 822 |
| 813 { | 823 { |
| 814 // Single chunk of data with two left entries expected in update. | 824 // Single chunk of data with two left entries expected in update. |
| 815 TestStatsStream stats_update = GetHeapStatsUpdate(); | 825 TestStatsStream stats_update = GetHeapStatsUpdate(); |
| 816 CHECK_EQ(1, stats_update.intervals_count()); | 826 CHECK_EQ(1, stats_update.intervals_count()); |
| 817 CHECK_EQ(2, stats_update.numbers_written()); | 827 CHECK_EQ(3, stats_update.numbers_written()); |
| 828 CHECK_GT(entries_size, stats_update.entries_size()); |
| 818 CHECK_EQ(1, stats_update.entries_count()); | 829 CHECK_EQ(1, stats_update.entries_count()); |
| 819 // Two strings from forth interval were released. | 830 // Two strings from forth interval were released. |
| 820 CHECK_EQ(4, stats_update.first_interval_index()); | 831 CHECK_EQ(4, stats_update.first_interval_index()); |
| 821 } | 832 } |
| 822 } | 833 } |
| 823 | 834 |
| 824 { | 835 { |
| 825 // Single chunk of data with 0 left entries expected in update. | 836 // Single chunk of data with 0 left entries expected in update. |
| 826 TestStatsStream stats_update = GetHeapStatsUpdate(); | 837 TestStatsStream stats_update = GetHeapStatsUpdate(); |
| 827 CHECK_EQ(1, stats_update.intervals_count()); | 838 CHECK_EQ(1, stats_update.intervals_count()); |
| 828 CHECK_EQ(2, stats_update.numbers_written()); | 839 CHECK_EQ(3, stats_update.numbers_written()); |
| 840 CHECK_EQ(0, stats_update.entries_size()); |
| 829 CHECK_EQ(0, stats_update.entries_count()); | 841 CHECK_EQ(0, stats_update.entries_count()); |
| 830 // The last string from forth interval was released. | 842 // The last string from forth interval was released. |
| 831 CHECK_EQ(4, stats_update.first_interval_index()); | 843 CHECK_EQ(4, stats_update.first_interval_index()); |
| 832 } | 844 } |
| 833 } | 845 } |
| 834 { | 846 { |
| 835 // Single chunk of data with 0 left entries expected in update. | 847 // Single chunk of data with 0 left entries expected in update. |
| 836 TestStatsStream stats_update = GetHeapStatsUpdate(); | 848 TestStatsStream stats_update = GetHeapStatsUpdate(); |
| 837 CHECK_EQ(1, stats_update.intervals_count()); | 849 CHECK_EQ(1, stats_update.intervals_count()); |
| 838 CHECK_EQ(2, stats_update.numbers_written()); | 850 CHECK_EQ(3, stats_update.numbers_written()); |
| 851 CHECK_EQ(0, stats_update.entries_size()); |
| 839 CHECK_EQ(0, stats_update.entries_count()); | 852 CHECK_EQ(0, stats_update.entries_count()); |
| 840 // The only string from the second interval was released. | 853 // The only string from the second interval was released. |
| 841 CHECK_EQ(2, stats_update.first_interval_index()); | 854 CHECK_EQ(2, stats_update.first_interval_index()); |
| 842 } | 855 } |
| 843 | 856 |
| 857 v8::Local<v8::Array> array = v8::Array::New(); |
| 858 CHECK_EQ(0, array->Length()); |
| 859 // Force array's buffer allocation. |
| 860 array->Set(2, v8_num(7)); |
| 861 |
| 862 uint32_t entries_size; |
| 863 { |
| 864 // Single chunk of data with 2 entries expected in update. |
| 865 TestStatsStream stats_update = GetHeapStatsUpdate(); |
| 866 CHECK_EQ(1, stats_update.intervals_count()); |
| 867 CHECK_EQ(3, stats_update.numbers_written()); |
| 868 CHECK_LT(0, entries_size = stats_update.entries_size()); |
| 869 // They are the array and its buffer. |
| 870 CHECK_EQ(2, stats_update.entries_count()); |
| 871 CHECK_EQ(8, stats_update.first_interval_index()); |
| 872 } |
| 873 |
| 874 for (int i = 0; i < 100; ++i) |
| 875 array->Set(i, v8_num(i)); |
| 876 |
| 877 { |
| 878 // Single chunk of data with 1 entry expected in update. |
| 879 TestStatsStream stats_update = GetHeapStatsUpdate(); |
| 880 CHECK_EQ(1, stats_update.intervals_count()); |
| 881 // The first interval was changed because old buffer was collected. |
| 882 // The second interval was changed because new buffer was allocated. |
| 883 CHECK_EQ(6, stats_update.numbers_written()); |
| 884 CHECK_LT(entries_size, stats_update.entries_size()); |
| 885 CHECK_EQ(2, stats_update.entries_count()); |
| 886 CHECK_EQ(8, stats_update.first_interval_index()); |
| 887 } |
| 888 |
| 844 v8::HeapProfiler::StopHeapObjectsTracking(); | 889 v8::HeapProfiler::StopHeapObjectsTracking(); |
| 845 } | 890 } |
| 846 | 891 |
| 847 | 892 |
| 848 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 893 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
| 849 const v8::HeapGraphNode* node, | 894 const v8::HeapGraphNode* node, |
| 850 int level, int max_level) { | 895 int level, int max_level) { |
| 851 if (level > max_level) return; | 896 if (level > max_level) return; |
| 852 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 897 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
| 853 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 898 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. | 1563 // Dipose the persistent handles in a different order. |
| 1519 p_AAA.Dispose(); | 1564 p_AAA.Dispose(); |
| 1520 CHECK_EQ(global_handle_count + 2, | 1565 CHECK_EQ(global_handle_count + 2, |
| 1521 v8::HeapProfiler::GetPersistentHandleCount()); | 1566 v8::HeapProfiler::GetPersistentHandleCount()); |
| 1522 p_CCC.Dispose(); | 1567 p_CCC.Dispose(); |
| 1523 CHECK_EQ(global_handle_count + 1, | 1568 CHECK_EQ(global_handle_count + 1, |
| 1524 v8::HeapProfiler::GetPersistentHandleCount()); | 1569 v8::HeapProfiler::GetPersistentHandleCount()); |
| 1525 p_BBB.Dispose(); | 1570 p_BBB.Dispose(); |
| 1526 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1571 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
| 1527 } | 1572 } |
| OLD | NEW |