Skip to content

Commit

Permalink
src: implement GetDetachedness() in MemoryRetainerNode
Browse files Browse the repository at this point in the history
This allows us to mark weak/detached references in the heap snapshot.
Also mark weak/detached BaseObject with Detachedness::kDetached
so that the state of the reference can be displayed by frontend
consuming the heap snapshot.

PR-URL: #44803
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
joyeecheung authored and danielleadams committed Oct 10, 2022
1 parent 7ca77dd commit daf3152
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/base_object-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ bool BaseObject::IsWeakOrDetached() const {
return pd->wants_weak_jsobj || pd->is_detached;
}

v8::EmbedderGraph::Node::Detachedness BaseObject::GetDetachedness() const {
return IsWeakOrDetached() ? v8::EmbedderGraph::Node::Detachedness::kDetached
: v8::EmbedderGraph::Node::Detachedness::kUnknown;
}

template <int Field>
void BaseObject::InternalFieldGet(
v8::Local<v8::String> property,
Expand Down
2 changes: 2 additions & 0 deletions src/base_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class BaseObject : public MemoryRetainer {
// to it anymore.
inline bool IsWeakOrDetached() const;

inline v8::EmbedderGraph::Node::Detachedness GetDetachedness() const override;

// Utility to create a FunctionTemplate with one internal field (used for
// the `BaseObject*` pointer) and a constructor that initializes that field
// to `nullptr`.
Expand Down
6 changes: 6 additions & 0 deletions src/memory_tracker-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MemoryRetainerNode : public v8::EmbedderGraph::Node {

name_ = retainer_->MemoryInfoName();
size_ = retainer_->SelfSize();
detachedness_ = retainer_->GetDetachedness();
}

inline MemoryRetainerNode(MemoryTracker* tracker,
Expand All @@ -57,6 +58,9 @@ class MemoryRetainerNode : public v8::EmbedderGraph::Node {
}
return is_root_node_;
}
v8::EmbedderGraph::Node::Detachedness GetDetachedness() override {
return detachedness_;
}

private:
friend class MemoryTracker;
Expand All @@ -73,6 +77,8 @@ class MemoryRetainerNode : public v8::EmbedderGraph::Node {
bool is_root_node_ = false;
std::string name_;
size_t size_ = 0;
v8::EmbedderGraph::Node::Detachedness detachedness_ =
v8::EmbedderGraph::Node::Detachedness::kUnknown;
};

void MemoryTracker::TrackFieldWithSize(const char* edge_name,
Expand Down
3 changes: 3 additions & 0 deletions src/memory_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class MemoryRetainer {
}

virtual bool IsRootNode() const { return false; }
virtual v8::EmbedderGraph::Node::Detachedness GetDetachedness() const {
return v8::EmbedderGraph::Node::Detachedness::kUnknown;
}
};

class MemoryTracker {
Expand Down
16 changes: 16 additions & 0 deletions test/common/heap.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@ class State {
}
}
}

if (expectation.detachedness !== undefined) {
const matchedNodes = rootNodes.filter(
(node) => node.detachedness === expectation.detachedness);
if (loose) {
assert(matchedNodes.length >= rootNodes.length,
`Expect to find at least ${rootNodes.length} with ` +
`detachedness ${expectation.detachedness}, ` +
`found ${matchedNodes.length}`);
} else {
assert.strictEqual(
matchedNodes.length, rootNodes.length,
`Expect to find ${rootNodes.length} with detachedness ` +
`${expectation.detachedness}, found ${matchedNodes.length}`);
}
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion test/pummel/test-heapdump-dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ validateSnapshotNodes('Node / ChannelWrap', [
{ node_name: 'Node / NodeAresTask::List', edge_name: 'task_list' },
// `Node / ChannelWrap` (C++) -> `ChannelWrap` (JS)
{ node_name: 'ChannelWrap', edge_name: 'wrapped' },
]
],
detachedness: 2
},
]);

0 comments on commit daf3152

Please sign in to comment.