• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <vector>
9 
10 #include "src/objects/js-array.h"
11 #include "src/snapshot/default-deserializer-allocator.h"
12 #include "src/snapshot/serializer-common.h"
13 #include "src/snapshot/snapshot-source-sink.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 class HeapObject;
19 class Object;
20 
21 // Used for platforms with embedded constant pools to trigger deserialization
22 // of objects found in code.
23 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \
24     defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_S390) ||    \
25     V8_EMBEDDED_CONSTANT_POOL
26 #define V8_CODE_EMBEDS_OBJECT_POINTER 1
27 #else
28 #define V8_CODE_EMBEDS_OBJECT_POINTER 0
29 #endif
30 
31 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
32 template <class AllocatorT = DefaultDeserializerAllocator>
33 class Deserializer : public SerializerDeserializer {
34  public:
35   ~Deserializer() override;
36 
SetRehashability(bool v)37   void SetRehashability(bool v) { can_rehash_ = v; }
38 
39  protected:
40   // Create a deserializer from a snapshot byte source.
41   template <class Data>
Deserializer(Data * data,bool deserializing_user_code)42   Deserializer(Data* data, bool deserializing_user_code)
43       : isolate_(nullptr),
44         source_(data->Payload()),
45         magic_number_(data->GetMagicNumber()),
46         external_reference_table_(nullptr),
47         allocator_(this),
48         deserializing_user_code_(deserializing_user_code),
49         can_rehash_(false) {
50     allocator()->DecodeReservation(data->Reservations());
51     // We start the indices here at 1, so that we can distinguish between an
52     // actual index and a nullptr in a deserialized object requiring fix-up.
53     off_heap_backing_stores_.push_back(nullptr);
54   }
55 
56   void Initialize(Isolate* isolate);
57   void DeserializeDeferredObjects();
58 
59   // Deserializes into a single pointer and returns the resulting object.
60   Object* ReadDataSingle();
61 
62   // This returns the address of an object that has been described in the
63   // snapshot by chunk index and offset.
64   HeapObject* GetBackReferencedObject(int space);
65 
66   // Add an object to back an attached reference. The order to add objects must
67   // mirror the order they are added in the serializer.
AddAttachedObject(Handle<HeapObject> attached_object)68   void AddAttachedObject(Handle<HeapObject> attached_object) {
69     attached_objects_.push_back(attached_object);
70   }
71 
isolate()72   Isolate* isolate() const { return isolate_; }
source()73   SnapshotByteSource* source() { return &source_; }
new_code_objects()74   const std::vector<Code*>& new_code_objects() const {
75     return new_code_objects_;
76   }
accessor_infos()77   const std::vector<AccessorInfo*>& accessor_infos() const {
78     return accessor_infos_;
79   }
call_handler_infos()80   const std::vector<CallHandlerInfo*>& call_handler_infos() const {
81     return call_handler_infos_;
82   }
new_internalized_strings()83   const std::vector<Handle<String>>& new_internalized_strings() const {
84     return new_internalized_strings_;
85   }
new_scripts()86   const std::vector<Handle<Script>>& new_scripts() const {
87     return new_scripts_;
88   }
89 
allocator()90   AllocatorT* allocator() { return &allocator_; }
deserializing_user_code()91   bool deserializing_user_code() const { return deserializing_user_code_; }
can_rehash()92   bool can_rehash() const { return can_rehash_; }
93 
94   bool IsLazyDeserializationEnabled() const;
95 
96   void Rehash();
97 
98  private:
99   void VisitRootPointers(Root root, const char* description, Object** start,
100                          Object** end) override;
101 
102   void Synchronize(VisitorSynchronization::SyncTag tag) override;
103 
104   template <typename T>
UnalignedCopy(T ** dest,T ** src)105   void UnalignedCopy(T** dest, T** src) {
106     DCHECK(!allocator()->next_reference_is_weak());
107     memcpy(dest, src, sizeof(*src));
108   }
109 
110   // Fills in some heap data in an area from start to end (non-inclusive).  The
111   // space id is used for the write barrier.  The object_address is the address
112   // of the object we are writing into, or nullptr if we are not writing into an
113   // object, i.e. if we are writing a series of tagged values that are not on
114   // the heap. Return false if the object content has been deferred.
115   bool ReadData(MaybeObject** start, MaybeObject** end, int space,
116                 Address object_address);
117 
118   // A helper function for ReadData, templatized on the bytecode for efficiency.
119   // Returns the new value of {current}.
120   template <int where, int how, int within, int space_number_if_any>
121   inline MaybeObject** ReadDataCase(Isolate* isolate, MaybeObject** current,
122                                     Address current_object_address, byte data,
123                                     bool write_barrier_needed);
124 
125   // A helper function for ReadData for reading external references.
126   // Returns the new value of {current}.
127   inline void** ReadExternalReferenceCase(HowToCode how, void** current,
128                                           Address current_object_address);
129 
130   void ReadObject(int space_number, MaybeObject** write_back,
131                   HeapObjectReferenceType reference_type);
132 
133   // Special handling for serialized code like hooking up internalized strings.
134   HeapObject* PostProcessNewObject(HeapObject* obj, int space);
135 
136   // May replace the given builtin_id with the DeserializeLazy builtin for lazy
137   // deserialization.
138   int MaybeReplaceWithDeserializeLazy(int builtin_id);
139 
140   // Cached current isolate.
141   Isolate* isolate_;
142 
143   // Objects from the attached object descriptions in the serialized user code.
144   std::vector<Handle<HeapObject>> attached_objects_;
145 
146   SnapshotByteSource source_;
147   uint32_t magic_number_;
148 
149   ExternalReferenceTable* external_reference_table_;
150 
151   std::vector<Code*> new_code_objects_;
152   std::vector<AccessorInfo*> accessor_infos_;
153   std::vector<CallHandlerInfo*> call_handler_infos_;
154   std::vector<Handle<String>> new_internalized_strings_;
155   std::vector<Handle<Script>> new_scripts_;
156   std::vector<byte*> off_heap_backing_stores_;
157 
158   AllocatorT allocator_;
159   const bool deserializing_user_code_;
160 
161   // TODO(6593): generalize rehashing, and remove this flag.
162   bool can_rehash_;
163   std::vector<HeapObject*> to_rehash_;
164 
165 #ifdef DEBUG
166   uint32_t num_api_references_;
167 #endif  // DEBUG
168 
169   // For source(), isolate(), and allocator().
170   friend class DefaultDeserializerAllocator;
171 
172   DISALLOW_COPY_AND_ASSIGN(Deserializer);
173 };
174 
175 // Used to insert a deserialized internalized string into the string table.
176 class StringTableInsertionKey : public StringTableKey {
177  public:
178   explicit StringTableInsertionKey(String* string);
179 
180   bool IsMatch(Object* string) override;
181 
182   V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override;
183 
184  private:
185   uint32_t ComputeHashField(String* string);
186 
187   String* string_;
188   DisallowHeapAllocation no_gc;
189 };
190 
191 }  // namespace internal
192 }  // namespace v8
193 
194 #endif  // V8_SNAPSHOT_DESERIALIZER_H_
195