GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_snapshotable.h Lines: 13 14 92.9 %
Date: 2022-08-12 04:19:25 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 EnvSerializeInfo;
14
struct SnapshotData;
15
class ExternalReferenceRegistry;
16
17
#define SERIALIZABLE_OBJECT_TYPES(V)                                           \
18
  V(fs_binding_data, fs::BindingData)                                          \
19
  V(v8_binding_data, v8_utils::BindingData)                                    \
20
  V(blob_binding_data, BlobBindingData)                                        \
21
  V(process_binding_data, process::BindingData)
22
23
enum class EmbedderObjectType : uint8_t {
24
  k_default = 0,
25
#define V(PropertyName, NativeType) k_##PropertyName,
26
  SERIALIZABLE_OBJECT_TYPES(V)
27
#undef V
28
};
29
30
// When serializing an embedder object, we'll serialize the native states
31
// into a chunk that can be mapped into a subclass of InternalFieldInfo,
32
// and pass it into the V8 callback as the payload of StartupData.
33
// The memory chunk looks like this:
34
//
35
// [   type   ] - EmbedderObjectType (a uint8_t)
36
// [  length  ] - a size_t
37
// [    ...   ] - custom bytes of size |length - header size|
38
struct InternalFieldInfo {
39
  EmbedderObjectType type;
40
  size_t length;
41
42
  InternalFieldInfo() = delete;
43
44
24
  static InternalFieldInfo* New(EmbedderObjectType type) {
45
24
    return New(type, sizeof(InternalFieldInfo));
46
  }
47
48
24
  static InternalFieldInfo* New(EmbedderObjectType type, size_t length) {
49
    InternalFieldInfo* result =
50
24
        reinterpret_cast<InternalFieldInfo*>(::operator new[](length));
51
24
    result->type = type;
52
24
    result->length = length;
53
24
    return result;
54
  }
55
56
21320
  InternalFieldInfo* Copy() const {
57
    InternalFieldInfo* result =
58
21320
        reinterpret_cast<InternalFieldInfo*>(::operator new[](length));
59
21320
    memcpy(result, this, length);
60
21320
    return result;
61
  }
62
63
21320
  void Delete() { ::operator delete[](this); }
64
};
65
66
// An interface for snapshotable native objects to inherit from.
67
// Use the SERIALIZABLE_OBJECT_METHODS() macro in the class to define
68
// the following methods to implement:
69
//
70
// - PrepareForSerialization(): This would be run prior to context
71
//   serialization. Use this method to e.g. release references that
72
//   can be re-initialized, or perform property store operations
73
//   that needs a V8 context.
74
// - Serialize(): This would be called during context serialization,
75
//   once for each embedder field of the object.
76
//   Allocate and construct an InternalFieldInfo object that contains
77
//   data that can be used to deserialize native states.
78
// - Deserialize(): This would be called after the context is
79
//   deserialized and the object graph is complete, once for each
80
//   embedder field of the object. Use this to restore native states
81
//   in the object.
82
class SnapshotableObject : public BaseObject {
83
 public:
84
  SnapshotableObject(Environment* env,
85
                     v8::Local<v8::Object> wrap,
86
                     EmbedderObjectType type = EmbedderObjectType::k_default);
87
  const char* GetTypeNameChars() const;
88
89
  virtual void PrepareForSerialization(v8::Local<v8::Context> context,
90
                                       v8::SnapshotCreator* creator) = 0;
91
  virtual InternalFieldInfo* Serialize(int index) = 0;
92
  bool is_snapshotable() const override { return true; }
93
  // We'll make sure that the type is set in the constructor
94
24
  EmbedderObjectType type() { return type_; }
95
96
 private:
97
  EmbedderObjectType type_;
98
};
99
100
#define SERIALIZABLE_OBJECT_METHODS()                                          \
101
  void PrepareForSerialization(v8::Local<v8::Context> context,                 \
102
                               v8::SnapshotCreator* creator) override;         \
103
  InternalFieldInfo* Serialize(int index) override;                            \
104
  static void Deserialize(v8::Local<v8::Context> context,                      \
105
                          v8::Local<v8::Object> holder,                        \
106
                          int index,                                           \
107
                          InternalFieldInfo* info);
108
109
v8::StartupData SerializeNodeContextInternalFields(v8::Local<v8::Object> holder,
110
                                                   int index,
111
                                                   void* env);
112
void DeserializeNodeInternalFields(v8::Local<v8::Object> holder,
113
                                   int index,
114
                                   v8::StartupData payload,
115
                                   void* env);
116
void SerializeBindingData(Environment* env,
117
                          v8::SnapshotCreator* creator,
118
                          EnvSerializeInfo* info);
119
120
bool IsSnapshotableType(FastStringKey key);
121
}  // namespace node
122
123
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
124
125
#endif  // SRC_NODE_SNAPSHOTABLE_H_