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 class TestStatsStream : public v8::OutputStream { |
| 700 public: |
| 701 TestStatsStream() : eos_signaled_(0), numbers_written_(0) {} |
| 702 virtual ~TestStatsStream() {} |
| 703 virtual void EndOfStream() { ++eos_signaled_; } |
| 704 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { |
| 705 ASSERT(false); |
| 706 return kAbort; |
| 707 } |
| 708 virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int numbers_written) { |
| 709 entries_count_ = 0; |
| 710 for (int i = 1; i < numbers_written; i += 2) |
| 711 entries_count_ += buffer[i]; |
| 712 numbers_written_ += numbers_written; |
| 713 return kContinue; |
| 714 } |
| 715 int eos_signaled() { return eos_signaled_; } |
| 716 int numbers_written() { return numbers_written_; } |
| 717 uint32_t entries_count() const { return entries_count_; } |
| 718 private: |
| 719 int eos_signaled_; |
| 720 int numbers_written_; |
| 721 uint32_t entries_count_; |
| 722 }; |
| 723 |
| 724 |
| 725 TEST(HeapSnapshotObjectsStats) { |
| 726 v8::HandleScope scope; |
| 727 LocalContext env; |
| 728 |
| 729 v8::HeapProfiler::StartHeapObjectsTracking(); |
| 730 |
| 731 for (int i = 0; i < 5; ++i) { |
| 732 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 733 } |
| 734 |
| 735 { |
| 736 TestStatsStream stream; |
| 737 v8::HeapProfiler::PushHeapObjectsStats(&stream); |
| 738 CHECK_EQ(2, stream.numbers_written()); |
| 739 CHECK_EQ(1, stream.eos_signaled()); |
| 740 } |
| 741 |
| 742 { // No data expected in update because nothing happened. |
| 743 TestStatsStream stream; |
| 744 v8::HeapProfiler::PushHeapObjectsStats(&stream); |
| 745 CHECK_EQ(0, stream.numbers_written()); |
| 746 CHECK_EQ(1, stream.eos_signaled()); |
| 747 } |
| 748 |
| 749 v8::Persistent<v8::String> p_string = |
| 750 v8::Persistent<v8::String>::New(v8_str("string")); |
| 751 |
| 752 { // Single chunk of data expected in update. |
| 753 TestStatsStream stream; |
| 754 v8::HeapProfiler::PushHeapObjectsStats(&stream); |
| 755 CHECK_EQ(2, stream.numbers_written()); |
| 756 CHECK_EQ(1, stream.entries_count()); |
| 757 CHECK_EQ(1, stream.eos_signaled()); |
| 758 } |
| 759 |
| 760 { // No data expected in update because nothing happened. |
| 761 TestStatsStream stream; |
| 762 v8::HeapProfiler::PushHeapObjectsStats(&stream); |
| 763 CHECK_EQ(0, stream.numbers_written()); |
| 764 CHECK_EQ(1, stream.eos_signaled()); |
| 765 } |
| 766 |
| 767 v8::HeapProfiler::StopHeapObjectsTracking(); |
| 768 } |
| 769 |
694 | 770 |
695 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 771 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
696 const v8::HeapGraphNode* node, | 772 const v8::HeapGraphNode* node, |
697 int level, int max_level) { | 773 int level, int max_level) { |
698 if (level > max_level) return; | 774 if (level > max_level) return; |
699 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 775 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
700 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 776 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
701 const v8::HeapGraphEdge* prop = node->GetChild(i); | 777 const v8::HeapGraphEdge* prop = node->GetChild(i); |
702 const v8::HeapGraphNode* child = | 778 const v8::HeapGraphNode* child = |
703 snapshot->GetNodeById(prop->GetToNode()->GetId()); | 779 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. | 1441 // Dipose the persistent handles in a different order. |
1366 p_AAA.Dispose(); | 1442 p_AAA.Dispose(); |
1367 CHECK_EQ(global_handle_count + 2, | 1443 CHECK_EQ(global_handle_count + 2, |
1368 v8::HeapProfiler::GetPersistentHandleCount()); | 1444 v8::HeapProfiler::GetPersistentHandleCount()); |
1369 p_CCC.Dispose(); | 1445 p_CCC.Dispose(); |
1370 CHECK_EQ(global_handle_count + 1, | 1446 CHECK_EQ(global_handle_count + 1, |
1371 v8::HeapProfiler::GetPersistentHandleCount()); | 1447 v8::HeapProfiler::GetPersistentHandleCount()); |
1372 p_BBB.Dispose(); | 1448 p_BBB.Dispose(); |
1373 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1449 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
1374 } | 1450 } |
OLD | NEW |