Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 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 "src/heap/heap.h" |
| 9 | #include "src/objects.h" |
| 10 | #include "src/snapshot/serializer-common.h" |
| 11 | #include "src/snapshot/snapshot-source-sink.h" |
| 12 | |
| 13 | namespace v8 { |
| 14 | namespace internal { |
| 15 | |
| 16 | // Used for platforms with embedded constant pools to trigger deserialization |
| 17 | // of objects found in code. |
| 18 | #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ |
| 19 | defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_S390) || \ |
| 20 | V8_EMBEDDED_CONSTANT_POOL |
| 21 | #define V8_CODE_EMBEDS_OBJECT_POINTER 1 |
| 22 | #else |
| 23 | #define V8_CODE_EMBEDS_OBJECT_POINTER 0 |
| 24 | #endif |
| 25 | |
| 26 | class Heap; |
| 27 | |
| 28 | // A Deserializer reads a snapshot and reconstructs the Object graph it defines. |
| 29 | class Deserializer : public SerializerDeserializer { |
| 30 | public: |
| 31 | // Create a deserializer from a snapshot byte source. |
| 32 | template <class Data> |
| 33 | explicit Deserializer(Data* data) |
| 34 | : isolate_(NULL), |
| 35 | source_(data->Payload()), |
| 36 | magic_number_(data->GetMagicNumber()), |
| 37 | external_reference_table_(NULL), |
| 38 | deserialized_large_objects_(0), |
| 39 | deserializing_user_code_(false), |
| 40 | next_alignment_(kWordAligned) { |
| 41 | DecodeReservation(data->Reservations()); |
| 42 | } |
| 43 | |
| 44 | ~Deserializer() override; |
| 45 | |
| 46 | // Deserialize the snapshot into an empty heap. |
| 47 | void Deserialize(Isolate* isolate); |
| 48 | |
| 49 | // Deserialize a single object and the objects reachable from it. |
| 50 | MaybeHandle<Object> DeserializePartial(Isolate* isolate, |
| 51 | Handle<JSGlobalProxy> global_proxy); |
| 52 | |
| 53 | // Deserialize a shared function info. Fail gracefully. |
| 54 | MaybeHandle<SharedFunctionInfo> DeserializeCode(Isolate* isolate); |
| 55 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 56 | // Add an object to back an attached reference. The order to add objects must |
| 57 | // mirror the order they are added in the serializer. |
| 58 | void AddAttachedObject(Handle<HeapObject> attached_object) { |
| 59 | attached_objects_.Add(attached_object); |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | private: |
| 63 | void VisitPointers(Object** start, Object** end) override; |
| 64 | |
| 65 | void Synchronize(VisitorSynchronization::SyncTag tag) override; |
| 66 | |
| 67 | void VisitRuntimeEntry(RelocInfo* rinfo) override { UNREACHABLE(); } |
| 68 | |
| 69 | void Initialize(Isolate* isolate); |
| 70 | |
| 71 | bool deserializing_user_code() { return deserializing_user_code_; } |
| 72 | |
| 73 | void DecodeReservation(Vector<const SerializedData::Reservation> res); |
| 74 | |
| 75 | bool ReserveSpace(); |
| 76 | |
| 77 | void UnalignedCopy(Object** dest, Object** src) { |
| 78 | memcpy(dest, src, sizeof(*src)); |
| 79 | } |
| 80 | |
| 81 | void SetAlignment(byte data) { |
| 82 | DCHECK_EQ(kWordAligned, next_alignment_); |
| 83 | int alignment = data - (kAlignmentPrefix - 1); |
| 84 | DCHECK_LE(kWordAligned, alignment); |
| 85 | DCHECK_LE(alignment, kSimd128Unaligned); |
| 86 | next_alignment_ = static_cast<AllocationAlignment>(alignment); |
| 87 | } |
| 88 | |
| 89 | void DeserializeDeferredObjects(); |
| 90 | |
| 91 | void FlushICacheForNewIsolate(); |
| 92 | void FlushICacheForNewCodeObjects(); |
| 93 | |
| 94 | void CommitPostProcessedObjects(Isolate* isolate); |
| 95 | |
| 96 | // Fills in some heap data in an area from start to end (non-inclusive). The |
| 97 | // space id is used for the write barrier. The object_address is the address |
| 98 | // of the object we are writing into, or NULL if we are not writing into an |
| 99 | // object, i.e. if we are writing a series of tagged values that are not on |
| 100 | // the heap. Return false if the object content has been deferred. |
| 101 | bool ReadData(Object** start, Object** end, int space, |
| 102 | Address object_address); |
| 103 | void ReadObject(int space_number, Object** write_back); |
| 104 | Address Allocate(int space_index, int size); |
| 105 | |
| 106 | // Special handling for serialized code like hooking up internalized strings. |
| 107 | HeapObject* PostProcessNewObject(HeapObject* obj, int space); |
| 108 | |
| 109 | // This returns the address of an object that has been described in the |
| 110 | // snapshot by chunk index and offset. |
| 111 | HeapObject* GetBackReferencedObject(int space); |
| 112 | |
| 113 | Object** CopyInNativesSource(Vector<const char> source_vector, |
| 114 | Object** current); |
| 115 | |
| 116 | // Cached current isolate. |
| 117 | Isolate* isolate_; |
| 118 | |
| 119 | // Objects from the attached object descriptions in the serialized user code. |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 120 | List<Handle<HeapObject> > attached_objects_; |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 121 | |
| 122 | SnapshotByteSource source_; |
| 123 | uint32_t magic_number_; |
| 124 | |
| 125 | // The address of the next object that will be allocated in each space. |
| 126 | // Each space has a number of chunks reserved by the GC, with each chunk |
| 127 | // fitting into a page. Deserialized objects are allocated into the |
| 128 | // current chunk of the target space by bumping up high water mark. |
| 129 | Heap::Reservation reservations_[kNumberOfSpaces]; |
| 130 | uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; |
| 131 | Address high_water_[kNumberOfPreallocatedSpaces]; |
| 132 | |
| 133 | ExternalReferenceTable* external_reference_table_; |
| 134 | |
| 135 | List<HeapObject*> deserialized_large_objects_; |
| 136 | List<Code*> new_code_objects_; |
| 137 | List<Handle<String> > new_internalized_strings_; |
| 138 | List<Handle<Script> > new_scripts_; |
| 139 | |
| 140 | bool deserializing_user_code_; |
| 141 | |
| 142 | AllocationAlignment next_alignment_; |
| 143 | |
| 144 | DISALLOW_COPY_AND_ASSIGN(Deserializer); |
| 145 | }; |
| 146 | |
| 147 | } // namespace internal |
| 148 | } // namespace v8 |
| 149 | |
| 150 | #endif // V8_SNAPSHOT_DESERIALIZER_H_ |