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