| 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 | 
|---|