diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 5f04317960d201..c176696d5a22cf 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -182,8 +182,8 @@ class PromiseWrap : public AsyncWrap { } SET_NO_MEMORY_INFO() - SET_MEMORY_INFO_NAME(AsyncWrapObject); - SET_SELF_SIZE(AsyncWrapObject) + SET_MEMORY_INFO_NAME(PromiseWrap) + SET_SELF_SIZE(PromiseWrap) static constexpr int kPromiseField = 1; static constexpr int kIsChainedPromiseField = 2; diff --git a/src/heap_utils.cc b/src/heap_utils.cc index fee5f874f59d49..72ad33c99a1e80 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -193,8 +193,9 @@ void BuildEmbedderGraph(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); JSGraph graph(env->isolate()); Environment::BuildEmbedderGraph(env->isolate(), &graph, env); - // Crash if we cannot build a proper graph - args.GetReturnValue().Set(graph.CreateObject().ToLocalChecked()); + Local ret; + if (graph.CreateObject().ToLocal(&ret)) + args.GetReturnValue().Set(ret); } diff --git a/src/memory_tracker-inl.h b/src/memory_tracker-inl.h index 359388a9525fea..93e9ba1818ac5d 100644 --- a/src/memory_tracker-inl.h +++ b/src/memory_tracker-inl.h @@ -5,11 +5,20 @@ #include "memory_tracker.h" -#define DEFAULT_NODE_NAME \ - (node_name == nullptr ? (edge_name == nullptr ? "" : edge_name) : node_name) - namespace node { +// Fallback edge_name if node_name is not available, or "" if edge_name +// is not available either. +inline const char* GetNodeName(const char* node_name, const char* edge_name) { + if (node_name != nullptr) { + return node_name; + } + if (edge_name != nullptr) { + return edge_name; + } + return ""; +} + class MemoryRetainerNode : public v8::EmbedderGraph::Node { public: explicit inline MemoryRetainerNode(MemoryTracker* tracker, @@ -69,8 +78,7 @@ class MemoryRetainerNode : public v8::EmbedderGraph::Node { void MemoryTracker::TrackFieldWithSize(const char* edge_name, size_t size, const char* node_name) { - if (size > 0) - AddNode(DEFAULT_NODE_NAME, size, edge_name); + if (size > 0) AddNode(GetNodeName(node_name, edge_name), size, edge_name); } void MemoryTracker::TrackField(const char* edge_name, @@ -105,16 +113,17 @@ template void MemoryTracker::TrackField(const char* edge_name, const T& value, const char* node_name, - const char* element_name) { + const char* element_name, + bool subtract_from_self) { // If the container is empty, the size has been accounted into the parent's // self size if (value.begin() == value.end()) return; // Fall back to edge name if node names are not provided - if (CurrentNode() != nullptr) { + if (CurrentNode() != nullptr && subtract_from_self) { // Shift the self size of this container out to a separate node CurrentNode()->size_ -= sizeof(T); } - PushNode(DEFAULT_NODE_NAME, sizeof(T), edge_name); + PushNode(GetNodeName(node_name, edge_name), sizeof(T), edge_name); for (Iterator it = value.begin(); it != value.end(); ++it) { // Use nullptr as edge names so the elements appear as indexed properties TrackField(nullptr, *it, element_name); @@ -239,14 +248,12 @@ MemoryRetainerNode* MemoryTracker::CurrentNode() const { MemoryRetainerNode* MemoryTracker::AddNode(const MemoryRetainer* retainer, const char* edge_name) { - MemoryRetainerNode* n; auto it = seen_.find(retainer); if (it != seen_.end()) { - n = it->second; - return n; + return it->second; } - n = new MemoryRetainerNode(this, retainer); + MemoryRetainerNode* n = new MemoryRetainerNode(this, retainer); graph_->AddNode(std::unique_ptr(n)); seen_[retainer] = n; if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name); diff --git a/src/memory_tracker.h b/src/memory_tracker.h index 0cc2def22e9af7..02be59a5dc9172 100644 --- a/src/memory_tracker.h +++ b/src/memory_tracker.h @@ -12,6 +12,8 @@ #include "aliased_buffer.h" #include "v8-profiler.h" +namespace node { + // Set the node name of a MemoryRetainer to klass #define SET_MEMORY_INFO_NAME(Klass) \ inline std::string MemoryInfoName() const override { return #Klass; } @@ -25,8 +27,6 @@ #define SET_NO_MEMORY_INFO() \ inline void MemoryInfo(node::MemoryTracker* tracker) const override {} -namespace node { - class MemoryTracker; class MemoryRetainerNode; @@ -43,16 +43,16 @@ class NodeBIO; * void MemoryInfo(MemoryTracker* tracker) const override { * // Node name and size comes from the MemoryInfoName and SelfSize of * // AnotherRetainerClass - * tracker->TrackField("another_retainer", this->another_retainer); + * tracker->TrackField("another_retainer", another_retainer); * // Specify node name and size explicitly * tracker->TrackFieldWithSize("internal_member", - * this->internal_member.size(), + * internal_member.size(), * "InternalClass"); * // Node name falls back to the edge name, * // elements in the container appear as grandchildren nodes - * tracker->TrackField("vector", this->vector_field); + * tracker->TrackField("vector", vector); * // Node name and size come from the JS object - * tracker->TrackField("target", this->target); + * tracker->TrackField("target", target); * } * * // Or use SET_MEMORY_INFO_NAME(ExampleRetainer) @@ -69,12 +69,12 @@ class NodeBIO; * // a BaseObject or an AsyncWrap class * bool IsRootNode() const override { return !wrapped.IsWeak(); } * v8::Local WrappedObject() const override { - * return node::PersistentToLocal(this->wrapped); + * return node::PersistentToLocal(wrapped); * } * private: * AnotherRetainerClass another_retainer; * InternalClass internal_member; - * std::vector vector; + * std::vector vector; * node::Persistent target; * * node::Persistent wrapped; @@ -84,7 +84,10 @@ class NodeBIO; * Node / ExampleRetainer * |> another_retainer :: Node / AnotherRetainerClass * |> internal_member :: Node / InternalClass - * |> vector :: Node / vector + * |> vector :: Node / vector (elements will be grandchildren) + * |> [1] :: Node / uv_async_t (uv_async_t has predefined names) + * |> [2] :: Node / uv_async_t + * |> ... * |> target :: TargetClass (JS class name of the target object) * |> wrapped :: WrappedClass (JS class name of the wrapped object) * |> wrapper :: Node / ExampleRetainer (back reference) @@ -123,12 +126,16 @@ class MemoryTracker { // For containers, the elements will be graphed as grandchildren nodes // if the container is not empty. + // By default, we assume the parent count the stack size of the container + // into its SelfSize so that will be subtracted from the parent size when we + // spin off a new node for the container. // TODO(joyeecheung): use RTTI to retrieve the class name at runtime? template inline void TrackField(const char* edge_name, const T& value, const char* node_name = nullptr, - const char* element_name = nullptr); + const char* element_name = nullptr, + bool subtract_from_self = true); template inline void TrackField(const char* edge_name, const std::queue& value,