PHP 7.4.33
Preview: memory_tracker.h Size: 11.23 KB
/usr/include/nodejs/src/memory_tracker.h
#pragma once

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "aliased_buffer.h"
#include "v8-profiler.h"

#include <uv.h>

#include <limits>
#include <queue>
#include <stack>
#include <string>
#include <unordered_map>

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; }

// 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 <typename T, bool kIsWeak>
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)
 *     std::string 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<v8::Object> WrappedObject() const override {
 *       return node::PersistentToLocal::Default(wrapped_);
 *     }
 *
 *   private:
 *     AnotherRetainerClass* another_retainer_;
 *     NonPointerRetainerClass non_pointer_retainer;
 *     InternalClass internal_member_;
 *     std::vector<uv_async_t> vector_;
 *     v8::Global<Object> target_;
 *
 *     v8::Global<Object> wrapped_;
 * }
 *
 * This creates the following graph:
 *   Node / ExampleRetainer
 *    |> another_retainer :: Node / AnotherRetainerClass
 *    |> internal_member :: Node / InternalClass
 *    |> 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)
 */
class MemoryRetainer {
 public:
  virtual ~MemoryRetainer() = default;

  // Subclasses should implement these methods to provide information
  // for the V8 heap snapshot generator.
  // The MemoryInfo() method is assumed to be called within a context
  // where all the edges start from the node of the current retainer,
  // and point to the nodes as specified by tracker->Track* calls.
  virtual void MemoryInfo(MemoryTracker* tracker) const = 0;
  virtual std::string MemoryInfoName() const = 0;
  virtual size_t SelfSize() const = 0;

  virtual v8::Local<v8::Object> WrappedObject() const {
    return v8::Local<v8::Object>();
  }

  virtual bool IsRootNode() const { return false; }
};

class MemoryTracker {
 public:
  // Used to specify node name and size explicitly
  inline void TrackFieldWithSize(const char* edge_name,
                                 size_t size,
                                 const char* node_name = nullptr);
  inline void TrackInlineFieldWithSize(const char* edge_name,
                                       size_t size,
                                       const char* node_name = nullptr);

  // Shortcut to extract the underlying object out of the smart pointer
  template <typename T, typename D>
  inline void TrackField(const char* edge_name,
                         const std::unique_ptr<T, D>& value,
                         const char* node_name = nullptr);

  template <typename T, bool kIsWeak>
  void TrackField(const char* edge_name,
                  const BaseObjectPtrImpl<T, kIsWeak>& value,
                  const char* node_name = nullptr);

