diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2018-08-03 14:43:40 +0300 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2018-08-18 19:52:41 +0300 |
commit | 54c87f37f44742588d0f8e0a778444e0890d7842 (patch) | |
tree | 36f836f637ce1f0bf787f3d141a2861b1dc75083 /deps | |
parent | 44d04a8c01dba1d7e4a9c9d9a4415eeacc580bf4 (diff) |
deps: cherry-pick 6ee8345 from upstream V8
Original commit message:
[heap-profiler] Allow embedder to specify edge names
This patch adds a variant of EmbedderGraph::AddEdge() which
allows the embedder to specify the name of an edge. The edges
added without name are element edges with auto-incremented indexes
while the edges added with names will be internal edges with
the specified names for more meaningful output in the heap
snapshot.
Refs: https://github.com/nodejs/node/pull/21741
Bug: v8:7938
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I8feefa2cf6911743e24b3b2024e0e849b0c65cd3
Reviewed-on: https://chromium-review.googlesource.com/1133299
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54412}
Refs: https://github.com/v8/v8/commit/6ee834532d6f924f6057584085fa79b4777c396a
PR-URL: https://github.com/nodejs/node/pull/22106
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r-- | deps/v8/include/v8-profiler.h | 9 | ||||
-rw-r--r-- | deps/v8/src/profiler/heap-snapshot-generator.cc | 14 | ||||
-rw-r--r-- | deps/v8/test/cctest/test-heap-profiler.cc | 83 |
3 files changed, 100 insertions, 6 deletions
diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 0e09d8732f2..bcb53f14460 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -686,11 +686,14 @@ class V8_EXPORT EmbedderGraph { virtual Node* AddNode(std::unique_ptr<Node> node) = 0; /** - * Adds an edge that represents a strong reference from the given node - * |from| to the given node |to|. The nodes must be added to the graph + * Adds an edge that represents a strong reference from the given + * node |from| to the given node |to|. The nodes must be added to the graph * before calling this function. + * + * If name is nullptr, the edge will have auto-increment indexes, otherwise + * it will be named accordingly. */ - virtual void AddEdge(Node* from, Node* to) = 0; + virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0; virtual ~EmbedderGraph() = default; }; diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc index 841d4e16e57..6564250d2e6 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.cc +++ b/deps/v8/src/profiler/heap-snapshot-generator.cc @@ -1989,6 +1989,7 @@ class EmbedderGraphImpl : public EmbedderGraph { struct Edge { Node* from; Node* to; + const char* name; }; class V8NodeImpl : public Node { @@ -2025,7 +2026,9 @@ class EmbedderGraphImpl : public EmbedderGraph { return result; } - void AddEdge(Node* from, Node* to) final { edges_.push_back({from, to}); } + void AddEdge(Node* from, Node* to, const char* name) final { + edges_.push_back({from, to, name}); + } const std::vector<std::unique_ptr<Node>>& nodes() { return nodes_; } const std::vector<Edge>& edges() { return edges_; } @@ -2318,8 +2321,13 @@ bool NativeObjectsExplorer::IterateAndExtractReferences( int from_index = from->index(); HeapEntry* to = EntryForEmbedderGraphNode(edge.to); if (to) { - filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, - from_index, to); + if (edge.name == nullptr) { + filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, + from_index, to); + } else { + filler_->SetNamedReference(HeapGraphEdge::kInternal, from_index, + edge.name, to); + } } } } else { diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 70dc07d3dc8..f164355bf8c 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -112,6 +112,12 @@ static const char* GetName(const v8::HeapGraphNode* node) { ->name(); } +static const char* GetName(const v8::HeapGraphEdge* edge) { + return const_cast<i::HeapGraphEdge*>( + reinterpret_cast<const i::HeapGraphEdge*>(edge)) + ->name(); +} + static size_t GetSize(const v8::HeapGraphNode* node) { return const_cast<i::HeapEntry*>(reinterpret_cast<const i::HeapEntry*>(node)) ->self_size(); @@ -128,6 +134,18 @@ static const v8::HeapGraphNode* GetChildByName(const v8::HeapGraphNode* node, return nullptr; } +static const v8::HeapGraphEdge* GetEdgeByChildName( + const v8::HeapGraphNode* node, const char* name) { + for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { + const v8::HeapGraphEdge* edge = node->GetChild(i); + const v8::HeapGraphNode* child = edge->GetToNode(); + if (!strcmp(name, GetName(child))) { + return edge; + } + } + return nullptr; +} + static const v8::HeapGraphNode* GetRootChild(const v8::HeapSnapshot* snapshot, const char* name) { return GetChildByName(snapshot->GetRoot(), name); @@ -2986,6 +3004,71 @@ TEST(EmbedderGraph) { CheckEmbedderGraphSnapshot(env->GetIsolate(), snapshot); } +void BuildEmbedderGraphWithNamedEdges(v8::Isolate* v8_isolate, + v8::EmbedderGraph* graph, void* data) { + using Node = v8::EmbedderGraph::Node; + Node* global_node = graph->V8Node(*global_object_pointer); + Node* embedder_node_A = graph->AddNode( + std::unique_ptr<Node>(new EmbedderNode("EmbedderNodeA", 10))); + Node* embedder_node_B = graph->AddNode( + std::unique_ptr<Node>(new EmbedderNode("EmbedderNodeB", 20))); + Node* embedder_node_C = graph->AddNode( + std::unique_ptr<Node>(new EmbedderNode("EmbedderNodeC", 30))); + graph->AddEdge(global_node, embedder_node_A, "global_to_a"); + graph->AddEdge(embedder_node_A, embedder_node_B, "a_to_b"); + graph->AddEdge(embedder_node_B, embedder_node_C); +} + +void CheckEmbedderGraphWithNamedEdges(v8::Isolate* isolate, + const v8::HeapSnapshot* snapshot) { + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphEdge* global_to_a = + GetEdgeByChildName(global, "EmbedderNodeA"); + CHECK(global_to_a); + CHECK_EQ(v8::HeapGraphEdge::kInternal, global_to_a->GetType()); + CHECK(global_to_a->GetName()->IsString()); + CHECK_EQ(0, strcmp("global_to_a", GetName(global_to_a))); + const v8::HeapGraphNode* embedder_node_A = global_to_a->GetToNode(); + CHECK_EQ(0, strcmp("EmbedderNodeA", GetName(embedder_node_A))); + CHECK_EQ(10, GetSize(embedder_node_A)); + + const v8::HeapGraphEdge* a_to_b = + GetEdgeByChildName(embedder_node_A, "EmbedderNodeB"); + CHECK(a_to_b); + CHECK(a_to_b->GetName()->IsString()); + CHECK_EQ(0, strcmp("a_to_b", GetName(a_to_b))); + CHECK_EQ(v8::HeapGraphEdge::kInternal, a_to_b->GetType()); + const v8::HeapGraphNode* embedder_node_B = a_to_b->GetToNode(); + CHECK_EQ(0, strcmp("EmbedderNodeB", GetName(embedder_node_B))); + CHECK_EQ(20, GetSize(embedder_node_B)); + + const v8::HeapGraphEdge* b_to_c = + GetEdgeByChildName(embedder_node_B, "EmbedderNodeC"); + CHECK(b_to_c); + CHECK(b_to_c->GetName()->IsNumber()); + CHECK_EQ(v8::HeapGraphEdge::kElement, b_to_c->GetType()); + const v8::HeapGraphNode* embedder_node_C = b_to_c->GetToNode(); + CHECK_EQ(0, strcmp("EmbedderNodeC", GetName(embedder_node_C))); + CHECK_EQ(30, GetSize(embedder_node_C)); +} + +TEST(EmbedderGraphWithNamedEdges) { + i::FLAG_heap_profiler_use_embedder_graph = true; + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); + v8::Local<v8::Value> global_object = + v8::Utils::ToLocal(i::Handle<i::JSObject>( + (isolate->context()->native_context()->global_object()), isolate)); + global_object_pointer = &global_object; + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + heap_profiler->AddBuildEmbedderGraphCallback(BuildEmbedderGraphWithNamedEdges, + nullptr); + const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); + CHECK(ValidateSnapshot(snapshot)); + CheckEmbedderGraphWithNamedEdges(env->GetIsolate(), snapshot); +} + struct GraphBuildingContext { int counter = 0; }; |