Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_snapshotable.h
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 "aliased_buffer.h" 8 #include "base_object.h" 9 #include "util.h" 10 11 namespace node { 12 13 class Environment; 14 struct RealmSerializeInfo; 15 struct SnapshotData; 16 class ExternalReferenceRegistry; 17 18 using SnapshotIndex = size_t; 19 20 struct PropInfo { 21 std::string name; // name for debugging 22 uint32_t id; // In the list - in case there are any empty entries 23 SnapshotIndex index; // In the snapshot 24 }; 25 26 typedef size_t SnapshotIndex; 27 28 bool WithoutCodeCache(const SnapshotFlags& flags); 29 bool WithoutCodeCache(const SnapshotConfig& config); 30 31 // When serializing an embedder object, we'll serialize the native states 32 // into a chunk that can be mapped into a subclass of InternalFieldInfoBase, 33 // and pass it into the V8 callback as the payload of StartupData. 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 InternalFieldInfoBase { 40 public: 41 EmbedderObjectType type; 42 size_t length; 43 44 template <typename T> 45 static T* New(EmbedderObjectType type) { 46 static_assert(std::is_base_of_v<InternalFieldInfoBase, T> || 47 std::is_same_v<InternalFieldInfoBase, T>, 48 "Can only accept InternalFieldInfoBase subclasses"); 49 void* buf = ::operator new[](sizeof(T)); 50 memset(buf, 0, sizeof(T)); // Make the padding reproducible. 51 T* result = new (buf) T; 52 result->type = type; 53 result->length = sizeof(T); 54 return result; 55 } 56 57 template <typename T> 58 T* Copy() const { 59 static_assert(std::is_base_of_v<InternalFieldInfoBase, T> || 60 std::is_same_v<InternalFieldInfoBase, T>, 61 "Can only accept InternalFieldInfoBase subclasses"); 62 static_assert(std::is_trivially_copyable_v<T>, 63 "Can only memcpy trivially copyable class"); 64 void* buf = ::operator new[](sizeof(T)); 65 T* result = new (buf) T; 66 memcpy(result, this, sizeof(T)); 67 return result; 68 } 69 70 void Delete() { ::operator delete[](this); } 71 72 InternalFieldInfoBase() = default; 73 }; 74 75 struct EmbedderTypeInfo { 76 enum class MemoryMode : uint8_t { kBaseObject, kCppGC }; 77 EmbedderTypeInfo(EmbedderObjectType t, MemoryMode m) : type(t), mode(m) {} 78 EmbedderTypeInfo() = default; 79 EmbedderObjectType type; 80 MemoryMode mode; 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(Realm* realm, 102 v8::Local<v8::Object> wrap, 103 EmbedderObjectType type); 104 std::string GetTypeName() 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 bool is_snapshotable() const override { return true; } 111 // We'll make sure that the type is set in the constructor 112 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 v8::StartupData SerializeNodeContextData(v8::Local<v8::Context> holder, 131 int index, 132 void* env); 133 void DeserializeNodeInternalFields(v8::Local<v8::Object> holder, 134 int index, 135 v8::StartupData payload, 136 void* env); 137 void DeserializeNodeContextData(v8::Local<v8::Context> holder, 138 int index, 139 v8::StartupData payload, 140 void* env); 141 void SerializeSnapshotableObjects(Realm* realm, 142 v8::SnapshotCreator* creator, 143 RealmSerializeInfo* info); 144 145 #define DCHECK_IS_SNAPSHOT_SLOT(index) DCHECK_EQ(index, BaseObject::kSlot) 146 147 namespace mksnapshot { 148 class BindingData : public SnapshotableObject { 149 public: 150 struct InternalFieldInfo : public node::InternalFieldInfoBase { 151 AliasedBufferIndex is_building_snapshot_buffer; 152 }; 153 154 BindingData(Realm* realm, 155 v8::Local<v8::Object> obj, 156 InternalFieldInfo* info = nullptr); 157 SET_BINDING_ID(mksnapshot_binding_data) 158 SERIALIZABLE_OBJECT_METHODS() 159 160 void MemoryInfo(MemoryTracker* tracker) const override; 161 SET_SELF_SIZE(BindingData) 162 SET_MEMORY_INFO_NAME(BindingData) 163 164 private: 165 AliasedUint8Array is_building_snapshot_buffer_; 166 InternalFieldInfo* internal_field_info_ = nullptr; 167 }; 168 } // namespace mksnapshot 169 170 } // namespace node 171 172 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 173 174 #endif // SRC_NODE_SNAPSHOTABLE_H_