  // 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,
                         bool subtract_from_self = true);
  template <typename T>
  inline void TrackField(const char* edge_name,
                         const std::queue<T>& value,
                         const char* node_name = nullptr,
                         const char* element_name = nullptr);
  template <typename T, typename U>
  inline void TrackField(const char* edge_name,
                         const std::pair<T, U>& value,
                         const char* node_name = nullptr);

  // For the following types, node_name will be ignored and predefined names
  // will be used instead. They are only in the signature for template
  // expansion.
  inline void TrackField(const char* edge_name,
                         const MemoryRetainer& value,
                         const char* node_name = nullptr);
  inline void TrackField(const char* edge_name,
                         const MemoryRetainer* value,
                         const char* node_name = nullptr);
  template <typename T>
  inline void TrackField(const char* edge_name,
                         const std::basic_string<T>& value,
                         const char* node_name = nullptr);
  template <typename T,
            typename test_for_number = typename std::
                enable_if<std::numeric_limits<T>::is_specialized, bool>::type,
            typename dummy = bool>
  inline void TrackField(const char* edge_name,
                         const T& value,
                         const char* node_name = nullptr);
  template <typename T>
  void TrackField(const char* edge_name,
                  const v8::Eternal<T>& value,
                  const char* node_name);
  template <typename T>
  inline void TrackField(const char* edge_name,
                         const v8::PersistentBase<T>& value,
                         const char* node_name = nullptr);
  template <typename T>
  inline void TrackField(const char* edge_name,
                         const v8::Local<T>& value,
                         const char* node_name = nullptr);
  template <typename T>
  inline void TrackField(const char* edge_name,
                         const MallocedBuffer<T>& value,
                         const char* node_name = nullptr);
  inline void TrackField(const char* edge_name,
                         const uv_buf_t& value,
                         const char* node_name = nullptr);
  inline void TrackField(const char* edge_name,
                         const uv_timer_t& value,
                         const char* node_name = nullptr);
  inline void TrackField(const char* edge_name,
                         const uv_async_t& value,
                         const char* node_name = nullptr);
  inline void TrackInlineField(const char* edge_name,
                               const uv_async_t& value,
                               const char* node_name = nullptr);
  template <class NativeT, class V8T>
  inline void TrackField(const char* edge_name,
                         const AliasedBufferBase<NativeT, V8T>& value,
                         const char* node_name = nullptr);

  // Put a memory container into the graph, create an edge from
  // the current node if there is one on the stack.
  inline void Track(const MemoryRetainer* retainer,
                    const char* edge_name = nullptr);

  // Useful for parents that do not wish to perform manual
  // adjustments to its `SelfSize()` when embedding retainer
  // objects inline.
  // Put a memory container into the graph, create an edge from
  // the current node if there is one on the stack - there should
  // be one, of the container object which the current field is part of.
  // Reduce the size of memory from the container so as to avoid
  // duplication in accounting.
  inline void TrackInlineField(const MemoryRetainer* retainer,
                               const char* edge_name = nullptr);

  inline v8::EmbedderGraph* graph() { return graph_; }
  inline v8::Isolate* isolate() { return isolate_; }

  inline explicit MemoryTracker(v8::Isolate* isolate,
                                v8::EmbedderGraph* graph)
    : isolate_(isolate), graph_(graph) {}

 private:
  typedef std::unordered_map<const MemoryRetainer*, MemoryRetainerNode*>
      NodeMap;

  inline MemoryRetainerNode* CurrentNode() const;
  inline MemoryRetainerNode* AddNode(const MemoryRetainer* retainer,
                                     const char* edge_name = nullptr);
  inline MemoryRetainerNode* PushNode(const MemoryRetainer* retainer,
                                      const char* edge_name = nullptr);
  inline MemoryRetainerNode* AddNode(const char* node_name,
                                     size_t size,
                                     const char* edge_name = nullptr);
  inline MemoryRetainerNode* PushNode(const char* node_name,
                                      size_t size,
                                      const char* edge_name = nullptr);
  inline void PopNode();

  v8::Isolate* isolate_;
  v8::EmbedderGraph* graph_;
  std::stack<MemoryRetainerNode*> node_stack_;
  NodeMap seen_;
};

}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

Directory Contents

Dirs: 0 × Files: 108
Name Size Perms Modified Actions
7.91 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.96 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
10.07 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.57 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
10.82 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.83 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.59 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.96 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
686 B lrw-r--r-- 2022-01-10 12:24:37
Edit Download
584 B lrw-r--r-- 2022-01-10 12:24:37
Edit Download
7.36 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.44 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
768 B lrw-r--r-- 2022-01-10 12:24:37
Edit Download
40.44 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
65.90 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.98 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.68 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.83 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
609 B lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.88 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.19 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.53 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.53 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.50 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.63 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
28.13 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.14 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
12.23 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.28 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.35 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.50 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.23 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.10 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
43.55 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.41 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.62 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.25 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.60 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.67 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.37 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.14 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
29.59 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.22 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.60 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.16 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.48 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
23.04 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.31 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.89 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.89 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
9.81 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
12.20 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
49.14 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.58 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
28.90 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.30 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
13.34 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.05 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.60 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.28 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.96 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.46 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.07 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.31 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.33 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.78 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
14.68 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
15.68 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.21 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.99 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.88 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.77 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.35 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.45 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
212.59 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.61 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.56 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.15 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.20 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.16 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.19 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.69 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.13 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.17 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
11.67 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.67 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.78 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.67 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.40 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.22 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.55 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
6.87 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
9.16 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
15.92 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.15 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
4.03 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.59 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
858 B lrw-r--r-- 2022-01-10 12:24:37
Edit Download
1.50 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
20.92 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
3.65 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.05 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
7.88 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
2.18 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
8.59 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
16.42 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
25.51 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
5.09 KB lrw-r--r-- 2022-01-10 12:24:37
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).