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