// Copyright 2016 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_SNAPSHOT_DESERIALIZER_H_ #define V8_SNAPSHOT_DESERIALIZER_H_ #include "src/heap/heap.h" #include "src/objects.h" #include "src/snapshot/serializer-common.h" #include "src/snapshot/snapshot-source-sink.h" namespace v8 { namespace internal { // Used for platforms with embedded constant pools to trigger deserialization // of objects found in code. #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_S390) || \ V8_EMBEDDED_CONSTANT_POOL #define V8_CODE_EMBEDS_OBJECT_POINTER 1 #else #define V8_CODE_EMBEDS_OBJECT_POINTER 0 #endif class Heap; // A Deserializer reads a snapshot and reconstructs the Object graph it defines. class Deserializer : public SerializerDeserializer { public: // Create a deserializer from a snapshot byte source. template <class Data> explicit Deserializer(Data* data, bool deserializing_user_code = false) : isolate_(NULL), source_(data->Payload()), magic_number_(data->GetMagicNumber()), next_map_index_(0), external_reference_table_(NULL), deserialized_large_objects_(0), deserializing_user_code_(deserializing_user_code), next_alignment_(kWordAligned) { DecodeReservation(data->Reservations()); } ~Deserializer() override; // Deserialize the snapshot into an empty heap. void Deserialize(Isolate* isolate); // Deserialize a single object and the objects reachable from it. MaybeHandle<Object> DeserializePartial( Isolate* isolate, Handle<JSGlobalProxy> global_proxy, v8::DeserializeInternalFieldsCallback internal_fields_deserializer); // Deserialize an object graph. Fail gracefully. MaybeHandle<HeapObject> DeserializeObject(Isolate* isolate); // Add an object to back an attached reference. The order to add objects must // mirror the order they are added in the serializer. void AddAttachedObject(Handle<HeapObject> attached_object) { attached_objects_.Add(attached_object); } private: void VisitPointers(Object** start, Object** end) override; void Synchronize(VisitorSynchronization::SyncTag tag) override; void VisitRuntimeEntry(RelocInfo* rinfo) override { UNREACHABLE(); } void Initialize(Isolate* isolate); bool deserializing_user_code() { return deserializing_user_code_; } void DecodeReservation(Vector<const SerializedData::Reservation> res); bool ReserveSpace(); void UnalignedCopy(Object** dest, Object** src) { memcpy(dest, src, sizeof(*src)); } void SetAlignment(byte data) { DCHECK_EQ(kWordAligned, next_alignment_); int alignment = data - (kAlignmentPrefix - 1); DCHECK_LE(kWordAligned, alignment); DCHECK_LE(alignment, kDoubleUnaligned); next_alignment_ = static_cast<AllocationAlignment>(alignment); } void DeserializeDeferredObjects(); void DeserializeInternalFields( v8::DeserializeInternalFieldsCallback internal_fields_deserializer); void FlushICacheForNewIsolate(); void FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects(); void CommitPostProcessedObjects(Isolate* isolate); // Fills in some heap data in an area from start to end (non-inclusive). The // space id is used for the write barrier. The object_address is the address // of the object we are writing into, or NULL if we are not writing into an // object, i.e. if we are writing a series of tagged values that are not on // the heap. Return false if the object content has been deferred. bool ReadData(Object** start, Object** end, int space, Address object_address); void ReadObject(int space_number, Object** write_back); Address Allocate(int space_index, int size); // Special handling for serialized code like hooking up internalized strings. HeapObject* PostProcessNewObject(HeapObject* obj, int space); // This returns the address of an object that has been described in the // snapshot by chunk index and offset. HeapObject* GetBackReferencedObject(int space); Object** CopyInNativesSource(Vector<const char> source_vector, Object** current); // Cached current isolate. Isolate* isolate_; // Objects from the attached object descriptions in the serialized user code. List<Handle<HeapObject> > attached_objects_; SnapshotByteSource source_; uint32_t magic_number_; // The address of the next object that will be allocated in each space. // Each space has a number of chunks reserved by the GC, with each chunk // fitting into a page. Deserialized objects are allocated into the // current chunk of the target space by bumping up high water mark. Heap::Reservation reservations_[kNumberOfSpaces]; uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; Address high_water_[kNumberOfPreallocatedSpaces]; int next_map_index_; List<Address> allocated_maps_; ExternalReferenceTable* external_reference_table_; List<HeapObject*> deserialized_large_objects_; List<Code*> new_code_objects_; List<AccessorInfo*> accessor_infos_; List<Handle<String> > new_internalized_strings_; List<Handle<Script> > new_scripts_; bool deserializing_user_code_; AllocationAlignment next_alignment_; DISALLOW_COPY_AND_ASSIGN(Deserializer); }; } // namespace internal } // namespace v8 #endif // V8_SNAPSHOT_DESERIALIZER_H_