v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
deserializer.h
Go to the documentation of this file.
1// Copyright 2016 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 V8_SNAPSHOT_DESERIALIZER_H_
6#define V8_SNAPSHOT_DESERIALIZER_H_
7
8#include <utility>
9#include <vector>
10
11#include "src/base/macros.h"
12#include "src/common/globals.h"
18#include "src/objects/code.h"
19#include "src/objects/map.h"
20#include "src/objects/objects.h"
22#include "src/objects/string.h"
25
26namespace v8 {
27namespace internal {
28
29class HeapObject;
30class Object;
31
32// Used for platforms with embedded constant pools to trigger deserialization
33// of objects found in code.
34#if defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_S390X) || \
35 defined(V8_TARGET_ARCH_PPC64) || defined(V8_TARGET_ARCH_RISCV32) || \
36 defined(V8_TARGET_ARCH_RISCV64) || V8_EMBEDDED_CONSTANT_POOL_BOOL
37#define V8_CODE_EMBEDS_OBJECT_POINTER 1
38#else
39#define V8_CODE_EMBEDS_OBJECT_POINTER 0
40#endif
41
42// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
43template <typename IsolateT>
45 public:
46 ~Deserializer() override;
47 Deserializer(const Deserializer&) = delete;
49
50 protected:
51 // Create a deserializer from a snapshot byte source.
52 Deserializer(IsolateT* isolate, base::Vector<const uint8_t> payload,
53 uint32_t magic_number, bool deserializing_user_code,
54 bool can_rehash);
55
57
58 // Create Log events for newly deserialized objects.
61 void LogNewMapEvents();
62
63 // Descriptor arrays are deserialized as "strong", so that there is no risk of
64 // them getting trimmed during a partial deserialization. This method makes
65 // them "weak" again after deserialization completes.
67
68 // This returns the address of an object that has been described in the
69 // snapshot by object vector index.
72
73 // Add an object to back an attached reference. The order to add objects must
74 // mirror the order they are added in the serializer.
76 attached_objects_.push_back(attached_object);
77 }
78
79 IsolateT* isolate() const { return isolate_; }
80
82
84
93 return {new_maps_.data(), new_maps_.size()};
94 }
105
106 std::shared_ptr<BackingStore> backing_store(size_t i) {
108 return backing_stores_[i];
109 }
110
112 bool should_rehash() const { return should_rehash_; }
113
115 to_rehash_.push_back(object);
116 }
117 void Rehash();
118
120
121 private:
122 // A circular queue of hot objects. This is added to in the same order as in
123 // Serializer::HotObjectsList, but this stores the objects as a vector of
124 // existing handles. This allows us to add Handles to the queue without having
125 // to create new handles. Note that this depends on those Handles staying
126 // valid as long as the HotObjectsList is alive.
128 public:
129 HotObjectsList() = default;
132
134 circular_queue_[index_] = object;
135 index_ = (index_ + 1) & kSizeMask;
136 }
137
139 DCHECK(!circular_queue_[index].is_null());
140 return circular_queue_[index];
141 }
142
143 private:
144 static const int kSize = kHotObjectCount;
145 static const int kSizeMask = kSize - 1;
146 static_assert(base::bits::IsPowerOfTwo(kSize));
148 int index_ = 0;
149 };
150
152 HeapObjectReferenceType type;
155 };
156
157 void VisitRootPointers(Root root, const char* description,
159
161
162 template <typename SlotAccessor>
163 int WriteHeapPointer(SlotAccessor slot_accessor,
164 Tagged<HeapObject> heap_object,
167 template <typename SlotAccessor>
168 int WriteHeapPointer(SlotAccessor slot_accessor,
169 DirectHandle<HeapObject> heap_object,
172
174 ExternalPointerSlot dest, Address value,
177 Tagged<HeapObject> value);
178
179 // Fills in a heap object's data from start to end (exclusive). Start and end
180 // are slot indices within the object.
181 void ReadData(Handle<HeapObject> object, int start_slot_index,
182 int end_slot_index);
183
184 // Fills in a contiguous range of full object slots (e.g. root pointers) from
185 // start to end (exclusive).
187
188 // Helper for ReadData which reads the given bytecode and fills in some heap
189 // data into the given slot. May fill in zero or multiple slots, so it returns
190 // the number of slots filled.
191 template <typename SlotAccessor>
192 int ReadSingleBytecodeData(uint8_t data, SlotAccessor slot_accessor);
193
194 template <typename SlotAccessor>
195 int ReadNewObject(uint8_t data, SlotAccessor slot_accessor);
196 template <typename SlotAccessor>
197 int ReadBackref(uint8_t data, SlotAccessor slot_accessor);
198 template <typename SlotAccessor>
199 int ReadReadOnlyHeapRef(uint8_t data, SlotAccessor slot_accessor);
200 template <typename SlotAccessor>
201 int ReadRootArray(uint8_t data, SlotAccessor slot_accessor);
202 template <typename SlotAccessor>
203 int ReadStartupObjectCache(uint8_t data, SlotAccessor slot_accessor);
204 template <typename SlotAccessor>
205 int ReadSharedHeapObjectCache(uint8_t data, SlotAccessor slot_accessor);
206 template <typename SlotAccessor>
207 int ReadNewMetaMap(uint8_t data, SlotAccessor slot_accessor);
208 template <typename SlotAccessor>
209 int ReadExternalReference(uint8_t data, SlotAccessor slot_accessor);
210 template <typename SlotAccessor>
211 int ReadRawExternalReference(uint8_t data, SlotAccessor slot_accessor);
212 template <typename SlotAccessor>
213 int ReadAttachedReference(uint8_t data, SlotAccessor slot_accessor);
214 template <typename SlotAccessor>
215 int ReadRegisterPendingForwardRef(uint8_t data, SlotAccessor slot_accessor);
216 template <typename SlotAccessor>
217 int ReadResolvePendingForwardRef(uint8_t data, SlotAccessor slot_accessor);
218 template <typename SlotAccessor>
219 int ReadVariableRawData(uint8_t data, SlotAccessor slot_accessor);
220 template <typename SlotAccessor>
221 int ReadVariableRepeatRoot(uint8_t data, SlotAccessor slot_accessor);
222 template <typename SlotAccessor>
223 int ReadOffHeapBackingStore(uint8_t data, SlotAccessor slot_accessor);
224 template <typename SlotAccessor>
225 int ReadApiReference(uint8_t data, SlotAccessor slot_accessor);
226 template <typename SlotAccessor>
227 int ReadClearedWeakReference(uint8_t data, SlotAccessor slot_accessor);
228 template <typename SlotAccessor>
229 int ReadWeakPrefix(uint8_t data, SlotAccessor slot_accessor);
230 template <typename SlotAccessor>
231 int ReadIndirectPointerPrefix(uint8_t data, SlotAccessor slot_accessor);
232 template <typename SlotAccessor>
233 int ReadInitializeSelfIndirectPointer(uint8_t data,
234 SlotAccessor slot_accessor);
235 template <typename SlotAccessor>
236 int ReadAllocateJSDispatchEntry(uint8_t data, SlotAccessor slot_accessor);
237 template <typename SlotAccessor>
238 int ReadJSDispatchEntry(uint8_t data, SlotAccessor slot_accessor);
239 template <typename SlotAccessor>
240 int ReadProtectedPointerPrefix(uint8_t data, SlotAccessor slot_accessor);
241 template <typename SlotAccessor>
242 int ReadRootArrayConstants(uint8_t data, SlotAccessor slot_accessor);
243 template <typename SlotAccessor>
244 int ReadHotObject(uint8_t data, SlotAccessor slot_accessor);
245 template <typename SlotAccessor>
246 int ReadFixedRawData(uint8_t data, SlotAccessor slot_accessor);
247 template <typename SlotAccessor>
248 int ReadFixedRepeatRoot(uint8_t data, SlotAccessor slot_accessor);
249
250 // A helper function for ReadData for reading external references.
252
253 // A helper function for reading external pointer tags.
255
258
260
261 template <typename SlotGetter>
262 int ReadRepeatedRoot(SlotGetter slot_getter, int repeat_count);
263
264 // Special handling for serialized code like hooking up internalized strings.
266 SnapshotSpace space);
268 InstanceType instance_type,
269 SnapshotSpace space);
270
271 Tagged<HeapObject> Allocate(AllocationType allocation, int size,
272 AllocationAlignment alignment);
273
274 // Cached current isolate.
275 IsolateT* isolate_;
276
277 // Objects from the attached object descriptions in the serialized user code.
279
282
290 std::vector<std::shared_ptr<BackingStore>> backing_stores_;
291
292 // Roots vector as those arrays are passed to Heap, see
293 // WeakenDescriptorArrays().
295
296 // Vector of allocated objects that can be accessed by a backref, by index.
297 std::vector<IndirectHandle<HeapObject>> back_refs_;
298
299 // Vector of already allocated JSDispatchTable entries.
300 std::vector<JSDispatchHandle> js_dispatch_entries_;
301
302 // Unresolved forward references (registered with kRegisterPendingForwardRef)
303 // are collected in order as (object, field offset) pairs. The subsequent
304 // forward ref resolution (with kResolvePendingForwardRef) accesses this
305 // vector by index.
306 //
307 // The vector is cleared when there are no more unresolved forward refs.
317 std::vector<UnresolvedForwardRef> unresolved_forward_refs_;
319
321
325
326 // TODO(6593): generalize rehashing, and remove this flag.
327 const bool should_rehash_;
329
330 // Do not collect any gc stats during deserialization since objects might
331 // be in an invalid state
333 public:
335 original_gc_stats_ = TracingFlags::gc_stats;
336 TracingFlags::gc_stats = 0;
337 }
338 ~DisableGCStats() { TracingFlags::gc_stats = original_gc_stats_; }
339
340 private:
341 unsigned int original_gc_stats_;
342 };
344
345 int depth_ = 0;
346
347#ifdef DEBUG
348 uint32_t num_api_references_;
349
350 // Record the previous object allocated for DCHECKs.
351 DirectHandle<HeapObject> previous_allocation_obj_;
352 int previous_allocation_size_ = 0;
353#endif // DEBUG
354};
355
360
361// Used to insert a deserialized internalized string into the string table.
363 public:
365 Isolate* isolate, DirectHandle<String> string,
366 DeserializingUserCodeOption deserializing_user_code);
368 LocalIsolate* isolate, DirectHandle<String> string,
369 DeserializingUserCodeOption deserializing_user_code);
370
371 template <typename IsolateT>
372 bool IsMatch(IsolateT* isolate, Tagged<String> string);
373
375 // When sharing the string table, all string table lookups during snapshot
376 // deserialization are hits.
377 DCHECK(isolate->OwnsStringTables() ||
378 deserializing_user_code_ ==
380 }
386
387 private:
389#ifdef DEBUG
390 DeserializingUserCodeOption deserializing_user_code_;
391#endif
393};
394
395} // namespace internal
396} // namespace v8
397
398#endif // V8_SNAPSHOT_DESERIALIZER_H_
#define DISALLOW_GARBAGE_COLLECTION(name)
HotObjectsList(const HotObjectsList &)=delete
HotObjectsList & operator=(const HotObjectsList &)=delete
DirectHandle< HeapObject > circular_queue_[kSize]
void Add(DirectHandle< HeapObject > object)
DirectHandle< HeapObject > Get(int index)
int ReadRootArray(uint8_t data, SlotAccessor slot_accessor)
int ReadApiReference(uint8_t data, SlotAccessor slot_accessor)
SnapshotByteSource source_
DirectHandleVector< HeapObject > to_rehash_
base::Vector< const DirectHandle< InstructionStream > > new_code_objects() const
int ReadReadOnlyHeapRef(uint8_t data, SlotAccessor slot_accessor)
base::Vector< const DirectHandle< AccessorInfo > > accessor_infos() const
int ReadSharedHeapObjectCache(uint8_t data, SlotAccessor slot_accessor)
DirectHandle< HeapObject > ReadObject()
Isolate * main_thread_isolate() const
void PostProcessNewObject(DirectHandle< Map > map, Handle< HeapObject > obj, SnapshotSpace space)
void LogScriptEvents(Tagged< Script > script)
SnapshotByteSource * source()
base::Vector< const DirectHandle< FunctionTemplateInfo > > function_template_infos() const
int ReadExternalReference(uint8_t data, SlotAccessor slot_accessor)
DirectHandleVector< AllocationSite > new_allocation_sites_
void Synchronize(VisitorSynchronization::SyncTag tag) override
base::Vector< const DirectHandle< AllocationSite > > new_allocation_sites() const
int ReadSingleBytecodeData(uint8_t data, SlotAccessor slot_accessor)
void PostProcessNewJSReceiver(Tagged< Map > map, DirectHandle< JSReceiver > obj, InstanceType instance_type, SnapshotSpace space)
int ReadRegisterPendingForwardRef(uint8_t data, SlotAccessor slot_accessor)
int ReadWeakPrefix(uint8_t data, SlotAccessor slot_accessor)
void VisitRootPointers(Root root, const char *description, FullObjectSlot start, FullObjectSlot end) override
int ReadResolvePendingForwardRef(uint8_t data, SlotAccessor slot_accessor)
int ReadClearedWeakReference(uint8_t data, SlotAccessor slot_accessor)
int ReadBackref(uint8_t data, SlotAccessor slot_accessor)
int WriteIndirectPointer(IndirectPointerSlot dest, Tagged< HeapObject > value)
int ReadAllocateJSDispatchEntry(uint8_t data, SlotAccessor slot_accessor)
int ReadRepeatedRoot(SlotGetter slot_getter, int repeat_count)
std::vector< std::shared_ptr< BackingStore > > backing_stores_
DirectHandleVector< Map > new_maps_
void PushObjectToRehash(DirectHandle< HeapObject > object)
int ReadOffHeapBackingStore(uint8_t data, SlotAccessor slot_accessor)
int ReadInitializeSelfIndirectPointer(uint8_t data, SlotAccessor slot_accessor)
int ReadStartupObjectCache(uint8_t data, SlotAccessor slot_accessor)
std::shared_ptr< BackingStore > backing_store(size_t i)
int ReadFixedRepeatRoot(uint8_t data, SlotAccessor slot_accessor)
Handle< HeapObject > ReadMetaMap(SnapshotSpace space)
DirectHandleVector< Script > new_scripts_
int ReadProtectedPointerPrefix(uint8_t data, SlotAccessor slot_accessor)
Deserializer & operator=(const Deserializer &)=delete
DirectHandleVector< HeapObject > attached_objects_
bool deserializing_user_code() const
int ReadFixedRawData(uint8_t data, SlotAccessor slot_accessor)
int ReadNewObject(uint8_t data, SlotAccessor slot_accessor)
int ReadJSDispatchEntry(uint8_t data, SlotAccessor slot_accessor)
DirectHandleVector< InstructionStream > new_code_objects_
ExternalPointerTag ReadExternalPointerTag()
int WriteExternalPointer(Tagged< HeapObject > host, ExternalPointerSlot dest, Address value, ExternalPointerTag tag)
std::vector< UnresolvedForwardRef > unresolved_forward_refs_
base::Vector< const DirectHandle< Map > > new_maps() const
std::vector< JSDispatchHandle > js_dispatch_entries_
IsolateT * isolate() const
int ReadVariableRawData(uint8_t data, SlotAccessor slot_accessor)
int ReadNewMetaMap(uint8_t data, SlotAccessor slot_accessor)
DirectHandleVector< AccessorInfo > accessor_infos_
int ReadHotObject(uint8_t data, SlotAccessor slot_accessor)
int ReadAttachedReference(uint8_t data, SlotAccessor slot_accessor)
std::vector< IndirectHandle< HeapObject > > back_refs_
int ReadVariableRepeatRoot(uint8_t data, SlotAccessor slot_accessor)
Tagged< HeapObject > Allocate(AllocationType allocation, int size, AllocationAlignment alignment)
void AddAttachedObject(DirectHandle< HeapObject > attached_object)
int WriteHeapPointer(SlotAccessor slot_accessor, Tagged< HeapObject > heap_object, ReferenceDescriptor descr, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
base::Vector< const DirectHandle< Script > > new_scripts() const
GlobalHandleVector< DescriptorArray > new_descriptor_arrays_
Deserializer(const Deserializer &)=delete
int ReadRawExternalReference(uint8_t data, SlotAccessor slot_accessor)
ReferenceDescriptor GetAndResetNextReferenceDescriptor()
int ReadIndirectPointerPrefix(uint8_t data, SlotAccessor slot_accessor)
void ReadData(Handle< HeapObject > object, int start_slot_index, int end_slot_index)
int ReadRootArrayConstants(uint8_t data, SlotAccessor slot_accessor)
Handle< HeapObject > GetBackReferencedObject()
DirectHandleVector< FunctionTemplateInfo > function_template_infos_
Isolate * AsIsolate()
Definition isolate.h:2187
bool IsMatch(IsolateT *isolate, Tagged< String > string)
StringTableInsertionKey(Isolate *isolate, DirectHandle< String > string, DeserializingUserCodeOption deserializing_user_code)
void PrepareForInsertion(LocalIsolate *isolate)
void PrepareForInsertion(Isolate *isolate)
V8_WARN_UNUSED_RESULT DirectHandle< String > GetHandleForInsertion(Isolate *isolate)
int start
int end
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
@ UPDATE_WRITE_BARRIER
Definition objects.h:55
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
UnresolvedForwardRef(Handle< HeapObject > object, int offset, ReferenceDescriptor descr)
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671
#define V8_NODISCARD
Definition v8config.h:693