Skip to content

Commit

Permalink
fixup! src: name EmbededderGraph edges and use class names for nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
joyeecheung committed Oct 2, 2018
1 parent e18aafa commit cd07235
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
4 changes: 2 additions & 2 deletions src/async_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions src/heap_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,9 @@ void BuildEmbedderGraph(const FunctionCallbackInfo<Value>& 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<Array> ret;
if (graph.CreateObject().ToLocal(&ret))
args.GetReturnValue().Set(ret);
}


Expand Down
31 changes: 19 additions & 12 deletions src/memory_tracker-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -105,16 +113,17 @@ template <typename T, typename Iterator>
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);
Expand Down Expand Up @@ -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<v8::EmbedderGraph::Node>(n));
seen_[retainer] = n;
if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name);
Expand Down
27 changes: 17 additions & 10 deletions src/memory_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -25,8 +27,6 @@
#define SET_NO_MEMORY_INFO() \
inline void MemoryInfo(node::MemoryTracker* tracker) const override {}

namespace node {

class MemoryTracker;
class MemoryRetainerNode;

Expand All @@ -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)
Expand All @@ -69,12 +69,12 @@ class NodeBIO;
* // a BaseObject or an AsyncWrap class
* bool IsRootNode() const override { return !wrapped.IsWeak(); }
* v8::Local<v8::Object> WrappedObject() const override {
* return node::PersistentToLocal(this->wrapped);
* return node::PersistentToLocal(wrapped);
* }
* private:
* AnotherRetainerClass another_retainer;
* InternalClass internal_member;
* std::vector<int> vector;
* std::vector<uv_async_t> vector;
* node::Persistent<Object> target;
*
* node::Persistent<Object> wrapped;
Expand All @@ -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)
Expand Down Expand Up @@ -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 <typename T, typename Iterator = typename T::const_iterator>
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 <typename T>
inline void TrackField(const char* edge_name,
const std::queue<T>& value,
Expand Down

0 comments on commit cd07235

Please sign in to comment.