Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: test/cctest/test-heap-profiler.cc

Issue 3020002: Heap profiler: implement diffing of snapshots. (Closed)
Patch Set: Comments addressed Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/profile-generator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 private: 49 private:
50 i::Handle<i::String> f_name_; 50 i::Handle<i::String> f_name_;
51 int f_count_; 51 int f_count_;
52 }; 52 };
53 53
54 } // namespace 54 } // namespace
55 55
56 56
57 TEST(ConstructorProfile) { 57 TEST(ConstructorProfile) {
58 v8::HandleScope scope; 58 v8::HandleScope scope;
59 v8::Handle<v8::Context> env = v8::Context::New(); 59 LocalContext env;
60 env->Enter();
61 60
62 CompileAndRunScript( 61 CompileAndRunScript(
63 "function F() {} // A constructor\n" 62 "function F() {} // A constructor\n"
64 "var f1 = new F();\n" 63 "var f1 = new F();\n"
65 "var f2 = new F();\n"); 64 "var f2 = new F();\n");
66 65
67 ConstructorHeapProfileTestHelper cons_profile; 66 ConstructorHeapProfileTestHelper cons_profile;
68 i::AssertNoAllocation no_alloc; 67 i::AssertNoAllocation no_alloc;
69 i::HeapIterator iterator; 68 i::HeapIterator iterator;
70 for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) 69 for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 value.DebugPrint(&stream); 136 value.DebugPrint(&stream);
138 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s", 137 V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
139 expected_source, value_source, 138 expected_source, value_source,
140 *stream.ToCString()); 139 *stream.ToCString());
141 } 140 }
142 } 141 }
143 142
144 143
145 TEST(ClustersCoarserSimple) { 144 TEST(ClustersCoarserSimple) {
146 v8::HandleScope scope; 145 v8::HandleScope scope;
147 v8::Handle<v8::Context> env = v8::Context::New(); 146 LocalContext env;
148 env->Enter();
149 147
150 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); 148 i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
151 149
152 JSObjectsRetainerTree tree; 150 JSObjectsRetainerTree tree;
153 JSObjectsCluster function(i::Heap::function_class_symbol()); 151 JSObjectsCluster function(i::Heap::function_class_symbol());
154 JSObjectsCluster a(*i::Factory::NewStringFromAscii(i::CStrVector("A"))); 152 JSObjectsCluster a(*i::Factory::NewStringFromAscii(i::CStrVector("A")));
155 JSObjectsCluster b(*i::Factory::NewStringFromAscii(i::CStrVector("B"))); 153 JSObjectsCluster b(*i::Factory::NewStringFromAscii(i::CStrVector("B")));
156 154
157 // o1 <- Function 155 // o1 <- Function
158 JSObjectsCluster o1 = 156 JSObjectsCluster o1 =
(...skipping 17 matching lines...) Expand all
176 174
177 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); 175 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
178 CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4)); 176 CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4));
179 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3)); 177 CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3));
180 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5)); 178 CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5));
181 } 179 }
182 180
183 181
184 TEST(ClustersCoarserMultipleConstructors) { 182 TEST(ClustersCoarserMultipleConstructors) {
185 v8::HandleScope scope; 183 v8::HandleScope scope;
186 v8::Handle<v8::Context> env = v8::Context::New(); 184 LocalContext env;
187 env->Enter();
188 185
189 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); 186 i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
190 187
191 JSObjectsRetainerTree tree; 188 JSObjectsRetainerTree tree;
192 JSObjectsCluster function(i::Heap::function_class_symbol()); 189 JSObjectsCluster function(i::Heap::function_class_symbol());
193 190
194 // o1 <- Function 191 // o1 <- Function
195 JSObjectsCluster o1 = 192 JSObjectsCluster o1 =
196 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function); 193 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x100, &function);
197 // a1 <- Function 194 // a1 <- Function
198 JSObjectsCluster a1 = 195 JSObjectsCluster a1 =
199 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x1000, &function); 196 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x1000, &function);
200 // o2 <- Function 197 // o2 <- Function
201 JSObjectsCluster o2 = 198 JSObjectsCluster o2 =
202 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function); 199 AddHeapObjectToTree(&tree, i::Heap::Object_symbol(), 0x200, &function);
203 // a2 <- Function 200 // a2 <- Function
204 JSObjectsCluster a2 = 201 JSObjectsCluster a2 =
205 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x2000, &function); 202 AddHeapObjectToTree(&tree, i::Heap::Array_symbol(), 0x2000, &function);
206 203
207 ClustersCoarser coarser; 204 ClustersCoarser coarser;
208 coarser.Process(&tree); 205 coarser.Process(&tree);
209 206
210 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2)); 207 CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
211 CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2)); 208 CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2));
212 } 209 }
213 210
214 211
215 TEST(ClustersCoarserPathsTraversal) { 212 TEST(ClustersCoarserPathsTraversal) {
216 v8::HandleScope scope; 213 v8::HandleScope scope;
217 v8::Handle<v8::Context> env = v8::Context::New(); 214 LocalContext env;
218 env->Enter();
219 215
220 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); 216 i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
221 217
222 JSObjectsRetainerTree tree; 218 JSObjectsRetainerTree tree;
223 219
224 // On the following graph: 220 // On the following graph:
225 // 221 //
226 // p 222 // p
227 // <- o21 <- o11 <- 223 // <- o21 <- o11 <-
228 // q o 224 // q o
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p)); 256 CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
261 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q)); 257 CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
262 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r)); 258 CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
263 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p)); 259 CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
264 CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p)); 260 CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
265 } 261 }
266 262
267 263
268 TEST(ClustersCoarserSelf) { 264 TEST(ClustersCoarserSelf) {
269 v8::HandleScope scope; 265 v8::HandleScope scope;
270 v8::Handle<v8::Context> env = v8::Context::New(); 266 LocalContext env;
271 env->Enter();
272 267
273 i::ZoneScope zn_scope(i::DELETE_ON_EXIT); 268 i::ZoneScope zn_scope(i::DELETE_ON_EXIT);
274 269
275 JSObjectsRetainerTree tree; 270 JSObjectsRetainerTree tree;
276 271
277 // On the following graph: 272 // On the following graph:
278 // 273 //
279 // p (self-referencing) 274 // p (self-referencing)
280 // <- o1 <- 275 // <- o1 <-
281 // q (self-referencing) o 276 // q (self-referencing) o
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 i::StringStream stream_; 350 i::StringStream stream_;
356 i::SmartPointer<const char> stream_str_; 351 i::SmartPointer<const char> stream_str_;
357 i::List<const char*> lines_; 352 i::List<const char*> lines_;
358 }; 353 };
359 354
360 } // namespace 355 } // namespace
361 356
362 357
363 TEST(RetainerProfile) { 358 TEST(RetainerProfile) {
364 v8::HandleScope scope; 359 v8::HandleScope scope;
365 v8::Handle<v8::Context> env = v8::Context::New(); 360 LocalContext env;
366 env->Enter();
367 361
368 CompileAndRunScript( 362 CompileAndRunScript(
369 "function A() {}\n" 363 "function A() {}\n"
370 "function B(x) { this.x = x; }\n" 364 "function B(x) { this.x = x; }\n"
371 "function C(x) { this.x1 = x; this.x2 = x; }\n" 365 "function C(x) { this.x1 = x; this.x2 = x; }\n"
372 "var a = new A();\n" 366 "var a = new A();\n"
373 "var b1 = new B(a), b2 = new B(a);\n" 367 "var b1 = new B(a), b2 = new B(a);\n"
374 "var c = new C(a);"); 368 "var c = new C(a);");
375 369
376 RetainerHeapProfile ret_profile; 370 RetainerHeapProfile ret_profile;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 bool has_A2; 418 bool has_A2;
425 bool has_B2; 419 bool has_B2;
426 bool has_C2; 420 bool has_C2;
427 }; 421 };
428 422
429 } // namespace 423 } // namespace
430 424
431 425
432 static const v8::HeapGraphNode* GetGlobalObject( 426 static const v8::HeapGraphNode* GetGlobalObject(
433 const v8::HeapSnapshot* snapshot) { 427 const v8::HeapSnapshot* snapshot) {
434 CHECK_EQ(1, snapshot->GetHead()->GetChildrenCount()); 428 CHECK_EQ(1, snapshot->GetRoot()->GetChildrenCount());
435 return snapshot->GetHead()->GetChild(0)->GetToNode(); 429 return snapshot->GetRoot()->GetChild(0)->GetToNode();
436 } 430 }
437 431
438 432
439 static const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node, 433 static const v8::HeapGraphNode* GetProperty(const v8::HeapGraphNode* node,
440 v8::HeapGraphEdge::Type type, 434 v8::HeapGraphEdge::Type type,
441 const char* name) { 435 const char* name) {
442 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 436 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
443 const v8::HeapGraphEdge* prop = node->GetChild(i); 437 const v8::HeapGraphEdge* prop = node->GetChild(i);
444 v8::String::AsciiValue prop_name(prop->GetName()); 438 v8::String::AsciiValue prop_name(prop->GetName());
445 if (prop->GetType() == type && strcmp(name, *prop_name) == 0) 439 if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
446 return prop->GetToNode(); 440 return prop->GetToNode();
447 } 441 }
448 return NULL; 442 return NULL;
449 } 443 }
450 444
451 445
446 static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
447 v8::HeapGraphEdge::Type type,
448 const char* name) {
449 for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
450 const v8::HeapGraphEdge* prop = node->GetRetainer(i);
451 v8::String::AsciiValue prop_name(prop->GetName());
452 if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
453 return true;
454 }
455 return false;
456 }
457
458
452 static bool HasString(const v8::HeapGraphNode* node, const char* contents) { 459 static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
453 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 460 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
454 const v8::HeapGraphEdge* prop = node->GetChild(i); 461 const v8::HeapGraphEdge* prop = node->GetChild(i);
455 const v8::HeapGraphNode* node = prop->GetToNode(); 462 const v8::HeapGraphNode* node = prop->GetToNode();
456 if (node->GetType() == v8::HeapGraphNode::STRING) { 463 if (node->GetType() == v8::HeapGraphNode::STRING) {
457 v8::String::AsciiValue node_name(node->GetName()); 464 v8::String::AsciiValue node_name(node->GetName());
458 if (strcmp(contents, *node_name) == 0) return true; 465 if (strcmp(contents, *node_name) == 0) return true;
459 } 466 }
460 } 467 }
461 return false; 468 return false;
462 } 469 }
463 470
464 471
465 TEST(HeapSnapshot) { 472 TEST(HeapSnapshot) {
466 v8::HandleScope scope; 473 v8::HandleScope scope;
467
468 v8::Handle<v8::String> token1 = v8::String::New("token1"); 474 v8::Handle<v8::String> token1 = v8::String::New("token1");
469 v8::Handle<v8::Context> env1 = v8::Context::New(); 475 LocalContext env1;
470 env1->SetSecurityToken(token1); 476 env1->SetSecurityToken(token1);
471 env1->Enter();
472 477
473 CompileAndRunScript( 478 CompileAndRunScript(
474 "function A1() {}\n" 479 "function A1() {}\n"
475 "function B1(x) { this.x = x; }\n" 480 "function B1(x) { this.x = x; }\n"
476 "function C1(x) { this.x1 = x; this.x2 = x; }\n" 481 "function C1(x) { this.x1 = x; this.x2 = x; }\n"
477 "var a1 = new A1();\n" 482 "var a1 = new A1();\n"
478 "var b1_1 = new B1(a1), b1_2 = new B1(a1);\n" 483 "var b1_1 = new B1(a1), b1_2 = new B1(a1);\n"
479 "var c1 = new C1(a1);"); 484 "var c1 = new C1(a1);");
480 485
481 v8::Handle<v8::String> token2 = v8::String::New("token2"); 486 v8::Handle<v8::String> token2 = v8::String::New("token2");
482 v8::Handle<v8::Context> env2 = v8::Context::New(); 487 LocalContext env2;
483 env2->SetSecurityToken(token2); 488 env2->SetSecurityToken(token2);
484 env2->Enter();
485 489
486 CompileAndRunScript( 490 CompileAndRunScript(
487 "function A2() {}\n" 491 "function A2() {}\n"
488 "function B2(x) { return function() { return typeof x; }; }\n" 492 "function B2(x) { return function() { return typeof x; }; }\n"
489 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" 493 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n"
490 "var a2 = new A2();\n" 494 "var a2 = new A2();\n"
491 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" 495 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n"
492 "var c2 = new C2(a2);"); 496 "var c2 = new C2(a2);");
493 const v8::HeapSnapshot* snapshot_env2 = 497 const v8::HeapSnapshot* snapshot_env2 =
494 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2")); 498 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2"));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 CHECK(has_c2_x1_ref); 566 CHECK(has_c2_x1_ref);
563 CHECK(has_c2_x2_ref); 567 CHECK(has_c2_x2_ref);
564 CHECK(has_c2_1_ref); 568 CHECK(has_c2_1_ref);
565 CHECK(has_b2_1_x_ref); 569 CHECK(has_b2_1_x_ref);
566 CHECK(has_b2_2_x_ref); 570 CHECK(has_b2_2_x_ref);
567 } 571 }
568 572
569 573
570 TEST(HeapSnapshotCodeObjects) { 574 TEST(HeapSnapshotCodeObjects) {
571 v8::HandleScope scope; 575 v8::HandleScope scope;
572 v8::Handle<v8::Context> env = v8::Context::New(); 576 LocalContext env;
573 env->Enter();
574 577
575 CompileAndRunScript( 578 CompileAndRunScript(
576 "function lazy(x) { return x - 1; }\n" 579 "function lazy(x) { return x - 1; }\n"
577 "function compiled(x) { return x + 1; }\n" 580 "function compiled(x) { return x + 1; }\n"
578 "compiled(1)"); 581 "compiled(1)");
579 const v8::HeapSnapshot* snapshot = 582 const v8::HeapSnapshot* snapshot =
580 v8::HeapProfiler::TakeSnapshot(v8::String::New("code")); 583 v8::HeapProfiler::TakeSnapshot(v8::String::New("code"));
581 584
582 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 585 const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
583 const v8::HeapGraphNode* compiled = 586 const v8::HeapGraphNode* compiled =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (HasString(node, "x")) { 621 if (HasString(node, "x")) {
619 lazy_references_x = true; 622 lazy_references_x = true;
620 break; 623 break;
621 } 624 }
622 } 625 }
623 } 626 }
624 CHECK(compiled_references_x); 627 CHECK(compiled_references_x);
625 CHECK(!lazy_references_x); 628 CHECK(!lazy_references_x);
626 } 629 }
627 630
631
632 TEST(HeapEntryIdsAndGC) {
633 v8::HandleScope scope;
634 LocalContext env;
635
636 CompileAndRunScript(
637 "function A() {}\n"
638 "function B(x) { this.x = x; }\n"
639 "var a = new A();\n"
640 "var b = new B(a);");
641 const v8::HeapSnapshot* snapshot1 =
642 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
643
644 i::Heap::CollectAllGarbage(true); // Enforce compaction.
645
646 const v8::HeapSnapshot* snapshot2 =
647 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
648
649 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1);
650 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2);
651 CHECK_NE(0, global1->GetId());
652 CHECK_EQ(global1->GetId(), global2->GetId());
653 const v8::HeapGraphNode* A1 =
654 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "A");
655 const v8::HeapGraphNode* A2 =
656 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "A");
657 CHECK_NE(0, A1->GetId());
658 CHECK_EQ(A1->GetId(), A2->GetId());
659 const v8::HeapGraphNode* B1 =
660 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "B");
661 const v8::HeapGraphNode* B2 =
662 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "B");
663 CHECK_NE(0, B1->GetId());
664 CHECK_EQ(B1->GetId(), B2->GetId());
665 const v8::HeapGraphNode* a1 =
666 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "a");
667 const v8::HeapGraphNode* a2 =
668 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "a");
669 CHECK_NE(0, a1->GetId());
670 CHECK_EQ(a1->GetId(), a2->GetId());
671 const v8::HeapGraphNode* b1 =
672 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "b");
673 const v8::HeapGraphNode* b2 =
674 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "b");
675 CHECK_NE(0, b1->GetId());
676 CHECK_EQ(b1->GetId(), b2->GetId());
677 }
678
679
680 TEST(HeapSnapshotsDiff) {
681 v8::HandleScope scope;
682 LocalContext env;
683
684 CompileAndRunScript(
685 "function A() {}\n"
686 "function B(x) { this.x = x; }\n"
687 "var a = new A();\n"
688 "var b = new B(a);");
689 const v8::HeapSnapshot* snapshot1 =
690 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
691
692 CompileAndRunScript(
693 "delete a;\n"
694 "b.x = null;\n"
695 "var a = new A();\n"
696 "var b2 = new B(a);");
697 const v8::HeapSnapshot* snapshot2 =
698 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
699
700 const v8::HeapSnapshotsDiff* diff = snapshot1->CompareWith(snapshot2);
701
702 // Verify additions: ensure that addition of A and B was detected.
703 const v8::HeapGraphNode* additions_root = diff->GetAdditionsRoot();
704 bool found_A = false, found_B = false;
705 uint64_t s1_A_id = 0;
706 for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) {
707 const v8::HeapGraphEdge* prop = additions_root->GetChild(i);
708 const v8::HeapGraphNode* node = prop->GetToNode();
709 if (node->GetType() == v8::HeapGraphNode::OBJECT) {
710 v8::String::AsciiValue node_name(node->GetName());
711 if (strcmp(*node_name, "A") == 0) {
712 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a"));
713 CHECK(!found_A);
714 found_A = true;
715 s1_A_id = node->GetId();
716 } else if (strcmp(*node_name, "B") == 0) {
717 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "b2"));
718 CHECK(!found_B);
719 found_B = true;
720 }
721 }
722 }
723 CHECK(found_A);
724 CHECK(found_B);
725
726 // Verify deletions: ensure that deletion of A was detected.
727 const v8::HeapGraphNode* deletions_root = diff->GetDeletionsRoot();
728 bool found_A_del = false;
729 uint64_t s2_A_id = 0;
730 for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) {
731 const v8::HeapGraphEdge* prop = deletions_root->GetChild(i);
732 const v8::HeapGraphNode* node = prop->GetToNode();
733 if (node->GetType() == v8::HeapGraphNode::OBJECT) {
734 v8::String::AsciiValue node_name(node->GetName());
735 if (strcmp(*node_name, "A") == 0) {
736 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a"));
737 CHECK(!found_A_del);
738 found_A_del = true;
739 s2_A_id = node->GetId();
740 }
741 }
742 }
743 CHECK(found_A_del);
744 CHECK_NE(0, s1_A_id);
745 CHECK(s1_A_id != s2_A_id);
746 }
747
628 #endif // ENABLE_LOGGING_AND_PROFILING 748 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698