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

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

Issue 3060008: Heap profiler: reduce heap snapshots size. (Closed)
Patch Set: Comments addressed Created 10 years, 4 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/version.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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 389
390 namespace { 390 namespace {
391 391
392 class NamedEntriesDetector { 392 class NamedEntriesDetector {
393 public: 393 public:
394 NamedEntriesDetector() 394 NamedEntriesDetector()
395 : has_A1(false), has_B1(false), has_C1(false), 395 : has_A1(false), has_B1(false), has_C1(false),
396 has_A2(false), has_B2(false), has_C2(false) { 396 has_A2(false), has_B2(false), has_C2(false) {
397 } 397 }
398 398
399 void Apply(i::HeapEntry* entry) { 399 void Apply(i::HeapEntry** entry_ptr) {
400 const char* node_name = entry->name(); 400 if (IsReachableNodeWithName(*entry_ptr, "A1")) has_A1 = true;
401 if (strcmp("A1", node_name) == 0 401 if (IsReachableNodeWithName(*entry_ptr, "B1")) has_B1 = true;
402 && entry->GetRetainingPaths()->length() > 0) has_A1 = true; 402 if (IsReachableNodeWithName(*entry_ptr, "C1")) has_C1 = true;
403 if (strcmp("B1", node_name) == 0 403 if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true;
404 && entry->GetRetainingPaths()->length() > 0) has_B1 = true; 404 if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true;
405 if (strcmp("C1", node_name) == 0 405 if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true;
406 && entry->GetRetainingPaths()->length() > 0) has_C1 = true; 406 }
407 if (strcmp("A2", node_name) == 0 407
408 && entry->GetRetainingPaths()->length() > 0) has_A2 = true; 408 static bool IsReachableNodeWithName(i::HeapEntry* entry, const char* name) {
409 if (strcmp("B2", node_name) == 0 409 return strcmp(name, entry->name()) == 0 && entry->painted_reachable();
410 && entry->GetRetainingPaths()->length() > 0) has_B2 = true;
411 if (strcmp("C2", node_name) == 0
412 && entry->GetRetainingPaths()->length() > 0) has_C2 = true;
413 } 410 }
414 411
415 bool has_A1; 412 bool has_A1;
416 bool has_B1; 413 bool has_B1;
417 bool has_C1; 414 bool has_C1;
418 bool has_A2; 415 bool has_A2;
419 bool has_B2; 416 bool has_B2;
420 bool has_C2; 417 bool has_C2;
421 }; 418 };
422 419
(...skipping 30 matching lines...) Expand all
453 return true; 450 return true;
454 } 451 }
455 return false; 452 return false;
456 } 453 }
457 454
458 455
459 static bool HasString(const v8::HeapGraphNode* node, const char* contents) { 456 static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
460 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 457 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
461 const v8::HeapGraphEdge* prop = node->GetChild(i); 458 const v8::HeapGraphEdge* prop = node->GetChild(i);
462 const v8::HeapGraphNode* node = prop->GetToNode(); 459 const v8::HeapGraphNode* node = prop->GetToNode();
463 if (node->GetType() == v8::HeapGraphNode::STRING) { 460 if (node->GetType() == v8::HeapGraphNode::kString) {
464 v8::String::AsciiValue node_name(node->GetName()); 461 v8::String::AsciiValue node_name(node->GetName());
465 if (strcmp(contents, *node_name) == 0) return true; 462 if (strcmp(contents, *node_name) == 0) return true;
466 } 463 }
467 } 464 }
468 return false; 465 return false;
469 } 466 }
470 467
471 468
472 TEST(HeapSnapshot) { 469 TEST(HeapSnapshot) {
473 v8::HandleScope scope; 470 v8::HandleScope scope;
(...skipping 15 matching lines...) Expand all
489 486
490 CompileAndRunScript( 487 CompileAndRunScript(
491 "function A2() {}\n" 488 "function A2() {}\n"
492 "function B2(x) { return function() { return typeof x; }; }\n" 489 "function B2(x) { return function() { return typeof x; }; }\n"
493 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" 490 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n"
494 "var a2 = new A2();\n" 491 "var a2 = new A2();\n"
495 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" 492 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n"
496 "var c2 = new C2(a2);"); 493 "var c2 = new C2(a2);");
497 const v8::HeapSnapshot* snapshot_env2 = 494 const v8::HeapSnapshot* snapshot_env2 =
498 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2")); 495 v8::HeapProfiler::TakeSnapshot(v8::String::New("env2"));
496 i::HeapSnapshot* i_snapshot_env2 =
497 const_cast<i::HeapSnapshot*>(
498 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
499 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); 499 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2);
500 // Paint all nodes reachable from global object.
501 i_snapshot_env2->ClearPaint();
502 const_cast<i::HeapEntry*>(
503 reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable();
500 504
501 // Verify, that JS global object of env2 doesn't have '..1' 505 // Verify, that JS global object of env2 doesn't have '..1'
502 // properties, but has '..2' properties. 506 // properties, but has '..2' properties.
503 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a1")); 507 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a1"));
504 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_1")); 508 CHECK_EQ(
505 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_2")); 509 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_1"));
506 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c1")); 510 CHECK_EQ(
511 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_2"));
512 CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c1"));
507 const v8::HeapGraphNode* a2_node = 513 const v8::HeapGraphNode* a2_node =
508 GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a2"); 514 GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
509 CHECK_NE(NULL, a2_node); 515 CHECK_NE(NULL, a2_node);
510 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_1")); 516 CHECK_NE(
511 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_2")); 517 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1"));
512 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c2")); 518 CHECK_NE(
519 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2"));
520 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2"));
513 521
514 // Verify that anything related to '[ABC]1' is not reachable. 522 // Verify that anything related to '[ABC]1' is not reachable.
515 NamedEntriesDetector det; 523 NamedEntriesDetector det;
516 i::HeapSnapshot* i_snapshot_env2 =
517 const_cast<i::HeapSnapshot*>(
518 reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
519 i_snapshot_env2->IterateEntries(&det); 524 i_snapshot_env2->IterateEntries(&det);
520 CHECK(!det.has_A1); 525 CHECK(!det.has_A1);
521 CHECK(!det.has_B1); 526 CHECK(!det.has_B1);
522 CHECK(!det.has_C1); 527 CHECK(!det.has_C1);
523 CHECK(det.has_A2); 528 CHECK(det.has_A2);
524 CHECK(det.has_B2); 529 CHECK(det.has_B2);
525 CHECK(det.has_C2); 530 CHECK(det.has_C2);
526 531
527 // Verify 'a2' object retainers. They are: 532 // Verify 'a2' object retainers. They are:
528 // - (global object).a2 533 // - (global object).a2
529 // - c2.x1, c2.x2, c2[1] 534 // - c2.x1, c2.x2, c2[1]
530 // - b2_1 and b2_2 closures: via 'x' variable 535 // - b2_1 and b2_2 closures: via 'x' variable
531 CHECK_EQ(6, a2_node->GetRetainingPathsCount()); 536 CHECK_EQ(6, a2_node->GetRetainingPathsCount());
532 bool has_global_obj_a2_ref = false; 537 bool has_global_obj_a2_ref = false;
533 bool has_c2_x1_ref = false, has_c2_x2_ref = false, has_c2_1_ref = false; 538 bool has_c2_x1_ref = false, has_c2_x2_ref = false, has_c2_1_ref = false;
534 bool has_b2_1_x_ref = false, has_b2_2_x_ref = false; 539 bool has_b2_1_x_ref = false, has_b2_2_x_ref = false;
535 for (int i = 0; i < a2_node->GetRetainingPathsCount(); ++i) { 540 for (int i = 0; i < a2_node->GetRetainingPathsCount(); ++i) {
536 const v8::HeapGraphPath* path = a2_node->GetRetainingPath(i); 541 const v8::HeapGraphPath* path = a2_node->GetRetainingPath(i);
537 const int edges_count = path->GetEdgesCount(); 542 const int edges_count = path->GetEdgesCount();
538 CHECK_GT(edges_count, 0); 543 CHECK_GT(edges_count, 0);
539 const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1); 544 const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1);
540 v8::String::AsciiValue last_edge_name(last_edge->GetName()); 545 v8::String::AsciiValue last_edge_name(last_edge->GetName());
541 if (strcmp("a2", *last_edge_name) == 0 546 if (strcmp("a2", *last_edge_name) == 0
542 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY) { 547 && last_edge->GetType() == v8::HeapGraphEdge::kProperty) {
543 has_global_obj_a2_ref = true; 548 has_global_obj_a2_ref = true;
544 continue; 549 continue;
545 } 550 }
546 CHECK_GT(edges_count, 1); 551 CHECK_GT(edges_count, 1);
547 const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2); 552 const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2);
548 v8::String::AsciiValue prev_edge_name(prev_edge->GetName()); 553 v8::String::AsciiValue prev_edge_name(prev_edge->GetName());
549 if (strcmp("x1", *last_edge_name) == 0 554 if (strcmp("x1", *last_edge_name) == 0
550 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY 555 && last_edge->GetType() == v8::HeapGraphEdge::kProperty
551 && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true; 556 && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true;
552 if (strcmp("x2", *last_edge_name) == 0 557 if (strcmp("x2", *last_edge_name) == 0
553 && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY 558 && last_edge->GetType() == v8::HeapGraphEdge::kProperty
554 && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true; 559 && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true;
555 if (strcmp("1", *last_edge_name) == 0 560 if (strcmp("1", *last_edge_name) == 0
556 && last_edge->GetType() == v8::HeapGraphEdge::ELEMENT 561 && last_edge->GetType() == v8::HeapGraphEdge::kElement
557 && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true; 562 && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true;
558 if (strcmp("x", *last_edge_name) == 0 563 if (strcmp("x", *last_edge_name) == 0
559 && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE 564 && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
560 && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true; 565 && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true;
561 if (strcmp("x", *last_edge_name) == 0 566 if (strcmp("x", *last_edge_name) == 0
562 && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE 567 && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
563 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true; 568 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
564 } 569 }
565 CHECK(has_global_obj_a2_ref); 570 CHECK(has_global_obj_a2_ref);
566 CHECK(has_c2_x1_ref); 571 CHECK(has_c2_x1_ref);
567 CHECK(has_c2_x2_ref); 572 CHECK(has_c2_x2_ref);
568 CHECK(has_c2_1_ref); 573 CHECK(has_c2_1_ref);
569 CHECK(has_b2_1_x_ref); 574 CHECK(has_b2_1_x_ref);
570 CHECK(has_b2_2_x_ref); 575 CHECK(has_b2_2_x_ref);
571 } 576 }
572 577
573 578
579 TEST(HeapSnapshotObjectSizes) {
580 v8::HandleScope scope;
581 LocalContext env;
582
583 // -a-> X1 --a
584 // x -b-> X2 <-|
585 CompileAndRunScript(
586 "function X(a, b) { this.a = a; this.b = b; }\n"
587 "x = new X(new X(), new X());\n"
588 "x.a.a = x.b;");
589 const v8::HeapSnapshot* snapshot =
590 v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes"));
591 const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
592 const v8::HeapGraphNode* x =
593 GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
594 CHECK_NE(NULL, x);
595 const v8::HeapGraphNode* x_prototype =
596 GetProperty(x, v8::HeapGraphEdge::kProperty, "prototype");
597 CHECK_NE(NULL, x_prototype);
598 const v8::HeapGraphNode* x1 =
599 GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
600 CHECK_NE(NULL, x1);
601 const v8::HeapGraphNode* x2 =
602 GetProperty(x, v8::HeapGraphEdge::kProperty, "b");
603 CHECK_NE(NULL, x2);
604 CHECK_EQ(
605 x->GetSelfSize() * 3,
606 x->GetReachableSize() - x_prototype->GetReachableSize());
607 CHECK_EQ(
608 x->GetSelfSize() * 3 + x_prototype->GetSelfSize(), x->GetRetainedSize());
609 CHECK_EQ(
610 x1->GetSelfSize() * 2,
611 x1->GetReachableSize() - x_prototype->GetReachableSize());
612 CHECK_EQ(
613 x1->GetSelfSize(), x1->GetRetainedSize());
614 CHECK_EQ(
615 x2->GetSelfSize(),
616 x2->GetReachableSize() - x_prototype->GetReachableSize());
617 CHECK_EQ(
618 x2->GetSelfSize(), x2->GetRetainedSize());
619 }
620
621
622 TEST(HeapSnapshotEntryChildren) {
623 v8::HandleScope scope;
624 LocalContext env;
625
626 CompileAndRunScript(
627 "function A() { }\n"
628 "a = new A;");
629 const v8::HeapSnapshot* snapshot =
630 v8::HeapProfiler::TakeSnapshot(v8::String::New("children"));
631 const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
632 for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) {
633 const v8::HeapGraphEdge* prop = global->GetChild(i);
634 CHECK_EQ(global, prop->GetFromNode());
635 }
636 const v8::HeapGraphNode* a =
637 GetProperty(global, v8::HeapGraphEdge::kProperty, "a");
638 CHECK_NE(NULL, a);
639 for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) {
640 const v8::HeapGraphEdge* prop = a->GetChild(i);
641 CHECK_EQ(a, prop->GetFromNode());
642 }
643 }
644
645
574 TEST(HeapSnapshotCodeObjects) { 646 TEST(HeapSnapshotCodeObjects) {
575 v8::HandleScope scope; 647 v8::HandleScope scope;
576 LocalContext env; 648 LocalContext env;
577 649
578 CompileAndRunScript( 650 CompileAndRunScript(
579 "function lazy(x) { return x - 1; }\n" 651 "function lazy(x) { return x - 1; }\n"
580 "function compiled(x) { return x + 1; }\n" 652 "function compiled(x) { return x + 1; }\n"
581 "compiled(1)"); 653 "compiled(1)");
582 const v8::HeapSnapshot* snapshot = 654 const v8::HeapSnapshot* snapshot =
583 v8::HeapProfiler::TakeSnapshot(v8::String::New("code")); 655 v8::HeapProfiler::TakeSnapshot(v8::String::New("code"));
584 656
585 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); 657 const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
586 const v8::HeapGraphNode* compiled = 658 const v8::HeapGraphNode* compiled =
587 GetProperty(global, v8::HeapGraphEdge::PROPERTY, "compiled"); 659 GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled");
588 CHECK_NE(NULL, compiled); 660 CHECK_NE(NULL, compiled);
589 CHECK_EQ(v8::HeapGraphNode::CLOSURE, compiled->GetType()); 661 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType());
590 const v8::HeapGraphNode* lazy = 662 const v8::HeapGraphNode* lazy =
591 GetProperty(global, v8::HeapGraphEdge::PROPERTY, "lazy"); 663 GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
592 CHECK_NE(NULL, lazy); 664 CHECK_NE(NULL, lazy);
593 CHECK_EQ(v8::HeapGraphNode::CLOSURE, lazy->GetType()); 665 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
594 666
595 // Find references to code. 667 // Find references to code.
596 const v8::HeapGraphNode* compiled_code = 668 const v8::HeapGraphNode* compiled_code =
597 GetProperty(compiled, v8::HeapGraphEdge::INTERNAL, "code"); 669 GetProperty(compiled, v8::HeapGraphEdge::kInternal, "code");
598 CHECK_NE(NULL, compiled_code); 670 CHECK_NE(NULL, compiled_code);
599 const v8::HeapGraphNode* lazy_code = 671 const v8::HeapGraphNode* lazy_code =
600 GetProperty(lazy, v8::HeapGraphEdge::INTERNAL, "code"); 672 GetProperty(lazy, v8::HeapGraphEdge::kInternal, "code");
601 CHECK_NE(NULL, lazy_code); 673 CHECK_NE(NULL, lazy_code);
602 674
603 // Verify that non-compiled code doesn't contain references to "x" 675 // Verify that non-compiled code doesn't contain references to "x"
604 // literal, while compiled code does. The scope info is stored in FixedArray 676 // literal, while compiled code does. The scope info is stored in FixedArray
605 // objects attached to the SharedFunctionInfo. 677 // objects attached to the SharedFunctionInfo.
606 bool compiled_references_x = false, lazy_references_x = false; 678 bool compiled_references_x = false, lazy_references_x = false;
607 for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) { 679 for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) {
608 const v8::HeapGraphEdge* prop = compiled_code->GetChild(i); 680 const v8::HeapGraphEdge* prop = compiled_code->GetChild(i);
609 const v8::HeapGraphNode* node = prop->GetToNode(); 681 const v8::HeapGraphNode* node = prop->GetToNode();
610 if (node->GetType() == v8::HeapGraphNode::ARRAY) { 682 if (node->GetType() == v8::HeapGraphNode::kArray) {
611 if (HasString(node, "x")) { 683 if (HasString(node, "x")) {
612 compiled_references_x = true; 684 compiled_references_x = true;
613 break; 685 break;
614 } 686 }
615 } 687 }
616 } 688 }
617 for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) { 689 for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) {
618 const v8::HeapGraphEdge* prop = lazy_code->GetChild(i); 690 const v8::HeapGraphEdge* prop = lazy_code->GetChild(i);
619 const v8::HeapGraphNode* node = prop->GetToNode(); 691 const v8::HeapGraphNode* node = prop->GetToNode();
620 if (node->GetType() == v8::HeapGraphNode::ARRAY) { 692 if (node->GetType() == v8::HeapGraphNode::kArray) {
621 if (HasString(node, "x")) { 693 if (HasString(node, "x")) {
622 lazy_references_x = true; 694 lazy_references_x = true;
623 break; 695 break;
624 } 696 }
625 } 697 }
626 } 698 }
627 CHECK(compiled_references_x); 699 CHECK(compiled_references_x);
628 CHECK(!lazy_references_x); 700 CHECK(!lazy_references_x);
629 } 701 }
630 702
631 703
632 // Trying to introduce a check helper for uint64_t causes many 704 // Trying to introduce a check helper for uint64_t causes many
633 // overloading ambiguities, so it seems easier just to cast 705 // overloading ambiguities, so it seems easier just to cast
634 // them to a signed type. 706 // them to a signed type.
635 #define CHECK_EQ_UINT64_T(a, b) \ 707 #define CHECK_EQ_UINT64_T(a, b) \
636 CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b)) 708 CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b))
637 #define CHECK_NE_UINT64_T(a, b) do \ 709 #define CHECK_NE_UINT64_T(a, b) \
638 { \ 710 CHECK((a) != (b)) // NOLINT
639 bool ne = a != b; \
640 CHECK(ne); \
641 } while (false)
642 711
643 TEST(HeapEntryIdsAndGC) { 712 TEST(HeapEntryIdsAndGC) {
644 v8::HandleScope scope; 713 v8::HandleScope scope;
645 LocalContext env; 714 LocalContext env;
646 715
647 CompileAndRunScript( 716 CompileAndRunScript(
648 "function A() {}\n" 717 "function A() {}\n"
649 "function B(x) { this.x = x; }\n" 718 "function B(x) { this.x = x; }\n"
650 "var a = new A();\n" 719 "var a = new A();\n"
651 "var b = new B(a);"); 720 "var b = new B(a);");
652 const v8::HeapSnapshot* snapshot1 = 721 const v8::HeapSnapshot* snapshot1 =
653 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1")); 722 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
654 723
655 i::Heap::CollectAllGarbage(true); // Enforce compaction. 724 i::Heap::CollectAllGarbage(true); // Enforce compaction.
656 725
657 const v8::HeapSnapshot* snapshot2 = 726 const v8::HeapSnapshot* snapshot2 =
658 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2")); 727 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
659 728
660 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); 729 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1);
661 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); 730 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2);
662 CHECK_NE_UINT64_T(0, global1->GetId()); 731 CHECK_NE_UINT64_T(0, global1->GetId());
663 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId()); 732 CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId());
664 const v8::HeapGraphNode* A1 = 733 const v8::HeapGraphNode* A1 =
665 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "A"); 734 GetProperty(global1, v8::HeapGraphEdge::kProperty, "A");
735 CHECK_NE(NULL, A1);
666 const v8::HeapGraphNode* A2 = 736 const v8::HeapGraphNode* A2 =
667 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "A"); 737 GetProperty(global2, v8::HeapGraphEdge::kProperty, "A");
738 CHECK_NE(NULL, A2);
668 CHECK_NE_UINT64_T(0, A1->GetId()); 739 CHECK_NE_UINT64_T(0, A1->GetId());
669 CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId()); 740 CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId());
670 const v8::HeapGraphNode* B1 = 741 const v8::HeapGraphNode* B1 =
671 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "B"); 742 GetProperty(global1, v8::HeapGraphEdge::kProperty, "B");
743 CHECK_NE(NULL, B1);
672 const v8::HeapGraphNode* B2 = 744 const v8::HeapGraphNode* B2 =
673 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "B"); 745 GetProperty(global2, v8::HeapGraphEdge::kProperty, "B");
746 CHECK_NE(NULL, B2);
674 CHECK_NE_UINT64_T(0, B1->GetId()); 747 CHECK_NE_UINT64_T(0, B1->GetId());
675 CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId()); 748 CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId());
676 const v8::HeapGraphNode* a1 = 749 const v8::HeapGraphNode* a1 =
677 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "a"); 750 GetProperty(global1, v8::HeapGraphEdge::kProperty, "a");
751 CHECK_NE(NULL, a1);
678 const v8::HeapGraphNode* a2 = 752 const v8::HeapGraphNode* a2 =
679 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "a"); 753 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a");
754 CHECK_NE(NULL, a2);
680 CHECK_NE_UINT64_T(0, a1->GetId()); 755 CHECK_NE_UINT64_T(0, a1->GetId());
681 CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId()); 756 CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId());
682 const v8::HeapGraphNode* b1 = 757 const v8::HeapGraphNode* b1 =
683 GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "b"); 758 GetProperty(global1, v8::HeapGraphEdge::kProperty, "b");
759 CHECK_NE(NULL, b1);
684 const v8::HeapGraphNode* b2 = 760 const v8::HeapGraphNode* b2 =
685 GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "b"); 761 GetProperty(global2, v8::HeapGraphEdge::kProperty, "b");
762 CHECK_NE(NULL, b2);
686 CHECK_NE_UINT64_T(0, b1->GetId()); 763 CHECK_NE_UINT64_T(0, b1->GetId());
687 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); 764 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId());
688 } 765 }
689 766
690 767
691 TEST(HeapSnapshotsDiff) { 768 TEST(HeapSnapshotsDiff) {
692 v8::HandleScope scope; 769 v8::HandleScope scope;
693 LocalContext env; 770 LocalContext env;
694 771
695 CompileAndRunScript( 772 CompileAndRunScript(
(...skipping 14 matching lines...) Expand all
710 787
711 const v8::HeapSnapshotsDiff* diff = snapshot1->CompareWith(snapshot2); 788 const v8::HeapSnapshotsDiff* diff = snapshot1->CompareWith(snapshot2);
712 789
713 // Verify additions: ensure that addition of A and B was detected. 790 // Verify additions: ensure that addition of A and B was detected.
714 const v8::HeapGraphNode* additions_root = diff->GetAdditionsRoot(); 791 const v8::HeapGraphNode* additions_root = diff->GetAdditionsRoot();
715 bool found_A = false, found_B = false; 792 bool found_A = false, found_B = false;
716 uint64_t s1_A_id = 0; 793 uint64_t s1_A_id = 0;
717 for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) { 794 for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) {
718 const v8::HeapGraphEdge* prop = additions_root->GetChild(i); 795 const v8::HeapGraphEdge* prop = additions_root->GetChild(i);
719 const v8::HeapGraphNode* node = prop->GetToNode(); 796 const v8::HeapGraphNode* node = prop->GetToNode();
720 if (node->GetType() == v8::HeapGraphNode::OBJECT) { 797 if (node->GetType() == v8::HeapGraphNode::kObject) {
721 v8::String::AsciiValue node_name(node->GetName()); 798 v8::String::AsciiValue node_name(node->GetName());
722 if (strcmp(*node_name, "A") == 0) { 799 if (strcmp(*node_name, "A") == 0) {
723 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a")); 800 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
724 CHECK(!found_A); 801 CHECK(!found_A);
725 found_A = true; 802 found_A = true;
726 s1_A_id = node->GetId(); 803 s1_A_id = node->GetId();
727 } else if (strcmp(*node_name, "B") == 0) { 804 } else if (strcmp(*node_name, "B") == 0) {
728 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "b2")); 805 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "b2"));
729 CHECK(!found_B); 806 CHECK(!found_B);
730 found_B = true; 807 found_B = true;
731 } 808 }
732 } 809 }
733 } 810 }
734 CHECK(found_A); 811 CHECK(found_A);
735 CHECK(found_B); 812 CHECK(found_B);
736 813
737 // Verify deletions: ensure that deletion of A was detected. 814 // Verify deletions: ensure that deletion of A was detected.
738 const v8::HeapGraphNode* deletions_root = diff->GetDeletionsRoot(); 815 const v8::HeapGraphNode* deletions_root = diff->GetDeletionsRoot();
739 bool found_A_del = false; 816 bool found_A_del = false;
740 uint64_t s2_A_id = 0; 817 uint64_t s2_A_id = 0;
741 for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) { 818 for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) {
742 const v8::HeapGraphEdge* prop = deletions_root->GetChild(i); 819 const v8::HeapGraphEdge* prop = deletions_root->GetChild(i);
743 const v8::HeapGraphNode* node = prop->GetToNode(); 820 const v8::HeapGraphNode* node = prop->GetToNode();
744 if (node->GetType() == v8::HeapGraphNode::OBJECT) { 821 if (node->GetType() == v8::HeapGraphNode::kObject) {
745 v8::String::AsciiValue node_name(node->GetName()); 822 v8::String::AsciiValue node_name(node->GetName());
746 if (strcmp(*node_name, "A") == 0) { 823 if (strcmp(*node_name, "A") == 0) {
747 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a")); 824 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
748 CHECK(!found_A_del); 825 CHECK(!found_A_del);
749 found_A_del = true; 826 found_A_del = true;
750 s2_A_id = node->GetId(); 827 s2_A_id = node->GetId();
751 } 828 }
752 } 829 }
753 } 830 }
754 CHECK(found_A_del); 831 CHECK(found_A_del);
755 CHECK_NE_UINT64_T(0, s1_A_id); 832 CHECK_NE_UINT64_T(0, s1_A_id);
756 CHECK(s1_A_id != s2_A_id); 833 CHECK(s1_A_id != s2_A_id);
757 } 834 }
758 835
759 #endif // ENABLE_LOGGING_AND_PROFILING 836 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/version.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698