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" |
11 #include "cctest.h" | 11 #include "cctest.h" |
12 #include "zone-inl.h" | 12 #include "zone-inl.h" |
13 #include "../include/v8-profiler.h" | 13 #include "../include/v8-profiler.h" |
14 | 14 |
15 namespace i = v8::internal; | 15 namespace i = v8::internal; |
16 using i::ClustersCoarser; | 16 using i::ClustersCoarser; |
17 using i::JSObjectsCluster; | 17 using i::JSObjectsCluster; |
18 using i::JSObjectsRetainerTree; | 18 using i::JSObjectsRetainerTree; |
19 using i::JSObjectsClusterTree; | 19 using i::JSObjectsClusterTree; |
20 using i::RetainerHeapProfile; | 20 using i::RetainerHeapProfile; |
21 | 21 |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile { | 25 class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile { |
26 public: | 26 public: |
27 ConstructorHeapProfileTestHelper() | 27 ConstructorHeapProfileTestHelper() |
28 : i::ConstructorHeapProfile(), | 28 : i::ConstructorHeapProfile(), |
29 f_name_(i::Factory::NewStringFromAscii(i::CStrVector("F"))), | 29 f_name_(FACTORY->NewStringFromAscii(i::CStrVector("F"))), |
30 f_count_(0) { | 30 f_count_(0) { |
31 } | 31 } |
32 | 32 |
33 void Call(const JSObjectsCluster& cluster, | 33 void Call(const JSObjectsCluster& cluster, |
34 const i::NumberAndSizeInfo& number_and_size) { | 34 const i::NumberAndSizeInfo& number_and_size) { |
35 if (f_name_->Equals(cluster.constructor())) { | 35 if (f_name_->Equals(cluster.constructor())) { |
36 CHECK_EQ(f_count_, 0); | 36 CHECK_EQ(f_count_, 0); |
37 f_count_ = number_and_size.number(); | 37 f_count_ = number_and_size.number(); |
38 CHECK_GT(f_count_, 0); | 38 CHECK_GT(f_count_, 0); |
39 } | 39 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 TEST(ClustersCoarserSimple) { | 139 TEST(ClustersCoarserSimple) { |
140 v8::HandleScope scope; | 140 v8::HandleScope scope; |
141 LocalContext env; | 141 LocalContext env; |
142 | 142 |
143 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); | 143 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); |
144 | 144 |
145 JSObjectsRetainerTree tree; | 145 JSObjectsRetainerTree tree; |
146 JSObjectsCluster function(i::Heap::function_class_symbol()); | 146 JSObjectsCluster function(HEAP->function_class_symbol()); |
147 JSObjectsCluster a(*i::Factory::NewStringFromAscii(i::CStrVector("A"))); | 147 JSObjectsCluster a(*FACTORY->NewStringFromAscii(i::CStrVector("A"))); |
148 JSObjectsCluster b(*i::Factory::NewStringFromAscii(i::CStrVector("B"))); | 148 JSObjectsCluster b(*FACTORY->NewStringFromAscii(i::CStrVector("B"))); |
149 | 149 |
150 // o1 <- Function | 150 // o1 <- Function |
151 JSObjectsCluster o1 = | 151 JSObjectsCluster o1 = |
152 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function); | 152 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function); |
153 // o2 <- Function | 153 // o2 <- Function |
154 JSObjectsCluster o2 = | 154 JSObjectsCluster o2 = |
155 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function); | 155 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function); |
156 // o3 <- A, B | 156 // o3 <- A, B |
157 JSObjectsCluster o3 = | 157 JSObjectsCluster o3 = |
158 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &a, &b); | 158 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &a, &b); |
159 // o4 <- B, A | 159 // o4 <- B, A |
160 JSObjectsCluster o4 = | 160 JSObjectsCluster o4 = |
161 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x400, &b, &a); | 161 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x400, &b, &a); |
162 // o5 <- A, B, Function | 162 // o5 <- A, B, Function |
163 JSObjectsCluster o5 = | 163 JSObjectsCluster o5 = |
164 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x500, | 164 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x500, |
165 &a, &b, &function); | 165 &a, &b, &function); |
166 | 166 |
167 ClustersCoarser coarser; | 167 ClustersCoarser coarser; |
168 coarser.Process(&tree); | 168 coarser.Process(&tree); |
169 | 169 |
170 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); | 170 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); |
171 CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4)); | 171 CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4)); |
172 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3)); | 172 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3)); |
173 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5)); | 173 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5)); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 TEST(ClustersCoarserMultipleConstructors) { | 177 TEST(ClustersCoarserMultipleConstructors) { |
178 v8::HandleScope scope; | 178 v8::HandleScope scope; |
179 LocalContext env; | 179 LocalContext env; |
180 | 180 |
181 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); | 181 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); |
182 | 182 |
183 JSObjectsRetainerTree tree; | 183 JSObjectsRetainerTree tree; |
184 JSObjectsCluster function(i::Heap::function_class_symbol()); | 184 JSObjectsCluster function(HEAP->function_class_symbol()); |
185 | 185 |
186 // o1 <- Function | 186 // o1 <- Function |
187 JSObjectsCluster o1 = | 187 JSObjectsCluster o1 = |
188 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function); | 188 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function); |
189 // a1 <- Function | 189 // a1 <- Function |
190 JSObjectsCluster a1 = | 190 JSObjectsCluster a1 = |
191 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x1000, &function); | 191 AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x1000, &function); |
192 // o2 <- Function | 192 // o2 <- Function |
193 JSObjectsCluster o2 = | 193 JSObjectsCluster o2 = |
194 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function); | 194 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function); |
195 // a2 <- Function | 195 // a2 <- Function |
196 JSObjectsCluster a2 = | 196 JSObjectsCluster a2 = |
197 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x2000, &function); | 197 AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x2000, &function); |
198 | 198 |
199 ClustersCoarser coarser; | 199 ClustersCoarser coarser; |
200 coarser.Process(&tree); | 200 coarser.Process(&tree); |
201 | 201 |
202 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); | 202 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); |
203 CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2)); | 203 CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2)); |
204 } | 204 } |
205 | 205 |
206 | 206 |
207 TEST(ClustersCoarserPathsTraversal) { | 207 TEST(ClustersCoarserPathsTraversal) { |
208 v8::HandleScope scope; | 208 v8::HandleScope scope; |
209 LocalContext env; | 209 LocalContext env; |
210 | 210 |
211 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); | 211 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); |
212 | 212 |
213 JSObjectsRetainerTree tree; | 213 JSObjectsRetainerTree tree; |
214 | 214 |
215 // On the following graph: | 215 // On the following graph: |
216 // | 216 // |
217 // p | 217 // p |
218 // <- o21 <- o11 <- | 218 // <- o21 <- o11 <- |
219 // q o | 219 // q o |
220 // <- o22 <- o12 <- | 220 // <- o22 <- o12 <- |
221 // r | 221 // r |
222 // | 222 // |
223 // we expect that coarser will deduce equivalences: p ~ q ~ r, | 223 // we expect that coarser will deduce equivalences: p ~ q ~ r, |
224 // o21 ~ o22, and o11 ~ o12. | 224 // o21 ~ o22, and o11 ~ o12. |
225 | 225 |
226 JSObjectsCluster o = | 226 JSObjectsCluster o = |
227 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100); | 227 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100); |
228 JSObjectsCluster o11 = | 228 JSObjectsCluster o11 = |
229 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x110, &o); | 229 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o); |
230 JSObjectsCluster o12 = | 230 JSObjectsCluster o12 = |
231 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x120, &o); | 231 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o); |
232 JSObjectsCluster o21 = | 232 JSObjectsCluster o21 = |
233 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x210, &o11); | 233 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x210, &o11); |
234 JSObjectsCluster o22 = | 234 JSObjectsCluster o22 = |
235 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x220, &o12); | 235 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x220, &o12); |
236 JSObjectsCluster p = | 236 JSObjectsCluster p = |
237 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o21); | 237 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o21); |
238 JSObjectsCluster q = | 238 JSObjectsCluster q = |
239 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o21, &o22); | 239 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o21, &o22); |
240 JSObjectsCluster r = | 240 JSObjectsCluster r = |
241 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o22); | 241 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o22); |
242 | 242 |
243 ClustersCoarser coarser; | 243 ClustersCoarser coarser; |
244 coarser.Process(&tree); | 244 coarser.Process(&tree); |
245 | 245 |
246 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o)); | 246 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o)); |
247 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11)); | 247 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11)); |
248 CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12)); | 248 CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12)); |
249 CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22)); | 249 CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22)); |
250 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21)); | 250 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21)); |
251 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p)); | 251 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p)); |
(...skipping 16 matching lines...) Expand all Loading... |
268 // | 268 // |
269 // p (self-referencing) | 269 // p (self-referencing) |
270 // <- o1 <- | 270 // <- o1 <- |
271 // q (self-referencing) o | 271 // q (self-referencing) o |
272 // <- o2 <- | 272 // <- o2 <- |
273 // r (self-referencing) | 273 // r (self-referencing) |
274 // | 274 // |
275 // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2; | 275 // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2; |
276 | 276 |
277 JSObjectsCluster o = | 277 JSObjectsCluster o = |
278 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100); | 278 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100); |
279 JSObjectsCluster o1 = | 279 JSObjectsCluster o1 = |
280 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x110, &o); | 280 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o); |
281 JSObjectsCluster o2 = | 281 JSObjectsCluster o2 = |
282 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x120, &o); | 282 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o); |
283 JSObjectsCluster p = | 283 JSObjectsCluster p = |
284 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x300, &o1); | 284 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o1); |
285 AddSelfReferenceToTree(&tree, &p); | 285 AddSelfReferenceToTree(&tree, &p); |
286 JSObjectsCluster q = | 286 JSObjectsCluster q = |
287 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x310, &o1, &o2); | 287 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o1, &o2); |
288 AddSelfReferenceToTree(&tree, &q); | 288 AddSelfReferenceToTree(&tree, &q); |
289 JSObjectsCluster r = | 289 JSObjectsCluster r = |
290 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x320, &o2); | 290 AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o2); |
291 AddSelfReferenceToTree(&tree, &r); | 291 AddSelfReferenceToTree(&tree, &r); |
292 | 292 |
293 ClustersCoarser coarser; | 293 ClustersCoarser coarser; |
294 coarser.Process(&tree); | 294 coarser.Process(&tree); |
295 | 295 |
296 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o)); | 296 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o)); |
297 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1)); | 297 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1)); |
298 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); | 298 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); |
299 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p)); | 299 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p)); |
300 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q)); | 300 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q)); |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 LocalContext env; | 723 LocalContext env; |
724 | 724 |
725 CompileRun( | 725 CompileRun( |
726 "function A() {}\n" | 726 "function A() {}\n" |
727 "function B(x) { this.x = x; }\n" | 727 "function B(x) { this.x = x; }\n" |
728 "var a = new A();\n" | 728 "var a = new A();\n" |
729 "var b = new B(a);"); | 729 "var b = new B(a);"); |
730 const v8::HeapSnapshot* snapshot1 = | 730 const v8::HeapSnapshot* snapshot1 = |
731 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1")); | 731 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1")); |
732 | 732 |
733 i::Heap::CollectAllGarbage(true); // Enforce compaction. | 733 HEAP->CollectAllGarbage(true); // Enforce compaction. |
734 | 734 |
735 const v8::HeapSnapshot* snapshot2 = | 735 const v8::HeapSnapshot* snapshot2 = |
736 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2")); | 736 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2")); |
737 | 737 |
738 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); | 738 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); |
739 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 739 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
740 CHECK_NE_UINT64_T(0, global1->GetId()); | 740 CHECK_NE_UINT64_T(0, global1->GetId()); |
741 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); | 741 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); |
742 const v8::HeapGraphNode* A1 = | 742 const v8::HeapGraphNode* A1 = |
743 GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); | 743 GetProperty(global1, v8::HeapGraphEdge::kProperty, "A"); |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 const v8::HeapGraphNode* n_CCC = GetNode( | 1389 const v8::HeapGraphNode* n_CCC = GetNode( |
1390 ccc, v8::HeapGraphNode::kString, "CCC"); | 1390 ccc, v8::HeapGraphNode::kString, "CCC"); |
1391 CHECK_NE(NULL, n_CCC); | 1391 CHECK_NE(NULL, n_CCC); |
1392 | 1392 |
1393 CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "Native")); | 1393 CHECK_EQ(aaa, GetProperty(n_AAA, v8::HeapGraphEdge::kInternal, "Native")); |
1394 CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "Native")); | 1394 CHECK_EQ(aaa, GetProperty(n_BBB, v8::HeapGraphEdge::kInternal, "Native")); |
1395 CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "Native")); | 1395 CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "Native")); |
1396 } | 1396 } |
1397 | 1397 |
1398 #endif // ENABLE_LOGGING_AND_PROFILING | 1398 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |