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