From e2d8f7acde86ad3ddb9d60571141e6fed0e77430 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sat, 4 Aug 2018 00:09:16 +0800 Subject: [PATCH] src: implement the new EmbedderGraph::AddEdge() The signature of EmbedderGraph::AddEdge() has been changed so the current implementation of JSGraph no longer compiles. This patch updates the implementation accordingly. PR-URL: https://github.com/nodejs/node/pull/22106 Refs: https://github.com/v8/v8/commit/6ee834532d6f924f6057584085fa79b4777c396a Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- src/heap_utils.cc | 33 +++++++++++++++++++++++++++------ test/common/heap.js | 20 ++++++++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/heap_utils.cc b/src/heap_utils.cc index 2d339c580fa076..5ed5119bdb0ca0 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -77,7 +77,14 @@ class JSGraph : public EmbedderGraph { } void AddEdge(Node* from, Node* to) override { - edges_[from].insert(to); + edges_[from].insert(std::make_pair(nullptr, to)); + } + + // For ABI compatibility, we did not backport the virtual function + // AddEdge() with the name as last argument back to v10.x. + // This is only here to reduce the amount of churn. + void AddEdge(Node* from, Node* to, const char* name = nullptr) { + edges_[from].insert(std::make_pair(name, to)); } MaybeLocal CreateObject() const { @@ -92,6 +99,7 @@ class JSGraph : public EmbedderGraph { Local size_string = FIXED_ONE_BYTE_STRING(isolate_, "size"); Local value_string = FIXED_ONE_BYTE_STRING(isolate_, "value"); Local wraps_string = FIXED_ONE_BYTE_STRING(isolate_, "wraps"); + Local to_string = FIXED_ONE_BYTE_STRING(isolate_, "to"); for (const std::unique_ptr& n : nodes_) info_objects[n.get()] = Object::New(isolate_); @@ -141,10 +149,23 @@ class JSGraph : public EmbedderGraph { } size_t i = 0; - for (Node* target : edge_info.second) { - if (edges.As()->Set(context, - i++, - info_objects[target]).IsNothing()) { + size_t j = 0; + for (const auto& edge : edge_info.second) { + Local to_object = info_objects[edge.second]; + Local edge_info = Object::New(isolate_); + Local edge_name_value; + const char* edge_name = edge.first; + if (edge_name != nullptr && + !String::NewFromUtf8( + isolate_, edge_name, v8::NewStringType::kNormal) + .ToLocal(&edge_name_value)) { + return MaybeLocal(); + } else { + edge_name_value = Number::New(isolate_, j++); + } + if (edge_info->Set(context, name_string, edge_name_value).IsNothing() || + edge_info->Set(context, to_string, to_object).IsNothing() || + edges.As()->Set(context, i++, edge_info).IsNothing()) { return MaybeLocal(); } } @@ -158,7 +179,7 @@ class JSGraph : public EmbedderGraph { std::unordered_set> nodes_; std::unordered_set engine_nodes_; - std::unordered_map> edges_; + std::unordered_map>> edges_; }; void BuildEmbedderGraph(const FunctionCallbackInfo& args) { diff --git a/test/common/heap.js b/test/common/heap.js index bd8b588b4b0e1b..382d1d3642c959 100644 --- a/test/common/heap.js +++ b/test/common/heap.js @@ -54,15 +54,19 @@ class State { else assert.strictEqual(graph.length, expected.length); for (const expectedNode of expected) { - if (expectedNode.edges) { + if (expectedNode.children) { for (const expectedChild of expectedNode.children) { - const check = typeof expectedChild === 'function' ? - expectedChild : (node) => { - return node.name === expectedChild.name || - (node.value && - node.value.constructor && - node.value.constructor.name === expectedChild.name); - }; + const check = (edge) => { + // TODO(joyeecheung): check the edge names + const node = edge.to; + if (typeof expectedChild === 'function') { + return expectedChild(node); + } + return node.name === expectedChild.name || + (node.value && + node.value.constructor && + node.value.constructor.name === expectedChild.name); + }; // Don't use assert with a custom message here. Otherwise the // inspection in the message is done eagerly and wastes a lot of CPU