OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Tests for heap profiler | 3 // Tests for heap profiler |
4 | 4 |
5 #ifdef ENABLE_LOGGING_AND_PROFILING | 5 #ifdef ENABLE_LOGGING_AND_PROFILING |
6 | 6 |
7 #include "v8.h" | 7 #include "v8.h" |
8 #include "heap-profiler.h" | 8 #include "heap-profiler.h" |
9 #include "snapshot.h" | 9 #include "snapshot.h" |
10 #include "string-stream.h" | 10 #include "string-stream.h" |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 CompileRun( | 558 CompileRun( |
559 "function X(a, b) { this.a = a; this.b = b; }\n" | 559 "function X(a, b) { this.a = a; this.b = b; }\n" |
560 "x = new X(new X(), new X());\n" | 560 "x = new X(new X(), new X());\n" |
561 "(function() { x.a.a = x.b; })();"); | 561 "(function() { x.a.a = x.b; })();"); |
562 const v8::HeapSnapshot* snapshot = | 562 const v8::HeapSnapshot* snapshot = |
563 v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes")); | 563 v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes")); |
564 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 564 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
565 const v8::HeapGraphNode* x = | 565 const v8::HeapGraphNode* x = |
566 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); | 566 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); |
567 CHECK_NE(NULL, x); | 567 CHECK_NE(NULL, x); |
568 const v8::HeapGraphNode* x_prototype = | |
569 GetProperty(x, v8::HeapGraphEdge::kProperty, "__proto__"); | |
570 CHECK_NE(NULL, x_prototype); | |
571 const v8::HeapGraphNode* x1 = | 568 const v8::HeapGraphNode* x1 = |
572 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 569 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
573 CHECK_NE(NULL, x1); | 570 CHECK_NE(NULL, x1); |
574 const v8::HeapGraphNode* x2 = | 571 const v8::HeapGraphNode* x2 = |
575 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 572 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
576 CHECK_NE(NULL, x2); | 573 CHECK_NE(NULL, x2); |
577 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize()); | 574 |
578 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize()); | 575 // Test approximate sizes. |
579 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize()); | 576 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(false)); |
| 577 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(false)); |
| 578 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(false)); |
| 579 // Test exact sizes. |
| 580 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(true)); |
| 581 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(true)); |
| 582 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(true)); |
580 } | 583 } |
581 | 584 |
582 | 585 |
583 TEST(HeapSnapshotEntryChildren) { | 586 TEST(HeapSnapshotEntryChildren) { |
584 v8::HandleScope scope; | 587 v8::HandleScope scope; |
585 LocalContext env; | 588 LocalContext env; |
586 | 589 |
587 CompileRun( | 590 CompileRun( |
588 "function A() { }\n" | 591 "function A() { }\n" |
589 "a = new A;"); | 592 "a = new A;"); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 b_with_children, | 959 b_with_children, |
957 v8::HeapGraphNode::kObject, | 960 v8::HeapGraphNode::kObject, |
958 "A"); | 961 "A"); |
959 CHECK_NE(NULL, a_from_b); | 962 CHECK_NE(NULL, a_from_b); |
960 CHECK_EQ(0, a_from_b->GetSelfSize()); | 963 CHECK_EQ(0, a_from_b->GetSelfSize()); |
961 CHECK_EQ(0, a_from_b->GetInstancesCount()); | 964 CHECK_EQ(0, a_from_b->GetInstancesCount()); |
962 CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing. | 965 CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing. |
963 CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A. | 966 CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A. |
964 } | 967 } |
965 | 968 |
| 969 |
| 970 TEST(HeapEntryDominator) { |
| 971 // The graph looks like this: |
| 972 // |
| 973 // -> node1 |
| 974 // a |^ |
| 975 // -> node5 ba |
| 976 // a v| |
| 977 // node6 -> node2 |
| 978 // b a |^ |
| 979 // -> node4 ba |
| 980 // b v| |
| 981 // -> node3 |
| 982 // |
| 983 // The dominator for all nodes is node6. |
| 984 |
| 985 v8::HandleScope scope; |
| 986 LocalContext env; |
| 987 |
| 988 CompileRun( |
| 989 "function X(a, b) { this.a = a; this.b = b; }\n" |
| 990 "node6 = new X(new X(new X()), new X(new X(),new X()));\n" |
| 991 "(function(){\n" |
| 992 "node6.a.a.b = node6.b.a; // node1 -> node2\n" |
| 993 "node6.b.a.a = node6.a.a; // node2 -> node1\n" |
| 994 "node6.b.a.b = node6.b.b; // node2 -> node3\n" |
| 995 "node6.b.b.a = node6.b.a; // node3 -> node2\n" |
| 996 "})();"); |
| 997 |
| 998 const v8::HeapSnapshot* snapshot = |
| 999 v8::HeapProfiler::TakeSnapshot(v8::String::New("dominators")); |
| 1000 |
| 1001 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1002 CHECK_NE(NULL, global); |
| 1003 const v8::HeapGraphNode* node6 = |
| 1004 GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); |
| 1005 CHECK_NE(NULL, node6); |
| 1006 const v8::HeapGraphNode* node5 = |
| 1007 GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); |
| 1008 CHECK_NE(NULL, node5); |
| 1009 const v8::HeapGraphNode* node4 = |
| 1010 GetProperty(node6, v8::HeapGraphEdge::kProperty, "b"); |
| 1011 CHECK_NE(NULL, node4); |
| 1012 const v8::HeapGraphNode* node3 = |
| 1013 GetProperty(node4, v8::HeapGraphEdge::kProperty, "b"); |
| 1014 CHECK_NE(NULL, node3); |
| 1015 const v8::HeapGraphNode* node2 = |
| 1016 GetProperty(node4, v8::HeapGraphEdge::kProperty, "a"); |
| 1017 CHECK_NE(NULL, node2); |
| 1018 const v8::HeapGraphNode* node1 = |
| 1019 GetProperty(node5, v8::HeapGraphEdge::kProperty, "a"); |
| 1020 CHECK_NE(NULL, node1); |
| 1021 |
| 1022 CHECK_EQ(node6, node1->GetDominatorNode()); |
| 1023 CHECK_EQ(node6, node2->GetDominatorNode()); |
| 1024 CHECK_EQ(node6, node3->GetDominatorNode()); |
| 1025 CHECK_EQ(node6, node4->GetDominatorNode()); |
| 1026 CHECK_EQ(node6, node5->GetDominatorNode()); |
| 1027 } |
| 1028 |
| 1029 |
966 namespace { | 1030 namespace { |
967 | 1031 |
968 class TestJSONStream : public v8::OutputStream { | 1032 class TestJSONStream : public v8::OutputStream { |
969 public: | 1033 public: |
970 TestJSONStream() : eos_signaled_(0), abort_countdown_(-1) {} | 1034 TestJSONStream() : eos_signaled_(0), abort_countdown_(-1) {} |
971 explicit TestJSONStream(int abort_countdown) | 1035 explicit TestJSONStream(int abort_countdown) |
972 : eos_signaled_(0), abort_countdown_(abort_countdown) {} | 1036 : eos_signaled_(0), abort_countdown_(abort_countdown) {} |
973 virtual ~TestJSONStream() {} | 1037 virtual ~TestJSONStream() {} |
974 virtual void EndOfStream() { ++eos_signaled_; } | 1038 virtual void EndOfStream() { ++eos_signaled_; } |
975 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { | 1039 virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 LocalContext env; | 1172 LocalContext env; |
1109 const v8::HeapSnapshot* snapshot = | 1173 const v8::HeapSnapshot* snapshot = |
1110 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort")); | 1174 v8::HeapProfiler::TakeSnapshot(v8::String::New("abort")); |
1111 TestJSONStream stream(5); | 1175 TestJSONStream stream(5); |
1112 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 1176 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
1113 CHECK_GT(stream.size(), 0); | 1177 CHECK_GT(stream.size(), 0); |
1114 CHECK_EQ(0, stream.eos_signaled()); | 1178 CHECK_EQ(0, stream.eos_signaled()); |
1115 } | 1179 } |
1116 | 1180 |
1117 #endif // ENABLE_LOGGING_AND_PROFILING | 1181 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |