• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 namespace v8 {
13 
14 class Object;
15 
16 class 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  */
42 struct SerializeInternalFieldsCallback {
43   using CallbackFunction = StartupData (*)(Local<Object> holder, int index,
44                                            void* data);
45   SerializeInternalFieldsCallback(CallbackFunction function = nullptr,
46                                   void* data_arg = nullptr)
callbackSerializeInternalFieldsCallback47       : 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.
53 using SerializeEmbedderFieldsCallback = SerializeInternalFieldsCallback;
54 
55 /**
56  * Callback and supporting data used to implement embedder logic to deserialize
57  * internal fields.
58  */
59 struct 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)
callbackDeserializeInternalFieldsCallback64       : callback(function), data(data_arg) {}
65   void (*callback)(Local<Object> holder, int index, StartupData payload,
66                    void* data);
67   void* data;
68 };
69 
70 using 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  */
80 class 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    */
92   SnapshotCreator(Isolate* isolate,
93                   const intptr_t* external_references = nullptr,
94                   StartupData* existing_blob = nullptr);
95 
96   /**
97    * Create and enter an isolate, and set it up for serialization.
98    * The isolate is either created from scratch or from an existing snapshot.
99    * The caller keeps ownership of the argument snapshot.
100    * \param existing_blob existing snapshot from which to create this one.
101    * \param external_references a null-terminated array of external references
102    *        that must be equivalent to CreateParams::external_references.
103    */
104   SnapshotCreator(const intptr_t* external_references = nullptr,
105                   StartupData* existing_blob = nullptr);
106 
107   /**
108    * Destroy the snapshot creator, and exit and dispose of the Isolate
109    * associated with it.
110    */
111   ~SnapshotCreator();
112 
113   /**
114    * \returns the isolate prepared by the snapshot creator.
115    */
116   Isolate* GetIsolate();
117 
118   /**
119    * Set the default context to be included in the snapshot blob.
120    * The snapshot will not contain the global proxy, and we expect one or a
121    * global object template to create one, to be provided upon deserialization.
122    *
123    * \param callback optional callback to serialize internal fields.
124    */
125   void SetDefaultContext(Local<Context> context,
126                          SerializeInternalFieldsCallback callback =
127                              SerializeInternalFieldsCallback());
128 
129   /**
130    * Add additional context to be included in the snapshot blob.
131    * The snapshot will include the global proxy.
132    *
133    * \param callback optional callback to serialize internal fields.
134    *
135    * \returns the index of the context in the snapshot blob.
136    */
137   size_t AddContext(Local<Context> context,
138                     SerializeInternalFieldsCallback callback =
139                         SerializeInternalFieldsCallback());
140 
141   /**
142    * Attach arbitrary V8::Data to the context snapshot, which can be retrieved
143    * via Context::GetDataFromSnapshotOnce after deserialization. This data does
144    * not survive when a new snapshot is created from an existing snapshot.
145    * \returns the index for retrieval.
146    */
147   template <class T>
148   V8_INLINE size_t AddData(Local<Context> context, Local<T> object);
149 
150   /**
151    * Attach arbitrary V8::Data to the isolate snapshot, which can be retrieved
152    * via Isolate::GetDataFromSnapshotOnce after deserialization. This data does
153    * not survive when a new snapshot is created from an existing snapshot.
154    * \returns the index for retrieval.
155    */
156   template <class T>
157   V8_INLINE size_t AddData(Local<T> object);
158 
159   /**
160    * Created a snapshot data blob.
161    * This must not be called from within a handle scope.
162    * \param function_code_handling whether to include compiled function code
163    *        in the snapshot.
164    * \returns { nullptr, 0 } on failure, and a startup snapshot on success. The
165    *        caller acquires ownership of the data array in the return value.
166    */
167   StartupData CreateBlob(FunctionCodeHandling function_code_handling);
168 
169   // Disallow copying and assigning.
170   SnapshotCreator(const SnapshotCreator&) = delete;
171   void operator=(const SnapshotCreator&) = delete;
172 
173  private:
174   size_t AddData(Local<Context> context, internal::Address object);
175   size_t AddData(internal::Address object);
176 
177   void* data_;
178 };
179 
180 template <class T>
AddData(Local<Context> context,Local<T> object)181 size_t SnapshotCreator::AddData(Local<Context> context, Local<T> object) {
182   T* object_ptr = *object;
183   internal::Address* p = reinterpret_cast<internal::Address*>(object_ptr);
184   return AddData(context, *p);
185 }
186 
187 template <class T>
AddData(Local<T> object)188 size_t SnapshotCreator::AddData(Local<T> object) {
189   T* object_ptr = *object;
190   internal::Address* p = reinterpret_cast<internal::Address*>(object_ptr);
191   return AddData(*p);
192 }
193 
194 }  // namespace v8
195 
196 #endif  // INCLUDE_V8_SNAPSHOT_H_
197