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/objects/allocation-site.h" 12 #include "src/objects/api-callbacks.h" 13 #include "src/objects/backing-store.h" 14 #include "src/objects/code.h" 15 #include "src/objects/js-array.h" 16 #include "src/objects/map.h" 17 #include "src/objects/string.h" 18 #include "src/snapshot/deserializer-allocator.h" 19 #include "src/snapshot/serializer-common.h" 20 #include "src/snapshot/snapshot-source-sink.h" 21 22 namespace v8 { 23 namespace internal { 24 25 class HeapObject; 26 class Object; 27 28 // Used for platforms with embedded constant pools to trigger deserialization 29 // of objects found in code. 30 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ 31 defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_S390) || \ 32 defined(V8_TARGET_ARCH_PPC64) || V8_EMBEDDED_CONSTANT_POOL 33 #define V8_CODE_EMBEDS_OBJECT_POINTER 1 34 #else 35 #define V8_CODE_EMBEDS_OBJECT_POINTER 0 36 #endif 37 38 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 39 class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { 40 public: 41 ~Deserializer() override; 42 SetRehashability(bool v)43 void SetRehashability(bool v) { can_rehash_ = v; } GetChecksum()44 uint32_t GetChecksum() const { return source_.GetChecksum(); } 45 46 protected: 47 // Create a deserializer from a snapshot byte source. 48 template <class Data> Deserializer(Data * data,bool deserializing_user_code)49 Deserializer(Data* data, bool deserializing_user_code) 50 : isolate_(nullptr), 51 source_(data->Payload()), 52 magic_number_(data->GetMagicNumber()), 53 deserializing_user_code_(deserializing_user_code), 54 can_rehash_(false) { 55 allocator()->DecodeReservation(data->Reservations()); 56 // We start the indices here at 1, so that we can distinguish between an 57 // actual index and a nullptr in a deserialized object requiring fix-up. 58 backing_stores_.push_back({}); 59 } 60 61 void Initialize(Isolate* isolate); 62 void DeserializeDeferredObjects(); 63 64 // Create Log events for newly deserialized objects. 65 void LogNewObjectEvents(); 66 void LogScriptEvents(Script script); 67 void LogNewMapEvents(); 68 69 // This returns the address of an object that has been described in the 70 // snapshot by chunk index and offset. 71 HeapObject GetBackReferencedObject(SnapshotSpace space); 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. AddAttachedObject(Handle<HeapObject> attached_object)75 void AddAttachedObject(Handle<HeapObject> attached_object) { 76 attached_objects_.push_back(attached_object); 77 } 78 CheckNoArrayBufferBackingStores()79 void CheckNoArrayBufferBackingStores() { 80 CHECK_EQ(new_off_heap_array_buffers().size(), 0); 81 } 82 isolate()83 Isolate* isolate() const { return isolate_; } source()84 SnapshotByteSource* source() { return &source_; } new_allocation_sites()85 const std::vector<AllocationSite>& new_allocation_sites() const { 86 return new_allocation_sites_; 87 } new_code_objects()88 const std::vector<Code>& new_code_objects() const { 89 return new_code_objects_; 90 } new_maps()91 const std::vector<Map>& new_maps() const { return new_maps_; } accessor_infos()92 const std::vector<AccessorInfo>& accessor_infos() const { 93 return accessor_infos_; 94 } call_handler_infos()95 const std::vector<CallHandlerInfo>& call_handler_infos() const { 96 return call_handler_infos_; 97 } new_internalized_strings()98 const std::vector<Handle<String>>& new_internalized_strings() const { 99 return new_internalized_strings_; 100 } new_scripts()101 const std::vector<Handle<Script>>& new_scripts() const { 102 return new_scripts_; 103 } 104 new_off_heap_array_buffers()105 const std::vector<Handle<JSArrayBuffer>>& new_off_heap_array_buffers() const { 106 return new_off_heap_array_buffers_; 107 } 108 backing_store(size_t i)109 std::shared_ptr<BackingStore> backing_store(size_t i) { 110 return backing_stores_[i]; 111 } 112 allocator()113 DeserializerAllocator* allocator() { return &allocator_; } deserializing_user_code()114 bool deserializing_user_code() const { return deserializing_user_code_; } can_rehash()115 bool can_rehash() const { return can_rehash_; } 116 117 void Rehash(); 118 119 // Cached current isolate. 120 Isolate* isolate_; 121 122 private: 123 void VisitRootPointers(Root root, const char* description, 124 FullObjectSlot start, FullObjectSlot end) override; 125 126 void Synchronize(VisitorSynchronization::SyncTag tag) override; 127 128 template <typename TSlot> 129 inline TSlot Write(TSlot dest, MaybeObject value); 130 131 template <typename TSlot> 132 inline TSlot WriteAddress(TSlot dest, Address value); 133 134 // Fills in some heap data in an area from start to end (non-inclusive). The 135 // space id is used for the write barrier. The object_address is the address 136 // of the object we are writing into, or nullptr if we are not writing into an 137 // object, i.e. if we are writing a series of tagged values that are not on 138 // the heap. Return false if the object content has been deferred. 139 template <typename TSlot> 140 bool ReadData(TSlot start, TSlot end, SnapshotSpace space, 141 Address object_address); 142 143 // A helper function for ReadData, templatized on the bytecode for efficiency. 144 // Returns the new value of {current}. 145 template <typename TSlot, Bytecode bytecode, 146 SnapshotSpace space_number_if_any> 147 inline TSlot ReadDataCase(Isolate* isolate, TSlot current, 148 Address current_object_address, byte data, 149 bool write_barrier_needed); 150 151 // A helper function for ReadData for reading external references. 152 inline Address ReadExternalReferenceCase(); 153 154 HeapObject ReadObject(); 155 HeapObject ReadObject(SnapshotSpace space_number); 156 void ReadCodeObjectBody(SnapshotSpace space_number, 157 Address code_object_address); 158 159 public: 160 void VisitCodeTarget(Code host, RelocInfo* rinfo); 161 void VisitEmbeddedPointer(Code host, RelocInfo* rinfo); 162 void VisitRuntimeEntry(Code host, RelocInfo* rinfo); 163 void VisitExternalReference(Code host, RelocInfo* rinfo); 164 void VisitInternalReference(Code host, RelocInfo* rinfo); 165 void VisitOffHeapTarget(Code host, RelocInfo* rinfo); 166 167 private: 168 template <typename TSlot> 169 TSlot ReadRepeatedObject(TSlot current, int repeat_count); 170 171 // Special handling for serialized code like hooking up internalized strings. 172 HeapObject PostProcessNewObject(HeapObject obj, SnapshotSpace space); 173 174 // Objects from the attached object descriptions in the serialized user code. 175 std::vector<Handle<HeapObject>> attached_objects_; 176 177 SnapshotByteSource source_; 178 uint32_t magic_number_; 179 180 std::vector<Map> new_maps_; 181 std::vector<AllocationSite> new_allocation_sites_; 182 std::vector<Code> new_code_objects_; 183 std::vector<AccessorInfo> accessor_infos_; 184 std::vector<CallHandlerInfo> call_handler_infos_; 185 std::vector<Handle<String>> new_internalized_strings_; 186 std::vector<Handle<Script>> new_scripts_; 187 std::vector<Handle<JSArrayBuffer>> new_off_heap_array_buffers_; 188 std::vector<std::shared_ptr<BackingStore>> backing_stores_; 189 190 DeserializerAllocator allocator_; 191 const bool deserializing_user_code_; 192 193 // TODO(6593): generalize rehashing, and remove this flag. 194 bool can_rehash_; 195 std::vector<HeapObject> to_rehash_; 196 197 #ifdef DEBUG 198 uint32_t num_api_references_; 199 #endif // DEBUG 200 201 // For source(), isolate(), and allocator(). 202 friend class DeserializerAllocator; 203 204 DISALLOW_COPY_AND_ASSIGN(Deserializer); 205 }; 206 207 // Used to insert a deserialized internalized string into the string table. 208 class StringTableInsertionKey final : public StringTableKey { 209 public: 210 explicit StringTableInsertionKey(String string); 211 212 bool IsMatch(String string) override; 213 214 V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override; 215 string()216 String string() const { return string_; } 217 218 private: 219 uint32_t ComputeHashField(String string); 220 221 String string_; 222 DISALLOW_HEAP_ALLOCATION(no_gc) 223 }; 224 225 } // namespace internal 226 } // namespace v8 227 228 #endif // V8_SNAPSHOT_DESERIALIZER_H_ 229