1// Copyright 2021 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef INCLUDE_V8_SNAPSHOT_H_ 6#define INCLUDE_V8_SNAPSHOT_H_ 7 8#include "v8-internal.h" // NOLINT(build/include_directory) 9#include "v8-local-handle.h" // NOLINT(build/include_directory) 10#include "v8config.h" // NOLINT(build/include_directory) 11 12namespace v8 { 13 14class Object; 15 16class V8_EXPORT StartupData { 17 public: 18 /** 19 * Whether the data created can be rehashed and and the hash seed can be 20 * recomputed when deserialized. 21 * Only valid for StartupData returned by SnapshotCreator::CreateBlob(). 22 */ 23 bool CanBeRehashed() const; 24 /** 25 * Allows embedders to verify whether the data is valid for the current 26 * V8 instance. 27 */ 28 bool IsValid() const; 29 30 const char* data; 31 int raw_size; 32}; 33 34/** 35 * Callback and supporting data used in SnapshotCreator to implement embedder 36 * logic to serialize internal fields. 37 * Internal fields that directly reference V8 objects are serialized without 38 * calling this callback. Internal fields that contain aligned pointers are 39 * serialized by this callback if it returns non-zero result. Otherwise it is 40 * serialized verbatim. 41 */ 42struct SerializeInternalFieldsCallback { 43 using CallbackFunction = StartupData (*)(Local<Object> holder, int index, 44 void* data); 45 SerializeInternalFieldsCallback(CallbackFunction function = nullptr, 46 void* data_arg = nullptr) 47 : callback(function), data(data_arg) {} 48 CallbackFunction callback; 49 void* data; 50}; 51// Note that these fields are called "internal fields" in the API and called 52// "embedder fields" within V8. 53using SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback; 54 55/** 56 * Callback and supporting data used to implement embedder logic to deserialize 57 * internal fields. 58 */ 59struct DeserializeInternalFieldsCallback { 60 using CallbackFunction = void (*)(Local<Object> holder, int index, 61 StartupData payload, void* data); 62 DeserializeInternalFieldsCallback(CallbackFunction function = nullptr, 63 void* data_arg = nullptr) 64 : callback(function), data(data_arg) {} 65 void (*callback)(Local<Object> holder, int index, StartupData payload, 66 void* data); 67 void* data; 68}; 69 70using DeserializeEmbedderFieldsCallback = DeserializeInternalFieldsCallback; 71 72/** 73 * Helper class to create a snapshot data blob. 74 * 75 * The Isolate used by a SnapshotCreator is owned by it, and will be entered 76 * and exited by the constructor and destructor, respectively; The destructor 77 * will also destroy the Isolate. Experimental language features, including 78 * those available by default, are not available while creating a snapshot. 79 */ 80class V8_EXPORT SnapshotCreator { 81 public: 82 enum class FunctionCodeHandling { kClear, kKeep }; 83 84 /** 85 * Initialize and enter an isolate, and set it up for serialization. 86 * The isolate is either created from scratch or from an existing snapshot. 87 * The caller keeps ownership of the argument snapshot. 88 * \param existing_blob existing snapshot from which to create this one. 89 * \param external_references a null-terminated array of external references 90 * that must be equivalent to CreateParams::external_references. 91 * \param owns_isolate whether this SnapshotCreator should call 92 * v8::Isolate::Dispose() during its destructor. 93 */ 94 SnapshotCreator(Isolate* isolate, 95 const intptr_t* external_references = nullptr, 96 const StartupData* existing_blob = nullptr, 97 bool owns_isolate = true); 98 99 /** 100 * Create and enter an isolate, and set it up for serialization. 101 * The isolate is either created from scratch or from an existing snapshot. 102 * The caller keeps ownership of the argument snapshot. 103 * \param existing_blob existing snapshot from which to create this one. 104 * \param external_references a null-terminated array of external references 105 * that must be equivalent to CreateParams::external_references. 106 */ 107 SnapshotCreator(const intptr_t* external_references = nullptr, 108 const StartupData* existing_blob = nullptr); 109 110 /** 111 * Destroy the snapshot creator, and exit and dispose of the Isolate 112 * associated with it. 113 */ 114 ~SnapshotCreator(); 115 116 /** 117 * \returns the isolate prepared by the snapshot creator. 118 */ 119 Isolate* GetIsolate(); 120 121 /** 122 * Set the default context to be included in the snapshot blob. 123 * The snapshot will not contain the global proxy, and we expect one or a 124 * global object template to create one, to be provided upon deserialization. 125 * 126 * \param callback optional callback to serialize internal fields. 127 */ 128 void SetDefaultContext(Local<Context> context, 129 SerializeInternalFieldsCallback callback = 130 SerializeInternalFieldsCallback()); 131 132 /** 133 * Add additional context to be included in the snapshot blob. 134 * The snapshot will include the global proxy. 135 * 136 * \param callback optional callback to serialize internal fields. 137 * 138 * \returns the index of the context in the snapshot blob. 139 */ 140 size_t AddContext(Local<Context> context, 141 SerializeInternalFieldsCallback callback = 142 SerializeInternalFieldsCallback()); 143 144 /** 145 * Attach arbitrary V8::Data to the context snapshot, which can be retrieved 146 * via Context::GetDataFromSnapshotOnce after deserialization. This data does 147 * not survive when a new snapshot is created from an existing snapshot. 148 * \returns the index for retrieval. 149 */ 150 template <class T> 151 V8_INLINE size_t AddData(Local<Context> context, Local<T> object); 152 153 /** 154 * Attach arbitrary V8::Data to the isolate snapshot, which can be retrieved 155 * via Isolate::GetDataFromSnapshotOnce after deserialization. This data does 156 * not survive when a new snapshot is created from an existing snapshot. 157 * \returns the index for retrieval. 158 */ 159 template <class T> 160 V8_INLINE size_t AddData(Local<T> object); 161 162 /** 163 * Created a snapshot data blob. 164 * This must not be called from within a handle scope. 165 * \param function_code_handling whether to include compiled function code 166 * in the snapshot. 167 * \returns { nullptr, 0 } on failure, and a startup snapshot on success. The 168 * caller acquires ownership of the data array in the return value. 169 */ 170 StartupData CreateBlob(FunctionCodeHandling function_code_handling); 171 172 // Disallow copying and assigning. 173 SnapshotCreator(const SnapshotCreator&) = delete; 174 void operator=(const SnapshotCreator&) = delete; 175 176 private: 177 size_t AddData(Local<Context> context, internal::Address object); 178 size_t AddData(internal::Address object); 179 180 void* data_; 181}; 182 183template <class T> 184size_t SnapshotCreator::AddData(Local<Context> context, Local<T> object) { 185 return AddData(context, internal::ValueHelper::ValueAsAddress(*object)); 186} 187 188template <class T> 189size_t SnapshotCreator::AddData(Local<T> object) { 190 return AddData(internal::ValueHelper::ValueAsAddress(*object)); 191} 192 193} // namespace v8 194 195#endif // INCLUDE_V8_SNAPSHOT_H_ 196