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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 virtual ~TestJSONStream() {} | 550 virtual ~TestJSONStream() {} |
551 virtual void EndOfStream() { ++eos_signaled_; } | 551 virtual void EndOfStream() { ++eos_signaled_; } |
552 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { | 552 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { |
553 if (abort_countdown_ > 0) --abort_countdown_; | 553 if (abort_countdown_ > 0) --abort_countdown_; |
554 if (abort_countdown_ == 0) return kAbort; | 554 if (abort_countdown_ == 0) return kAbort; |
555 CHECK_GT(chars_written, 0); | 555 CHECK_GT(chars_written, 0); |
556 i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0'); | 556 i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0'); |
557 memcpy(chunk.start(), buffer, chars_written); | 557 memcpy(chunk.start(), buffer, chars_written); |
558 return kContinue; | 558 return kContinue; |
559 } | 559 } |
560 virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) { | |
561 ASSERT(false); | |
562 return kAbort; | |
563 } | |
560 void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } | 564 void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } |
561 int eos_signaled() { return eos_signaled_; } | 565 int eos_signaled() { return eos_signaled_; } |
562 int size() { return buffer_.size(); } | 566 int size() { return buffer_.size(); } |
567 | |
563 private: | 568 private: |
564 i::Collector<char> buffer_; | 569 i::Collector<char> buffer_; |
565 int eos_signaled_; | 570 int eos_signaled_; |
566 int abort_countdown_; | 571 int abort_countdown_; |
567 }; | 572 }; |
568 | 573 |
569 class AsciiResource: public v8::String::ExternalAsciiStringResource { | 574 class AsciiResource: public v8::String::ExternalAsciiStringResource { |
570 public: | 575 public: |
571 explicit AsciiResource(i::Vector<char> string): data_(string.start()) { | 576 explicit AsciiResource(i::Vector<char> string): data_(string.start()) { |
572 length_ = string.length(); | 577 length_ = string.length(); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 v8::HandleScope scope; | 689 v8::HandleScope scope; |
685 LocalContext env; | 690 LocalContext env; |
686 const v8::HeapSnapshot* snapshot = | 691 const v8::HeapSnapshot* snapshot = |
687 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); | 692 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); |
688 TestJSONStream stream(5); | 693 TestJSONStream stream(5); |
689 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 694 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
690 CHECK_GT(stream.size(), 0); | 695 CHECK_GT(stream.size(), 0); |
691 CHECK_EQ(0, stream.eos_signaled()); | 696 CHECK_EQ(0, stream.eos_signaled()); |
692 } | 697 } |
693 | 698 |
699 namespace { | |
700 | |
701 class TestStatsStream : public v8::OutputStream { | |
702 public: | |
703 TestStatsStream() | |
704 : eos_signaled_(0), | |
705 numbers_written_(0), | |
706 entries_count_(0), | |
707 intervals_count_(0), | |
708 first_interval_index_(-1) { } | |
709 TestStatsStream(const TestStatsStream& stream) | |
710 : eos_signaled_(stream.eos_signaled_), | |
711 numbers_written_(stream.numbers_written_), | |
712 entries_count_(stream.entries_count_), | |
713 intervals_count_(stream.intervals_count_), | |
714 first_interval_index_(stream.first_interval_index_) { } | |
715 virtual ~TestStatsStream() {} | |
716 virtual void EndOfStream() { ++eos_signaled_; } | |
717 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { | |
718 ASSERT(false); | |
719 return kAbort; | |
720 } | |
721 virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int numbers_written) { | |
722 ++intervals_count_; | |
723 ASSERT(numbers_written); | |
724 numbers_written_ += numbers_written; | |
725 entries_count_ = 0; | |
726 if (first_interval_index_ == -1 && numbers_written != 0) | |
727 first_interval_index_ = buffer[0]; | |
728 for (int i = 1; i < numbers_written; i += 2) | |
729 entries_count_ += buffer[i]; | |
730 | |
731 return kContinue; | |
732 } | |
733 int eos_signaled() { return eos_signaled_; } | |
734 int numbers_written() { return numbers_written_; } | |
735 uint32_t entries_count() const { return entries_count_; } | |
736 int intervals_count() const { return intervals_count_; } | |
737 int first_interval_index() const { return first_interval_index_; } | |
738 | |
739 private: | |
740 int eos_signaled_; | |
741 int numbers_written_; | |
742 uint32_t entries_count_; | |
743 int intervals_count_; | |
744 int first_interval_index_; | |
745 }; | |
746 | |
747 } // namespace | |
748 | |
749 static TestStatsStream GetHeapStatsUpdate() { | |
750 TestStatsStream stream; | |
751 v8::HeapProfiler::PushHeapObjectsStats(&stream); | |
752 CHECK_EQ(1, stream.eos_signaled()); | |
753 return stream; | |
754 } | |
755 | |
756 | |
757 TEST(HeapSnapshotObjectsStats) { | |
758 v8::HandleScope scope; | |
759 LocalContext env; | |
760 | |
761 v8::HeapProfiler::StartHeapObjectsTracking(); | |
762 for (int i = 0; i < 5; ++i) { | |
763 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | |
764 } | |
765 | |
766 { | |
767 // Single chunk of data expected in update. Initial data. | |
768 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
769 CHECK_EQ(1, stats_update.intervals_count()); | |
770 CHECK_EQ(2, stats_update.numbers_written()); | |
771 CHECK_EQ(0, stats_update.first_interval_index()); | |
772 } | |
773 | |
774 // No data expected in update because nothing has happened. | |
775 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); | |
776 { | |
777 v8::HandleScope inner_scope_1; | |
778 v8::Local<v8::String> string1 = v8_str("string1"); | |
779 { | |
780 // Single chunk of data with one new entry expected in update. | |
781 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
782 CHECK_EQ(1, stats_update.intervals_count()); | |
783 CHECK_EQ(2, stats_update.numbers_written()); | |
784 CHECK_EQ(1, stats_update.entries_count()); | |
785 CHECK_EQ(2, stats_update.first_interval_index()); | |
786 } | |
787 | |
788 // No data expected in update because nothing happened. | |
789 CHECK_EQ(0, GetHeapStatsUpdate().numbers_written()); | |
790 | |
791 { | |
792 v8::HandleScope inner_scope_2; | |
793 v8::Local<v8::String> string2 = v8_str("string2"); | |
794 | |
795 { | |
796 v8::HandleScope inner_scope_3; | |
797 v8::Handle<v8::String> string3 = v8::String::New("string3"); | |
798 v8::Handle<v8::String> string4 = v8::String::New("string4"); | |
799 | |
800 { | |
801 // Single chunk of data with three new entries expected in update. | |
802 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
803 CHECK_EQ(1, stats_update.intervals_count()); | |
804 CHECK_EQ(2, stats_update.numbers_written()); | |
805 CHECK_EQ(3, stats_update.entries_count()); | |
806 CHECK_EQ(4, stats_update.first_interval_index()); | |
807 } | |
808 } | |
809 | |
810 { | |
811 // Single chunk of data with two left entries expected in update. | |
812 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
mnaganov (inactive)
2012/04/13 08:44:51
nit: Might be worth adding a comment that prior to
| |
813 CHECK_EQ(1, stats_update.intervals_count()); | |
814 CHECK_EQ(2, stats_update.numbers_written()); | |
815 CHECK_EQ(1, stats_update.entries_count()); | |
816 // Two strings from forth interval were released. | |
817 CHECK_EQ(4, stats_update.first_interval_index()); | |
818 } | |
819 } | |
820 | |
821 { | |
822 // Single chunk of data with 0 left entries expected in update. | |
823 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
824 CHECK_EQ(1, stats_update.intervals_count()); | |
825 CHECK_EQ(2, stats_update.numbers_written()); | |
826 CHECK_EQ(0, stats_update.entries_count()); | |
827 // The last string from forth interval was released. | |
828 CHECK_EQ(4, stats_update.first_interval_index()); | |
829 } | |
830 } | |
831 { | |
832 // Single chunk of data with 0 left entries expected in update. | |
833 TestStatsStream stats_update = GetHeapStatsUpdate(); | |
834 CHECK_EQ(1, stats_update.intervals_count()); | |
835 CHECK_EQ(2, stats_update.numbers_written()); | |
836 CHECK_EQ(0, stats_update.entries_count()); | |
837 // The only string from the second interval was released. | |
838 CHECK_EQ(2, stats_update.first_interval_index()); | |
839 } | |
840 | |
841 v8::HeapProfiler::StopHeapObjectsTracking(); | |
842 } | |
843 | |
694 | 844 |
695 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 845 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
696 const v8::HeapGraphNode* node, | 846 const v8::HeapGraphNode* node, |
697 int level, int max_level) { | 847 int level, int max_level) { |
698 if (level > max_level) return; | 848 if (level > max_level) return; |
699 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 849 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
700 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 850 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
701 const v8::HeapGraphEdge* prop = node->GetChild(i); | 851 const v8::HeapGraphEdge* prop = node->GetChild(i); |
702 const v8::HeapGraphNode* child = | 852 const v8::HeapGraphNode* child = |
703 snapshot->GetNodeById(prop->GetToNode()->GetId()); | 853 snapshot->GetNodeById(prop->GetToNode()->GetId()); |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 // Dipose the persistent handles in a different order. | 1515 // Dipose the persistent handles in a different order. |
1366 p_AAA.Dispose(); | 1516 p_AAA.Dispose(); |
1367 CHECK_EQ(global_handle_count + 2, | 1517 CHECK_EQ(global_handle_count + 2, |
1368 v8::HeapProfiler::GetPersistentHandleCount()); | 1518 v8::HeapProfiler::GetPersistentHandleCount()); |
1369 p_CCC.Dispose(); | 1519 p_CCC.Dispose(); |
1370 CHECK_EQ(global_handle_count + 1, | 1520 CHECK_EQ(global_handle_count + 1, |
1371 v8::HeapProfiler::GetPersistentHandleCount()); | 1521 v8::HeapProfiler::GetPersistentHandleCount()); |
1372 p_BBB.Dispose(); | 1522 p_BBB.Dispose(); |
1373 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1523 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
1374 } | 1524 } |
OLD | NEW |