1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
// 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 <vector>
#include "src/objects/js-array.h"
#include "src/snapshot/default-deserializer-allocator.h"
#include "src/snapshot/serializer-common.h"
#include "src/snapshot/snapshot-source-sink.h"
namespace v8 {
namespace internal {
class HeapObject;
class Object;
// 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
// A Deserializer reads a snapshot and reconstructs the Object graph it defines.
template <class AllocatorT = DefaultDeserializerAllocator>
class Deserializer : public SerializerDeserializer {
public:
~Deserializer() override;
void SetRehashability(bool v) { can_rehash_ = v; }
protected:
// Create a deserializer from a snapshot byte source.
template <class Data>
Deserializer(Data* data, bool deserializing_user_code)
: isolate_(nullptr),
source_(data->Payload()),
magic_number_(data->GetMagicNumber()),
external_reference_table_(nullptr),
allocator_(this),
deserializing_user_code_(deserializing_user_code),
can_rehash_(false) {
allocator()->DecodeReservation(data->Reservations());
// We start the indices here at 1, so that we can distinguish between an
// actual index and a nullptr in a deserialized object requiring fix-up.
off_heap_backing_stores_.push_back(nullptr);
}
void Initialize(Isolate* isolate);
void DeserializeDeferredObjects();
// Deserializes into a single pointer and returns the resulting object.
Object* ReadDataSingle();
// This returns the address of an object that has been described in the
// snapshot by chunk index and offset.
HeapObject* GetBackReferencedObject(int space);
// 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_.push_back(attached_object);
}
Isolate* isolate() const { return isolate_; }
SnapshotByteSource* source() { return &source_; }
const std::vector<Code*>& new_code_objects() const {
return new_code_objects_;
}
const std::vector<AccessorInfo*>& accessor_infos() const {
return accessor_infos_;
}
const std::vector<CallHandlerInfo*>& call_handler_infos() const {
return call_handler_infos_;
}
const std::vector<Handle<String>>& new_internalized_strings() const {
return new_internalized_strings_;
}
const std::vector<Handle<Script>>& new_scripts() const {
return new_scripts_;
}
AllocatorT* allocator() { return &allocator_; }
bool deserializing_user_code() const { return deserializing_user_code_; }
bool can_rehash() const { return can_rehash_; }
bool IsLazyDeserializationEnabled() const;
void Rehash();
private:
void VisitRootPointers(Root root, const char* description, Object** start,
Object** end) override;
void Synchronize(VisitorSynchronization::SyncTag tag) override;
template <typename T>
void UnalignedCopy(T** dest, T** src) {
DCHECK(!allocator()->next_reference_is_weak());
memcpy(dest, src, sizeof(*src));
}
// 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 nullptr 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(MaybeObject** start, MaybeObject** end, int space,
Address object_address);
// A helper function for ReadData, templatized on the bytecode for efficiency.
// Returns the new value of {current}.
template <int where, int how, int within, int space_number_if_any>
inline MaybeObject** ReadDataCase(Isolate* isolate, MaybeObject** current,
Address current_object_address, byte data,
bool write_barrier_needed);
// A helper function for ReadData for reading external references.
// Returns the new value of {current}.
inline void** ReadExternalReferenceCase(HowToCode how, void** current,
Address current_object_address);
void ReadObject(int space_number, MaybeObject** write_back,
HeapObjectReferenceType reference_type);
// Special handling for serialized code like hooking up internalized strings.
HeapObject* PostProcessNewObject(HeapObject* obj, int space);
// May replace the given builtin_id with the DeserializeLazy builtin for lazy
// deserialization.
int MaybeReplaceWithDeserializeLazy(int builtin_id);
// Cached current isolate.
Isolate* isolate_;
// Objects from the attached object descriptions in the serialized user code.
std::vector<Handle<HeapObject>> attached_objects_;
SnapshotByteSource source_;
uint32_t magic_number_;
ExternalReferenceTable* external_reference_table_;
std::vector<Code*> new_code_objects_;
std::vector<AccessorInfo*> accessor_infos_;
std::vector<CallHandlerInfo*> call_handler_infos_;
std::vector<Handle<String>> new_internalized_strings_;
std::vector<Handle<Script>> new_scripts_;
std::vector<byte*> off_heap_backing_stores_;
AllocatorT allocator_;
const bool deserializing_user_code_;
// TODO(6593): generalize rehashing, and remove this flag.
bool can_rehash_;
std::vector<HeapObject*> to_rehash_;
#ifdef DEBUG
uint32_t num_api_references_;
#endif // DEBUG
// For source(), isolate(), and allocator().
friend class DefaultDeserializerAllocator;
DISALLOW_COPY_AND_ASSIGN(Deserializer);
};
// Used to insert a deserialized internalized string into the string table.
class StringTableInsertionKey : public StringTableKey {
public:
explicit StringTableInsertionKey(String* string);
bool IsMatch(Object* string) override;
V8_WARN_UNUSED_RESULT Handle<String> AsHandle(Isolate* isolate) override;
private:
uint32_t ComputeHashField(String* string);
String* string_;
DisallowHeapAllocation no_gc;
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_DESERIALIZER_H_
|