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

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

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-assembler-mips.cc ('k') | test/cctest/test-parsing.cc » ('j') | 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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 426 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
427 const v8::HeapGraphEdge* prop = node->GetChild(i); 427 const v8::HeapGraphEdge* prop = node->GetChild(i);
428 v8::String::AsciiValue prop_name(prop->GetName()); 428 v8::String::AsciiValue prop_name(prop->GetName());
429 if (prop->GetType() == type && strcmp(name, *prop_name) == 0) 429 if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
430 return prop->GetToNode(); 430 return prop->GetToNode();
431 } 431 }
432 return NULL; 432 return NULL;
433 } 433 }
434 434
435 435
436 static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
437 v8::HeapGraphEdge::Type type,
438 const char* name) {
439 for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
440 const v8::HeapGraphEdge* prop = node->GetRetainer(i);
441 v8::String::AsciiValue prop_name(prop->GetName());
442 if (prop->GetType() == type && strcmp(name, *prop_name) == 0)
443 return true;
444 }
445 return false;
446 }
447
448
449 static bool HasString(const v8::HeapGraphNode* node, const char* contents) { 436 static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
450 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { 437 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
451 const v8::HeapGraphEdge* prop = node->GetChild(i); 438 const v8::HeapGraphEdge* prop = node->GetChild(i);
452 const v8::HeapGraphNode* node = prop->GetToNode(); 439 const v8::HeapGraphNode* node = prop->GetToNode();
453 if (node->GetType() == v8::HeapGraphNode::kString) { 440 if (node->GetType() == v8::HeapGraphNode::kString) {
454 v8::String::AsciiValue node_name(node->GetName()); 441 v8::String::AsciiValue node_name(node->GetName());
455 if (strcmp(contents, *node_name) == 0) return true; 442 if (strcmp(contents, *node_name) == 0) return true;
456 } 443 }
457 } 444 }
458 return false; 445 return false;
(...skipping 30 matching lines...) Expand all
489 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); 476 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1"));
490 CHECK_NE( 477 CHECK_NE(
491 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); 478 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2"));
492 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); 479 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2"));
493 480
494 NamedEntriesDetector det; 481 NamedEntriesDetector det;
495 i_snapshot_env2->IterateEntries(&det); 482 i_snapshot_env2->IterateEntries(&det);
496 CHECK(det.has_A2); 483 CHECK(det.has_A2);
497 CHECK(det.has_B2); 484 CHECK(det.has_B2);
498 CHECK(det.has_C2); 485 CHECK(det.has_C2);
499
500 /*
501 // Currently disabled. Too many retaining paths emerge, need to
502 // reduce the amount.
503
504 // Verify 'a2' object retainers. They are:
505 // - (global object).a2
506 // - c2.x1, c2.x2, c2[1]
507 // - b2_1 and b2_2 closures: via 'x' variable
508 CHECK_EQ(6, a2_node->GetRetainingPathsCount());
509 bool has_global_obj_a2_ref = false;
510 bool has_c2_x1_ref = false, has_c2_x2_ref = false, has_c2_1_ref = false;
511 bool has_b2_1_x_ref = false, has_b2_2_x_ref = false;
512 for (int i = 0; i < a2_node->GetRetainingPathsCount(); ++i) {
513 const v8::HeapGraphPath* path = a2_node->GetRetainingPath(i);
514 const int edges_count = path->GetEdgesCount();
515 CHECK_GT(edges_count, 0);
516 const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1);
517 v8::String::AsciiValue last_edge_name(last_edge->GetName());
518 if (strcmp("a2", *last_edge_name) == 0
519 && last_edge->GetType() == v8::HeapGraphEdge::kProperty) {
520 has_global_obj_a2_ref = true;
521 continue;
522 }
523 CHECK_GT(edges_count, 1);
524 const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2);
525 v8::String::AsciiValue prev_edge_name(prev_edge->GetName());
526 if (strcmp("x1", *last_edge_name) == 0
527 && last_edge->GetType() == v8::HeapGraphEdge::kProperty
528 && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true;
529 if (strcmp("x2", *last_edge_name) == 0
530 && last_edge->GetType() == v8::HeapGraphEdge::kProperty
531 && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true;
532 if (strcmp("1", *last_edge_name) == 0
533 && last_edge->GetType() == v8::HeapGraphEdge::kElement
534 && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true;
535 if (strcmp("x", *last_edge_name) == 0
536 && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
537 && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true;
538 if (strcmp("x", *last_edge_name) == 0
539 && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
540 && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
541 }
542 CHECK(has_global_obj_a2_ref);
543 CHECK(has_c2_x1_ref);
544 CHECK(has_c2_x2_ref);
545 CHECK(has_c2_1_ref);
546 CHECK(has_b2_1_x_ref);
547 CHECK(has_b2_2_x_ref);
548 */
549 } 486 }
550 487
551 488
552 TEST(HeapSnapshotObjectSizes) { 489 TEST(HeapSnapshotObjectSizes) {
553 v8::HandleScope scope; 490 v8::HandleScope scope;
554 LocalContext env; 491 LocalContext env;
555 492
556 // -a-> X1 --a 493 // -a-> X1 --a
557 // x -b-> X2 <-| 494 // x -b-> X2 <-|
558 CompileRun( 495 CompileRun(
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 GetProperty(global1, v8::HeapGraphEdge::kProperty, "b"); 704 GetProperty(global1, v8::HeapGraphEdge::kProperty, "b");
768 CHECK_NE(NULL, b1); 705 CHECK_NE(NULL, b1);
769 const v8::HeapGraphNode* b2 = 706 const v8::HeapGraphNode* b2 =
770 GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); 707 GetProperty(global2, v8::HeapGraphEdge::kProperty, "b");
771 CHECK_NE(NULL, b2); 708 CHECK_NE(NULL, b2);
772 CHECK_NE_UINT64_T(0, b1->GetId()); 709 CHECK_NE_UINT64_T(0, b1->GetId());
773 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId()); 710 CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId());
774 } 711 }
775 712
776 713
777 TEST(HeapSnapshotsDiff) {
778 v8::HandleScope scope;
779 LocalContext env;
780
781 CompileRun(
782 "function A() {}\n"
783 "function B(x) { this.x = x; }\n"
784 "function A2(a) { for (var i = 0; i < a; ++i) this[i] = i; }\n"
785 "var a = new A();\n"
786 "var b = new B(a);");
787 const v8::HeapSnapshot* snapshot1 =
788 v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
789
790 CompileRun(
791 "delete a;\n"
792 "b.x = null;\n"
793 "var a = new A2(20);\n"
794 "var b2 = new B(a);");
795 const v8::HeapSnapshot* snapshot2 =
796 v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
797
798 const v8::HeapSnapshotsDiff* diff = snapshot1->CompareWith(snapshot2);
799
800 // Verify additions: ensure that addition of A and B was detected.
801 const v8::HeapGraphNode* additions_root = diff->GetAdditionsRoot();
802 bool found_A = false, found_B = false;
803 uint64_t s1_A_id = 0;
804 for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) {
805 const v8::HeapGraphEdge* prop = additions_root->GetChild(i);
806 const v8::HeapGraphNode* node = prop->GetToNode();
807 if (node->GetType() == v8::HeapGraphNode::kObject) {
808 v8::String::AsciiValue node_name(node->GetName());
809 if (strcmp(*node_name, "A2") == 0) {
810 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
811 CHECK(!found_A);
812 found_A = true;
813 s1_A_id = node->GetId();
814 } else if (strcmp(*node_name, "B") == 0) {
815 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "b2"));
816 CHECK(!found_B);
817 found_B = true;
818 }
819 }
820 }
821 CHECK(found_A);
822 CHECK(found_B);
823
824 // Verify deletions: ensure that deletion of A was detected.
825 const v8::HeapGraphNode* deletions_root = diff->GetDeletionsRoot();
826 bool found_A_del = false;
827 uint64_t s2_A_id = 0;
828 for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) {
829 const v8::HeapGraphEdge* prop = deletions_root->GetChild(i);
830 const v8::HeapGraphNode* node = prop->GetToNode();
831 if (node->GetType() == v8::HeapGraphNode::kObject) {
832 v8::String::AsciiValue node_name(node->GetName());
833 if (strcmp(*node_name, "A") == 0) {
834 CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kShortcut, "a"));
835 CHECK(!found_A_del);
836 found_A_del = true;
837 s2_A_id = node->GetId();
838 }
839 }
840 }
841 CHECK(found_A_del);
842 CHECK_NE_UINT64_T(0, s1_A_id);
843 CHECK(s1_A_id != s2_A_id);
844 }
845
846
847 TEST(HeapSnapshotRootPreservedAfterSorting) { 714 TEST(HeapSnapshotRootPreservedAfterSorting) {
848 v8::HandleScope scope; 715 v8::HandleScope scope;
849 LocalContext env; 716 LocalContext env;
850 const v8::HeapSnapshot* snapshot = 717 const v8::HeapSnapshot* snapshot =
851 v8::HeapProfiler::TakeSnapshot(v8::String::New("s")); 718 v8::HeapProfiler::TakeSnapshot(v8::String::New("s"));
852 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); 719 const v8::HeapGraphNode* root1 = snapshot->GetRoot();
853 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( 720 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>(
854 snapshot))->GetSortedEntriesList(); 721 snapshot))->GetSortedEntriesList();
855 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); 722 const v8::HeapGraphNode* root2 = snapshot->GetRoot();
856 CHECK_EQ(root1, root2); 723 CHECK_EQ(root1, root2);
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 const_cast<v8::HeapSnapshot*>(s2)->Delete(); 1314 const_cast<v8::HeapSnapshot*>(s2)->Delete();
1448 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); 1315 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount());
1449 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2)); 1316 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2));
1450 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); 1317 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3));
1451 const_cast<v8::HeapSnapshot*>(s3)->Delete(); 1318 const_cast<v8::HeapSnapshot*>(s3)->Delete();
1452 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); 1319 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount());
1453 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3)); 1320 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3));
1454 } 1321 }
1455 1322
1456 #endif // ENABLE_LOGGING_AND_PROFILING 1323 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « test/cctest/test-assembler-mips.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698