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" |
11 #include "../include/v8-profiler.h" | 11 #include "../include/v8-profiler.h" |
12 | 12 |
13 namespace { | |
14 | |
15 class NamedEntriesDetector { | |
16 public: | |
17 NamedEntriesDetector() | |
18 : has_A2(false), has_B2(false), has_C2(false) { | |
19 } | |
20 | |
21 void Apply(i::HeapEntry** entry_ptr) { | |
22 if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true; | |
23 if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true; | |
24 if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true; | |
25 } | |
26 | |
27 static bool IsReachableNodeWithName(i::HeapEntry* entry, const char* name) { | |
28 return strcmp(name, entry->name()) == 0 && entry->painted_reachable(); | |
29 } | |
30 | |
31 bool has_A2; | |
32 bool has_B2; | |
33 bool has_C2; | |
34 }; | |
35 | |
36 } // namespace | |
37 | |
38 | 13 |
39 static const v8::HeapGraphNode* GetGlobalObject( | 14 static const v8::HeapGraphNode* GetGlobalObject( |
40 const v8::HeapSnapshot* snapshot) { | 15 const v8::HeapSnapshot* snapshot) { |
41 CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); | 16 CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); |
42 const v8::HeapGraphNode* global_obj = | 17 const v8::HeapGraphNode* global_obj = |
43 snapshot->GetRoot()->GetChild(0)->GetToNode(); | 18 snapshot->GetRoot()->GetChild(0)->GetToNode(); |
44 CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( | 19 CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( |
45 reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); | 20 reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); |
46 return global_obj; | 21 return global_obj; |
47 } | 22 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 | 54 |
80 CompileRun( | 55 CompileRun( |
81 "function A2() {}\n" | 56 "function A2() {}\n" |
82 "function B2(x) { return function() { return typeof x; }; }\n" | 57 "function B2(x) { return function() { return typeof x; }; }\n" |
83 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" | 58 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" |
84 "var a2 = new A2();\n" | 59 "var a2 = new A2();\n" |
85 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" | 60 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" |
86 "var c2 = new C2(a2);"); | 61 "var c2 = new C2(a2);"); |
87 const v8::HeapSnapshot* snapshot_env2 = | 62 const v8::HeapSnapshot* snapshot_env2 = |
88 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); | 63 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); |
89 i::HeapSnapshot* i_snapshot_env2 = | |
90 const_cast<i::HeapSnapshot*>( | |
91 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2)); | |
92 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); | 64 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); |
93 // Paint all nodes reachable from global object. | |
94 i_snapshot_env2->ClearPaint(); | |
95 const_cast<i::HeapEntry*>( | |
96 reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable(); | |
97 | 65 |
98 // Verify, that JS global object of env2 has '..2' properties. | 66 // Verify, that JS global object of env2 has '..2' properties. |
99 const v8::HeapGraphNode* a2_node = | 67 const v8::HeapGraphNode* a2_node = |
100 GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); | 68 GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); |
101 CHECK_NE(NULL, a2_node); | 69 CHECK_NE(NULL, a2_node); |
102 CHECK_NE( | 70 CHECK_NE( |
103 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); | 71 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); |
104 CHECK_NE( | 72 CHECK_NE( |
105 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); | 73 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); |
106 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); | 74 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); |
107 | |
108 NamedEntriesDetector det; | |
109 i_snapshot_env2->IterateEntries(&det); | |
110 CHECK(det.has_A2); | |
mnaganov (inactive)
2012/02/24 23:19:50
I'm against removing this code. It checks that A2,
alexeif
2012/02/27 11:57:25
Done.
| |
111 CHECK(det.has_B2); | |
112 CHECK(det.has_C2); | |
113 } | 75 } |
114 | 76 |
115 | 77 |
116 TEST(HeapSnapshotObjectSizes) { | 78 TEST(HeapSnapshotObjectSizes) { |
117 v8::HandleScope scope; | 79 v8::HandleScope scope; |
118 LocalContext env; | 80 LocalContext env; |
119 | 81 |
120 // -a-> X1 --a | 82 // -a-> X1 --a |
121 // x -b-> X2 <-| | 83 // x -b-> X2 <-| |
122 CompileRun( | 84 CompileRun( |
123 "function X(a, b) { this.a = a; this.b = b; }\n" | 85 "function X(a, b) { this.a = a; this.b = b; }\n" |
124 "x = new X(new X(), new X());\n" | 86 "x = new X(new X(), new X());\n" |
125 "(function() { x.a.a = x.b; })();"); | 87 "(function() { x.a.a = x.b; })();"); |
126 const v8::HeapSnapshot* snapshot = | 88 const v8::HeapSnapshot* snapshot = |
127 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); | 89 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); |
128 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 90 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
129 const v8::HeapGraphNode* x = | 91 const v8::HeapGraphNode* x = |
130 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); | 92 GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); |
131 CHECK_NE(NULL, x); | 93 CHECK_NE(NULL, x); |
132 const v8::HeapGraphNode* x1 = | 94 const v8::HeapGraphNode* x1 = |
133 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 95 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
134 CHECK_NE(NULL, x1); | 96 CHECK_NE(NULL, x1); |
135 const v8::HeapGraphNode* x2 = | 97 const v8::HeapGraphNode* x2 = |
136 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 98 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
137 CHECK_NE(NULL, x2); | 99 CHECK_NE(NULL, x2); |
138 | 100 |
139 // Test approximate sizes. | 101 // Test sizes. |
140 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(false)); | 102 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize()); |
141 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(false)); | 103 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize()); |
142 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(false)); | 104 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize()); |
143 // Test exact sizes. | |
144 CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(true)); | |
145 CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(true)); | |
146 CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(true)); | |
147 } | 105 } |
148 | 106 |
149 | 107 |
150 TEST(BoundFunctionInSnapshot) { | 108 TEST(BoundFunctionInSnapshot) { |
151 v8::HandleScope scope; | 109 v8::HandleScope scope; |
152 LocalContext env; | 110 LocalContext env; |
153 CompileRun( | 111 CompileRun( |
154 "function myFunction(a, b) { this.a = a; this.b = b; }\n" | 112 "function myFunction(a, b) { this.a = a; this.b = b; }\n" |
155 "function AAAAA() {}\n" | 113 "function AAAAA() {}\n" |
156 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); | 114 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); |
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1261 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); | 1219 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); |
1262 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1220 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
1263 CHECK_NE(NULL, global); | 1221 CHECK_NE(NULL, global); |
1264 const v8::HeapGraphNode* fun = | 1222 const v8::HeapGraphNode* fun = |
1265 GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); | 1223 GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); |
1266 CHECK(HasWeakEdge(fun)); | 1224 CHECK(HasWeakEdge(fun)); |
1267 const v8::HeapGraphNode* shared = | 1225 const v8::HeapGraphNode* shared = |
1268 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); | 1226 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); |
1269 CHECK(HasWeakEdge(shared)); | 1227 CHECK(HasWeakEdge(shared)); |
1270 } | 1228 } |
OLD | NEW |