| Index: test/cctest/test-heap-profiler.cc
|
| diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
|
| index 1819aa461ecef384ffe331ca21de37def4f48b4c..d3bcf478fb441f1203d673204c56a43b8dffe4ef 100644
|
| --- a/test/cctest/test-heap-profiler.cc
|
| +++ b/test/cctest/test-heap-profiler.cc
|
| @@ -396,20 +396,17 @@ class NamedEntriesDetector {
|
| has_A2(false), has_B2(false), has_C2(false) {
|
| }
|
|
|
| - void Apply(i::HeapEntry* entry) {
|
| - const char* node_name = entry->name();
|
| - if (strcmp("A1", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_A1 = true;
|
| - if (strcmp("B1", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_B1 = true;
|
| - if (strcmp("C1", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_C1 = true;
|
| - if (strcmp("A2", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_A2 = true;
|
| - if (strcmp("B2", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_B2 = true;
|
| - if (strcmp("C2", node_name) == 0
|
| - && entry->GetRetainingPaths()->length() > 0) has_C2 = true;
|
| + void Apply(i::HeapEntry** entry_ptr) {
|
| + if (IsReachableNodeWithName(*entry_ptr, "A1")) has_A1 = true;
|
| + if (IsReachableNodeWithName(*entry_ptr, "B1")) has_B1 = true;
|
| + if (IsReachableNodeWithName(*entry_ptr, "C1")) has_C1 = true;
|
| + if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true;
|
| + if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true;
|
| + if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true;
|
| + }
|
| +
|
| + static bool IsReachableNodeWithName(i::HeapEntry* entry, const char* name) {
|
| + return strcmp(name, entry->name()) == 0 && entry->painted_reachable();
|
| }
|
|
|
| bool has_A1;
|
| @@ -460,7 +457,7 @@ static bool HasString(const v8::HeapGraphNode* node, const char* contents) {
|
| for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
|
| const v8::HeapGraphEdge* prop = node->GetChild(i);
|
| const v8::HeapGraphNode* node = prop->GetToNode();
|
| - if (node->GetType() == v8::HeapGraphNode::STRING) {
|
| + if (node->GetType() == v8::HeapGraphNode::kString) {
|
| v8::String::AsciiValue node_name(node->GetName());
|
| if (strcmp(contents, *node_name) == 0) return true;
|
| }
|
| @@ -496,26 +493,34 @@ TEST(HeapSnapshot) {
|
| "var c2 = new C2(a2);");
|
| const v8::HeapSnapshot* snapshot_env2 =
|
| v8::HeapProfiler::TakeSnapshot(v8::String::New("env2"));
|
| + i::HeapSnapshot* i_snapshot_env2 =
|
| + const_cast<i::HeapSnapshot*>(
|
| + reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
|
| const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2);
|
| + // Paint all nodes reachable from global object.
|
| + i_snapshot_env2->ClearPaint();
|
| + const_cast<i::HeapEntry*>(
|
| + reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable();
|
|
|
| // Verify, that JS global object of env2 doesn't have '..1'
|
| // properties, but has '..2' properties.
|
| - CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a1"));
|
| - CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_1"));
|
| - CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b1_2"));
|
| - CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c1"));
|
| + CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a1"));
|
| + CHECK_EQ(
|
| + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_1"));
|
| + CHECK_EQ(
|
| + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b1_2"));
|
| + CHECK_EQ(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c1"));
|
| const v8::HeapGraphNode* a2_node =
|
| - GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "a2");
|
| + GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
|
| CHECK_NE(NULL, a2_node);
|
| - CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_1"));
|
| - CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "b2_2"));
|
| - CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::PROPERTY, "c2"));
|
| + CHECK_NE(
|
| + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1"));
|
| + CHECK_NE(
|
| + NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2"));
|
| + CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2"));
|
|
|
| // Verify that anything related to '[ABC]1' is not reachable.
|
| NamedEntriesDetector det;
|
| - i::HeapSnapshot* i_snapshot_env2 =
|
| - const_cast<i::HeapSnapshot*>(
|
| - reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
|
| i_snapshot_env2->IterateEntries(&det);
|
| CHECK(!det.has_A1);
|
| CHECK(!det.has_B1);
|
| @@ -539,7 +544,7 @@ TEST(HeapSnapshot) {
|
| const v8::HeapGraphEdge* last_edge = path->GetEdge(edges_count - 1);
|
| v8::String::AsciiValue last_edge_name(last_edge->GetName());
|
| if (strcmp("a2", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY) {
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kProperty) {
|
| has_global_obj_a2_ref = true;
|
| continue;
|
| }
|
| @@ -547,19 +552,19 @@ TEST(HeapSnapshot) {
|
| const v8::HeapGraphEdge* prev_edge = path->GetEdge(edges_count - 2);
|
| v8::String::AsciiValue prev_edge_name(prev_edge->GetName());
|
| if (strcmp("x1", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kProperty
|
| && strcmp("c2", *prev_edge_name) == 0) has_c2_x1_ref = true;
|
| if (strcmp("x2", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::PROPERTY
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kProperty
|
| && strcmp("c2", *prev_edge_name) == 0) has_c2_x2_ref = true;
|
| if (strcmp("1", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::ELEMENT
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kElement
|
| && strcmp("c2", *prev_edge_name) == 0) has_c2_1_ref = true;
|
| if (strcmp("x", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
|
| && strcmp("b2_1", *prev_edge_name) == 0) has_b2_1_x_ref = true;
|
| if (strcmp("x", *last_edge_name) == 0
|
| - && last_edge->GetType() == v8::HeapGraphEdge::CONTEXT_VARIABLE
|
| + && last_edge->GetType() == v8::HeapGraphEdge::kContextVariable
|
| && strcmp("b2_2", *prev_edge_name) == 0) has_b2_2_x_ref = true;
|
| }
|
| CHECK(has_global_obj_a2_ref);
|
| @@ -571,6 +576,73 @@ TEST(HeapSnapshot) {
|
| }
|
|
|
|
|
| +TEST(HeapSnapshotObjectSizes) {
|
| + v8::HandleScope scope;
|
| + LocalContext env;
|
| +
|
| + // -a-> X1 --a
|
| + // x -b-> X2 <-|
|
| + CompileAndRunScript(
|
| + "function X(a, b) { this.a = a; this.b = b; }\n"
|
| + "x = new X(new X(), new X());\n"
|
| + "x.a.a = x.b;");
|
| + const v8::HeapSnapshot* snapshot =
|
| + v8::HeapProfiler::TakeSnapshot(v8::String::New("sizes"));
|
| + const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
|
| + const v8::HeapGraphNode* x =
|
| + GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
|
| + CHECK_NE(NULL, x);
|
| + const v8::HeapGraphNode* x_prototype =
|
| + GetProperty(x, v8::HeapGraphEdge::kProperty, "prototype");
|
| + CHECK_NE(NULL, x_prototype);
|
| + const v8::HeapGraphNode* x1 =
|
| + GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
|
| + CHECK_NE(NULL, x1);
|
| + const v8::HeapGraphNode* x2 =
|
| + GetProperty(x, v8::HeapGraphEdge::kProperty, "b");
|
| + CHECK_NE(NULL, x2);
|
| + CHECK_EQ(
|
| + x->GetSelfSize() * 3,
|
| + x->GetReachableSize() - x_prototype->GetReachableSize());
|
| + CHECK_EQ(
|
| + x->GetSelfSize() * 3 + x_prototype->GetSelfSize(), x->GetRetainedSize());
|
| + CHECK_EQ(
|
| + x1->GetSelfSize() * 2,
|
| + x1->GetReachableSize() - x_prototype->GetReachableSize());
|
| + CHECK_EQ(
|
| + x1->GetSelfSize(), x1->GetRetainedSize());
|
| + CHECK_EQ(
|
| + x2->GetSelfSize(),
|
| + x2->GetReachableSize() - x_prototype->GetReachableSize());
|
| + CHECK_EQ(
|
| + x2->GetSelfSize(), x2->GetRetainedSize());
|
| +}
|
| +
|
| +
|
| +TEST(HeapSnapshotEntryChildren) {
|
| + v8::HandleScope scope;
|
| + LocalContext env;
|
| +
|
| + CompileAndRunScript(
|
| + "function A() { }\n"
|
| + "a = new A;");
|
| + const v8::HeapSnapshot* snapshot =
|
| + v8::HeapProfiler::TakeSnapshot(v8::String::New("children"));
|
| + const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
|
| + for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) {
|
| + const v8::HeapGraphEdge* prop = global->GetChild(i);
|
| + CHECK_EQ(global, prop->GetFromNode());
|
| + }
|
| + const v8::HeapGraphNode* a =
|
| + GetProperty(global, v8::HeapGraphEdge::kProperty, "a");
|
| + CHECK_NE(NULL, a);
|
| + for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) {
|
| + const v8::HeapGraphEdge* prop = a->GetChild(i);
|
| + CHECK_EQ(a, prop->GetFromNode());
|
| + }
|
| +}
|
| +
|
| +
|
| TEST(HeapSnapshotCodeObjects) {
|
| v8::HandleScope scope;
|
| LocalContext env;
|
| @@ -584,20 +656,20 @@ TEST(HeapSnapshotCodeObjects) {
|
|
|
| const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
|
| const v8::HeapGraphNode* compiled =
|
| - GetProperty(global, v8::HeapGraphEdge::PROPERTY, "compiled");
|
| + GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled");
|
| CHECK_NE(NULL, compiled);
|
| - CHECK_EQ(v8::HeapGraphNode::CLOSURE, compiled->GetType());
|
| + CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType());
|
| const v8::HeapGraphNode* lazy =
|
| - GetProperty(global, v8::HeapGraphEdge::PROPERTY, "lazy");
|
| + GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
|
| CHECK_NE(NULL, lazy);
|
| - CHECK_EQ(v8::HeapGraphNode::CLOSURE, lazy->GetType());
|
| + CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
|
|
|
| // Find references to code.
|
| const v8::HeapGraphNode* compiled_code =
|
| - GetProperty(compiled, v8::HeapGraphEdge::INTERNAL, "code");
|
| + GetProperty(compiled, v8::HeapGraphEdge::kInternal, "code");
|
| CHECK_NE(NULL, compiled_code);
|
| const v8::HeapGraphNode* lazy_code =
|
| - GetProperty(lazy, v8::HeapGraphEdge::INTERNAL, "code");
|
| + GetProperty(lazy, v8::HeapGraphEdge::kInternal, "code");
|
| CHECK_NE(NULL, lazy_code);
|
|
|
| // Verify that non-compiled code doesn't contain references to "x"
|
| @@ -607,7 +679,7 @@ TEST(HeapSnapshotCodeObjects) {
|
| for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) {
|
| const v8::HeapGraphEdge* prop = compiled_code->GetChild(i);
|
| const v8::HeapGraphNode* node = prop->GetToNode();
|
| - if (node->GetType() == v8::HeapGraphNode::ARRAY) {
|
| + if (node->GetType() == v8::HeapGraphNode::kArray) {
|
| if (HasString(node, "x")) {
|
| compiled_references_x = true;
|
| break;
|
| @@ -617,7 +689,7 @@ TEST(HeapSnapshotCodeObjects) {
|
| for (int i = 0, count = lazy_code->GetChildrenCount(); i < count; ++i) {
|
| const v8::HeapGraphEdge* prop = lazy_code->GetChild(i);
|
| const v8::HeapGraphNode* node = prop->GetToNode();
|
| - if (node->GetType() == v8::HeapGraphNode::ARRAY) {
|
| + if (node->GetType() == v8::HeapGraphNode::kArray) {
|
| if (HasString(node, "x")) {
|
| lazy_references_x = true;
|
| break;
|
| @@ -634,11 +706,8 @@ TEST(HeapSnapshotCodeObjects) {
|
| // them to a signed type.
|
| #define CHECK_EQ_UINT64_T(a, b) \
|
| CHECK_EQ(static_cast<int64_t>(a), static_cast<int64_t>(b))
|
| -#define CHECK_NE_UINT64_T(a, b) do \
|
| - { \
|
| - bool ne = a != b; \
|
| - CHECK(ne); \
|
| - } while (false)
|
| +#define CHECK_NE_UINT64_T(a, b) \
|
| + CHECK((a) != (b)) // NOLINT
|
|
|
| TEST(HeapEntryIdsAndGC) {
|
| v8::HandleScope scope;
|
| @@ -662,27 +731,35 @@ TEST(HeapEntryIdsAndGC) {
|
| CHECK_NE_UINT64_T(0, global1->GetId());
|
| CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId());
|
| const v8::HeapGraphNode* A1 =
|
| - GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "A");
|
| + GetProperty(global1, v8::HeapGraphEdge::kProperty, "A");
|
| + CHECK_NE(NULL, A1);
|
| const v8::HeapGraphNode* A2 =
|
| - GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "A");
|
| + GetProperty(global2, v8::HeapGraphEdge::kProperty, "A");
|
| + CHECK_NE(NULL, A2);
|
| CHECK_NE_UINT64_T(0, A1->GetId());
|
| CHECK_EQ_UINT64_T(A1->GetId(), A2->GetId());
|
| const v8::HeapGraphNode* B1 =
|
| - GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "B");
|
| + GetProperty(global1, v8::HeapGraphEdge::kProperty, "B");
|
| + CHECK_NE(NULL, B1);
|
| const v8::HeapGraphNode* B2 =
|
| - GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "B");
|
| + GetProperty(global2, v8::HeapGraphEdge::kProperty, "B");
|
| + CHECK_NE(NULL, B2);
|
| CHECK_NE_UINT64_T(0, B1->GetId());
|
| CHECK_EQ_UINT64_T(B1->GetId(), B2->GetId());
|
| const v8::HeapGraphNode* a1 =
|
| - GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "a");
|
| + GetProperty(global1, v8::HeapGraphEdge::kProperty, "a");
|
| + CHECK_NE(NULL, a1);
|
| const v8::HeapGraphNode* a2 =
|
| - GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "a");
|
| + GetProperty(global2, v8::HeapGraphEdge::kProperty, "a");
|
| + CHECK_NE(NULL, a2);
|
| CHECK_NE_UINT64_T(0, a1->GetId());
|
| CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId());
|
| const v8::HeapGraphNode* b1 =
|
| - GetProperty(global1, v8::HeapGraphEdge::PROPERTY, "b");
|
| + GetProperty(global1, v8::HeapGraphEdge::kProperty, "b");
|
| + CHECK_NE(NULL, b1);
|
| const v8::HeapGraphNode* b2 =
|
| - GetProperty(global2, v8::HeapGraphEdge::PROPERTY, "b");
|
| + GetProperty(global2, v8::HeapGraphEdge::kProperty, "b");
|
| + CHECK_NE(NULL, b2);
|
| CHECK_NE_UINT64_T(0, b1->GetId());
|
| CHECK_EQ_UINT64_T(b1->GetId(), b2->GetId());
|
| }
|
| @@ -717,15 +794,15 @@ TEST(HeapSnapshotsDiff) {
|
| for (int i = 0, count = additions_root->GetChildrenCount(); i < count; ++i) {
|
| const v8::HeapGraphEdge* prop = additions_root->GetChild(i);
|
| const v8::HeapGraphNode* node = prop->GetToNode();
|
| - if (node->GetType() == v8::HeapGraphNode::OBJECT) {
|
| + if (node->GetType() == v8::HeapGraphNode::kObject) {
|
| v8::String::AsciiValue node_name(node->GetName());
|
| if (strcmp(*node_name, "A") == 0) {
|
| - CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a"));
|
| + CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
|
| CHECK(!found_A);
|
| found_A = true;
|
| s1_A_id = node->GetId();
|
| } else if (strcmp(*node_name, "B") == 0) {
|
| - CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "b2"));
|
| + CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "b2"));
|
| CHECK(!found_B);
|
| found_B = true;
|
| }
|
| @@ -741,10 +818,10 @@ TEST(HeapSnapshotsDiff) {
|
| for (int i = 0, count = deletions_root->GetChildrenCount(); i < count; ++i) {
|
| const v8::HeapGraphEdge* prop = deletions_root->GetChild(i);
|
| const v8::HeapGraphNode* node = prop->GetToNode();
|
| - if (node->GetType() == v8::HeapGraphNode::OBJECT) {
|
| + if (node->GetType() == v8::HeapGraphNode::kObject) {
|
| v8::String::AsciiValue node_name(node->GetName());
|
| if (strcmp(*node_name, "A") == 0) {
|
| - CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::PROPERTY, "a"));
|
| + CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
|
| CHECK(!found_A_del);
|
| found_A_del = true;
|
| s2_A_id = node->GetId();
|
|
|