#pragma once
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "v8-profiler.h"
#include
#include
#include
#include
#include
#include
namespace v8 {
class BackingStore;
}
namespace node {
class CppgcMixin;
template
struct MallocedBuffer;
// Set the node name of a MemoryRetainer to klass
#define SET_MEMORY_INFO_NAME(Klass) \
inline const char* MemoryInfoName() const override { return #Klass; }
// Set the self size of a MemoryRetainer to the stack-allocated size of a
// certain class
#define SET_SELF_SIZE(Klass) \
inline size_t SelfSize() const override { return sizeof(Klass); }
// Used when there is no additional fields to track
#define SET_NO_MEMORY_INFO() \
inline void MemoryInfo(node::MemoryTracker* tracker) const override {}
class MemoryTracker;
class MemoryRetainerNode;
template
class BaseObjectPtrImpl;
namespace crypto {
class NodeBIO;
}
class CleanupHookCallback;
/* Example:
*
* class ExampleRetainer : public MemoryRetainer {
* public:
* // Or use SET_NO_MEMORY_INFO() when there is no additional fields
* // to track.
* void MemoryInfo(MemoryTracker* tracker) const override {
* // Node name and size comes from the MemoryInfoName and SelfSize of
* // AnotherRetainerClass
* tracker->TrackField("another_retainer", another_retainer_);
*
* // Add non_pointer_retainer as a separate node into the graph
* // and track its memory information recursively.
* // Note that we need to make sure its size is not accounted in
* // ExampleRetainer::SelfSize().
* tracker->TrackField("non_pointer_retainer", &non_pointer_retainer_);
*
* // Specify node name and size explicitly
* tracker->TrackFieldWithSize("internal_member",
* internal_member_.size(),
* "InternalClass");
* // Node name falls back to the edge name,
* // elements in the container appear as grandchildren nodes
* tracker->TrackField("vector", vector_);
* // Node name and size come from the JS object
* tracker->TrackField("target", target_);
* }
*
* // Or use SET_MEMORY_INFO_NAME(ExampleRetainer)
* const char* MemoryInfoName() const override {
* return "ExampleRetainer";
* }
*
* // Classes that only want to return its sizeof() value can use the
* // SET_SELF_SIZE(Class) macro instead.
* size_t SelfSize() const override {
* // We need to exclude the size of non_pointer_retainer so that
* // we can track it separately in ExampleRetainer::MemoryInfo().
* return sizeof(ExampleRetainer) - sizeof(NonPointerRetainerClass);
* }
*
* // Note: no need to implement these two methods when implementing
* // a BaseObject or an AsyncWrap class
* bool IsRootNode() const override { return !wrapped_.IsWeak(); }
* v8::Local<:object> WrappedObject() const override {
* return node::PersistentToLocal::Default(wrapped_);
* }
*
* private:
* AnotherRetainerClass* another_retainer_;
* NonPointerRetainerClass non_pointer_retainer;
* InternalClass internal_member_;
* std::vector vector_;
* v8::Global