GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_snapshotable.h Lines: 14 14 100.0 %
Date: 2022-10-02 04:22:39 Branches: 0 0 - %

Line Branch Exec Source
1
2
#ifndef SRC_NODE_SNAPSHOTABLE_H_
3
#define SRC_NODE_SNAPSHOTABLE_H_
4
5
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
6
7
#include "base_object.h"
8
#include "util.h"
9
10
namespace node {
11
12
class Environment;
13
struct RealmSerializeInfo;
14
struct SnapshotData;
15
class ExternalReferenceRegistry;
16
17
using SnapshotIndex = size_t;
18
19
struct PropInfo {
20
  std::string name;     // name for debugging
21
  uint32_t id;          // In the list - in case there are any empty entries
22
  SnapshotIndex index;  // In the snapshot
23
};
24
25
#define SERIALIZABLE_OBJECT_TYPES(V)                                           \
26
  V(fs_binding_data, fs::BindingData)                                          \
27
  V(v8_binding_data, v8_utils::BindingData)                                    \
28
  V(blob_binding_data, BlobBindingData)                                        \
29
  V(process_binding_data, process::BindingData)                                \
30
  V(util_weak_reference, util::WeakReference)
31
32
enum class EmbedderObjectType : uint8_t {
33
#define V(PropertyName, NativeType) k_##PropertyName,
34
  SERIALIZABLE_OBJECT_TYPES(V)
35
#undef V
36
};
37
38
typedef size_t SnapshotIndex;
39
40
// When serializing an embedder object, we'll serialize the native states
41
// into a chunk that can be mapped into a subclass of InternalFieldInfoBase,
42
// and pass it into the V8 callback as the payload of StartupData.
43
// The memory chunk looks like this:
44
//
45
// [   type   ] - EmbedderObjectType (a uint8_t)
46
// [  length  ] - a size_t
47
// [    ...   ] - custom bytes of size |length - header size|
48
struct InternalFieldInfoBase {
49
 public:
50
  EmbedderObjectType type;
51
  size_t length;
52
53
  template <typename T>
54
24
  static T* New(EmbedderObjectType type) {
55
    static_assert(std::is_base_of_v<InternalFieldInfoBase, T> ||
56
                      std::is_same_v<InternalFieldInfoBase, T>,
57
                  "Can only accept InternalFieldInfoBase subclasses");
58
24
    void* buf = ::operator new[](sizeof(T));
59
24
    T* result = new (buf) T;
60
24
    result->type = type;
61
24
    result->length = sizeof(T);
62
24
    return result;
63
  }
64
65
  template <typename T>
66
44192
  T* Copy() const {
67
    static_assert(std::is_base_of_v<InternalFieldInfoBase, T> ||
68
                      std::is_same_v<InternalFieldInfoBase, T>,
69
                  "Can only accept InternalFieldInfoBase subclasses");
70
    static_assert(std::is_trivially_copyable_v<T>,
71
                  "Can only memcpy trivially copyable class");
72
44192
    void* buf = ::operator new[](sizeof(T));
73
44192
    T* result = new (buf) T;
74
44192
    memcpy(result, this, sizeof(T));
75
44192
    return result;
76
  }
77
78
22096
  void Delete() { ::operator delete[](this); }
79
80
  InternalFieldInfoBase() = default;
81
};
82
83
// An interface for snapshotable native objects to inherit from.
84
// Use the SERIALIZABLE_OBJECT_METHODS() macro in the class to define
85
// the following methods to implement:
86
//
87
// - PrepareForSerialization(): This would be run prior to context
88
//   serialization. Use this method to e.g. release references that
89
//   can be re-initialized, or perform property store operations
90
//   that needs a V8 context.
91
// - Serialize(): This would be called during context serialization,
92
//   once for each embedder field of the object.
93
//   Allocate and construct an InternalFieldInfoBase object that contains
94
//   data that can be used to deserialize native states.
95
// - Deserialize(): This would be called after the context is
96
//   deserialized and the object graph is complete, once for each
97
//   embedder field of the object. Use this to restore native states
98
//   in the object.
99
class SnapshotableObject : public BaseObject {
100
 public:
101
  SnapshotableObject(Environment* env,
102
                     v8::Local<v8::Object> wrap,
103
                     EmbedderObjectType type);
104
  const char* GetTypeNameChars() const;
105
106
  // If returns false, the object will not be serialized.
107
  virtual bool PrepareForSerialization(v8::Local<v8::Context> context,
108
                                       v8::SnapshotCreator* creator) = 0;
109
  virtual InternalFieldInfoBase* Serialize(int index) = 0;
110
24
  bool is_snapshotable() const override { return true; }
111
  // We'll make sure that the type is set in the constructor
112
24
  EmbedderObjectType type() { return type_; }
113
114
 private:
115
  EmbedderObjectType type_;
116
};
117
118
#define SERIALIZABLE_OBJECT_METHODS()                                          \
119
  bool PrepareForSerialization(v8::Local<v8::Context> context,                 \
120
                               v8::SnapshotCreator* creator) override;         \
121
  InternalFieldInfoBase* Serialize(int index) override;                        \
122
  static void Deserialize(v8::Local<v8::Context> context,                      \
123
                          v8::Local<v8::Object> holder,                        \
124
                          int index,                                           \
125
                          InternalFieldInfoBase* info);
126
127
v8::StartupData SerializeNodeContextInternalFields(v8::Local<v8::Object> holder,
128
                                                   int index,
129
                                                   void* env);
130
void DeserializeNodeInternalFields(v8::Local<v8::Object> holder,
131
                                   int index,
132
                                   v8::StartupData payload,
133
                                   void* env);
134
void SerializeSnapshotableObjects(Realm* realm,
135
                                  v8::SnapshotCreator* creator,
136
                                  RealmSerializeInfo* info);
137
}  // namespace node
138
139
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
140
141
#endif  // SRC_NODE_SNAPSHOTABLE_H_