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" |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 LocalContext env; | 578 LocalContext env; |
579 const v8::HeapSnapshot* snapshot = | 579 const v8::HeapSnapshot* snapshot = |
580 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); | 580 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); |
581 TestJSONStream stream(5); | 581 TestJSONStream stream(5); |
582 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 582 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
583 CHECK_GT(stream.size(), 0); | 583 CHECK_GT(stream.size(), 0); |
584 CHECK_EQ(0, stream.eos_signaled()); | 584 CHECK_EQ(0, stream.eos_signaled()); |
585 } | 585 } |
586 | 586 |
587 | 587 |
| 588 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
| 589 const v8::HeapGraphNode* node, |
| 590 int level, int max_level) { |
| 591 if (level > max_level) return; |
| 592 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
| 593 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
| 594 const v8::HeapGraphEdge* prop = node->GetChild(i); |
| 595 const v8::HeapGraphNode* child = |
| 596 snapshot->GetNodeById(prop->GetToNode()->GetId()); |
| 597 CHECK_EQ_UINT64_T(prop->GetToNode()->GetId(), child->GetId()); |
| 598 CHECK_EQ(prop->GetToNode(), child); |
| 599 CheckChildrenIds(snapshot, child, level + 1, max_level); |
| 600 } |
| 601 } |
| 602 |
| 603 |
588 TEST(HeapSnapshotGetNodeById) { | 604 TEST(HeapSnapshotGetNodeById) { |
589 v8::HandleScope scope; | 605 v8::HandleScope scope; |
590 LocalContext env; | 606 LocalContext env; |
591 | 607 |
592 const v8::HeapSnapshot* snapshot = | 608 const v8::HeapSnapshot* snapshot = |
593 v8::HeapProfiler::TakeSnapshot(v8_str("id")); | 609 v8::HeapProfiler::TakeSnapshot(v8_str("id")); |
594 const v8::HeapGraphNode* root = snapshot->GetRoot(); | 610 const v8::HeapGraphNode* root = snapshot->GetRoot(); |
595 CHECK_EQ(root, snapshot->GetNodeById(root->GetId())); | 611 CheckChildrenIds(snapshot, root, 0, 3); |
596 for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) { | |
597 const v8::HeapGraphEdge* prop = root->GetChild(i); | |
598 CHECK_EQ( | |
599 prop->GetToNode(), snapshot->GetNodeById(prop->GetToNode()->GetId())); | |
600 } | |
601 // Check a big id, which should not exist yet. | 612 // Check a big id, which should not exist yet. |
602 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); | 613 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); |
603 } | 614 } |
604 | 615 |
605 | 616 |
606 namespace { | 617 namespace { |
607 | 618 |
608 class TestActivityControl : public v8::ActivityControl { | 619 class TestActivityControl : public v8::ActivityControl { |
609 public: | 620 public: |
610 explicit TestActivityControl(int abort_count) | 621 explicit TestActivityControl(int abort_count) |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 const v8::HeapGraphNode* obj1 = | 1069 const v8::HeapGraphNode* obj1 = |
1059 GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1"); | 1070 GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1"); |
1060 CHECK_NE(NULL, obj1); | 1071 CHECK_NE(NULL, obj1); |
1061 const v8::HeapGraphNode* getterFunction = | 1072 const v8::HeapGraphNode* getterFunction = |
1062 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); | 1073 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); |
1063 CHECK_NE(NULL, getterFunction); | 1074 CHECK_NE(NULL, getterFunction); |
1064 const v8::HeapGraphNode* setterFunction = | 1075 const v8::HeapGraphNode* setterFunction = |
1065 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); | 1076 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); |
1066 CHECK_NE(NULL, setterFunction); | 1077 CHECK_NE(NULL, setterFunction); |
1067 } | 1078 } |
| 1079 |
| 1080 |
| 1081 bool HasWeakEdge(const v8::HeapGraphNode* node) { |
| 1082 for (int i = 0; i < node->GetChildrenCount(); ++i) { |
| 1083 const v8::HeapGraphEdge* handle_edge = node->GetChild(i); |
| 1084 if (handle_edge->GetType() == v8::HeapGraphEdge::kWeak) return true; |
| 1085 } |
| 1086 return false; |
| 1087 } |
| 1088 |
| 1089 |
| 1090 bool HasWeakGlobalHandle() { |
| 1091 const v8::HeapSnapshot* snapshot = |
| 1092 v8::HeapProfiler::TakeSnapshot(v8_str("weaks")); |
| 1093 const v8::HeapGraphNode* gc_roots = GetNode( |
| 1094 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); |
| 1095 CHECK_NE(NULL, gc_roots); |
| 1096 const v8::HeapGraphNode* global_handles = GetNode( |
| 1097 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); |
| 1098 CHECK_NE(NULL, global_handles); |
| 1099 return HasWeakEdge(global_handles); |
| 1100 } |
| 1101 |
| 1102 |
| 1103 static void PersistentHandleCallback(v8::Persistent<v8::Value> handle, void*) { |
| 1104 handle.Dispose(); |
| 1105 } |
| 1106 |
| 1107 |
| 1108 TEST(WeakGlobalHandle) { |
| 1109 v8::HandleScope scope; |
| 1110 LocalContext env; |
| 1111 |
| 1112 CHECK(!HasWeakGlobalHandle()); |
| 1113 |
| 1114 v8::Persistent<v8::Object> handle = |
| 1115 v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 1116 handle.MakeWeak(NULL, PersistentHandleCallback); |
| 1117 |
| 1118 CHECK(HasWeakGlobalHandle()); |
| 1119 } |
| 1120 |
| 1121 |
| 1122 TEST(WeakGlobalContextRefs) { |
| 1123 v8::HandleScope scope; |
| 1124 LocalContext env; |
| 1125 |
| 1126 const v8::HeapSnapshot* snapshot = |
| 1127 v8::HeapProfiler::TakeSnapshot(v8_str("weaks")); |
| 1128 const v8::HeapGraphNode* gc_roots = GetNode( |
| 1129 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); |
| 1130 CHECK_NE(NULL, gc_roots); |
| 1131 const v8::HeapGraphNode* global_handles = GetNode( |
| 1132 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); |
| 1133 CHECK_NE(NULL, global_handles); |
| 1134 const v8::HeapGraphNode* global_context = GetNode( |
| 1135 global_handles, v8::HeapGraphNode::kHidden, "system / GlobalContext"); |
| 1136 CHECK_NE(NULL, global_context); |
| 1137 CHECK(HasWeakEdge(global_context)); |
| 1138 } |
| 1139 |
| 1140 |
| 1141 TEST(SfiAndJsFunctionWeakRefs) { |
| 1142 v8::HandleScope scope; |
| 1143 LocalContext env; |
| 1144 |
| 1145 CompileRun( |
| 1146 "fun = (function (x) { return function () { return x + 1; } })(1);"); |
| 1147 const v8::HeapSnapshot* snapshot = |
| 1148 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); |
| 1149 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1150 CHECK_NE(NULL, global); |
| 1151 const v8::HeapGraphNode* fun = |
| 1152 GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); |
| 1153 CHECK(HasWeakEdge(fun)); |
| 1154 const v8::HeapGraphNode* shared = |
| 1155 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); |
| 1156 CHECK(HasWeakEdge(shared)); |
| 1157 } |
OLD | NEW |