Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/snapshot/serializer.h

Issue 1751863002: [serializer] split up src/snapshot/serialize.* (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_SERIALIZER_H_
6 #define V8_SNAPSHOT_SERIALIZER_H_
7
8 #include "src/isolate.h"
9 #include "src/log.h"
10 #include "src/objects.h"
11 #include "src/snapshot/serializer-common.h"
12 #include "src/snapshot/snapshot-source-sink.h"
13
14 namespace v8 {
15 namespace internal {
16
17 class CodeAddressMap : public CodeEventLogger {
18 public:
19 explicit CodeAddressMap(Isolate* isolate) : isolate_(isolate) {
20 isolate->logger()->addCodeEventListener(this);
21 }
22
23 ~CodeAddressMap() override {
24 isolate_->logger()->removeCodeEventListener(this);
25 }
26
27 void CodeMoveEvent(AbstractCode* from, Address to) override {
28 address_to_name_map_.Move(from->address(), to);
29 }
30
31 void CodeDisableOptEvent(AbstractCode* code,
32 SharedFunctionInfo* shared) override {}
33
34 const char* Lookup(Address address) {
35 return address_to_name_map_.Lookup(address);
36 }
37
38 private:
39 class NameMap {
40 public:
41 NameMap() : impl_(HashMap::PointersMatch) {}
42
43 ~NameMap() {
44 for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
45 DeleteArray(static_cast<const char*>(p->value));
46 }
47 }
48
49 void Insert(Address code_address, const char* name, int name_size) {
50 HashMap::Entry* entry = FindOrCreateEntry(code_address);
51 if (entry->value == NULL) {
52 entry->value = CopyName(name, name_size);
53 }
54 }
55
56 const char* Lookup(Address code_address) {
57 HashMap::Entry* entry = FindEntry(code_address);
58 return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
59 }
60
61 void Remove(Address code_address) {
62 HashMap::Entry* entry = FindEntry(code_address);
63 if (entry != NULL) {
64 DeleteArray(static_cast<char*>(entry->value));
65 RemoveEntry(entry);
66 }
67 }
68
69 void Move(Address from, Address to) {
70 if (from == to) return;
71 HashMap::Entry* from_entry = FindEntry(from);
72 DCHECK(from_entry != NULL);
73 void* value = from_entry->value;
74 RemoveEntry(from_entry);
75 HashMap::Entry* to_entry = FindOrCreateEntry(to);
76 DCHECK(to_entry->value == NULL);
77 to_entry->value = value;
78 }
79
80 private:
81 static char* CopyName(const char* name, int name_size) {
82 char* result = NewArray<char>(name_size + 1);
83 for (int i = 0; i < name_size; ++i) {
84 char c = name[i];
85 if (c == '\0') c = ' ';
86 result[i] = c;
87 }
88 result[name_size] = '\0';
89 return result;
90 }
91
92 HashMap::Entry* FindOrCreateEntry(Address code_address) {
93 return impl_.LookupOrInsert(code_address,
94 ComputePointerHash(code_address));
95 }
96
97 HashMap::Entry* FindEntry(Address code_address) {
98 return impl_.Lookup(code_address, ComputePointerHash(code_address));
99 }
100
101 void RemoveEntry(HashMap::Entry* entry) {
102 impl_.Remove(entry->key, entry->hash);
103 }
104
105 HashMap impl_;
106
107 DISALLOW_COPY_AND_ASSIGN(NameMap);
108 };
109
110 void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*,
111 const char* name, int length) override {
112 address_to_name_map_.Insert(code->address(), name, length);
113 }
114
115 NameMap address_to_name_map_;
116 Isolate* isolate_;
117 };
118
119 // There can be only one serializer per V8 process.
120 class Serializer : public SerializerDeserializer {
121 public:
122 Serializer(Isolate* isolate, SnapshotByteSink* sink);
123 ~Serializer() override;
124
125 void EncodeReservations(List<SerializedData::Reservation>* out) const;
126
127 void SerializeDeferredObjects();
128
129 Isolate* isolate() const { return isolate_; }
130
131 BackReferenceMap* back_reference_map() { return &back_reference_map_; }
132 RootIndexMap* root_index_map() { return &root_index_map_; }
133
134 #ifdef OBJECT_PRINT
135 void CountInstanceType(Map* map, int size);
136 #endif // OBJECT_PRINT
137
138 protected:
139 class ObjectSerializer;
140 class RecursionScope {
141 public:
142 explicit RecursionScope(Serializer* serializer) : serializer_(serializer) {
143 serializer_->recursion_depth_++;
144 }
145 ~RecursionScope() { serializer_->recursion_depth_--; }
146 bool ExceedsMaximum() {
147 return serializer_->recursion_depth_ >= kMaxRecursionDepth;
148 }
149
150 private:
151 static const int kMaxRecursionDepth = 32;
152 Serializer* serializer_;
153 };
154
155 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
156 WhereToPoint where_to_point, int skip) = 0;
157
158 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
159 int skip);
160
161 void PutBackReference(HeapObject* object, BackReference reference);
162
163 // Emit alignment prefix if necessary, return required padding space in bytes.
164 int PutAlignmentPrefix(HeapObject* object);
165
166 // Returns true if the object was successfully serialized.
167 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
168 WhereToPoint where_to_point, int skip);
169
170 inline void FlushSkip(int skip) {
171 if (skip != 0) {
172 sink_->Put(kSkip, "SkipFromSerializeObject");
173 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
174 }
175 }
176
177 bool BackReferenceIsAlreadyAllocated(BackReference back_reference);
178
179 // This will return the space for an object.
180 BackReference AllocateLargeObject(int size);
181 BackReference Allocate(AllocationSpace space, int size);
182 int EncodeExternalReference(Address addr) {
183 return external_reference_encoder_.Encode(addr);
184 }
185
186 // GetInt reads 4 bytes at once, requiring padding at the end.
187 void Pad();
188
189 // Some roots should not be serialized, because their actual value depends on
190 // absolute addresses and they are reset after deserialization, anyway.
191 bool ShouldBeSkipped(Object** current);
192
193 // We may not need the code address map for logging for every instance
194 // of the serializer. Initialize it on demand.
195 void InitializeCodeAddressMap();
196
197 Code* CopyCode(Code* code);
198
199 inline uint32_t max_chunk_size(int space) const {
200 DCHECK_LE(0, space);
201 DCHECK_LT(space, kNumberOfSpaces);
202 return max_chunk_size_[space];
203 }
204
205 SnapshotByteSink* sink() const { return sink_; }
206
207 void QueueDeferredObject(HeapObject* obj) {
208 DCHECK(back_reference_map_.Lookup(obj).is_valid());
209 deferred_objects_.Add(obj);
210 }
211
212 void OutputStatistics(const char* name);
213
214 Isolate* isolate_;
215
216 SnapshotByteSink* sink_;
217 ExternalReferenceEncoder external_reference_encoder_;
218
219 BackReferenceMap back_reference_map_;
220 RootIndexMap root_index_map_;
221
222 int recursion_depth_;
223
224 friend class Deserializer;
225 friend class ObjectSerializer;
226 friend class RecursionScope;
227 friend class SnapshotData;
228
229 private:
230 void VisitPointers(Object** start, Object** end) override;
231
232 CodeAddressMap* code_address_map_;
233 // Objects from the same space are put into chunks for bulk-allocation
234 // when deserializing. We have to make sure that each chunk fits into a
235 // page. So we track the chunk size in pending_chunk_ of a space, but
236 // when it exceeds a page, we complete the current chunk and start a new one.
237 uint32_t pending_chunk_[kNumberOfPreallocatedSpaces];
238 List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces];
239 uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces];
240
241 // We map serialized large objects to indexes for back-referencing.
242 uint32_t large_objects_total_size_;
243 uint32_t seen_large_objects_index_;
244
245 List<byte> code_buffer_;
246
247 // To handle stack overflow.
248 List<HeapObject*> deferred_objects_;
249
250 #ifdef OBJECT_PRINT
251 static const int kInstanceTypes = 256;
252 int* instance_type_count_;
253 size_t* instance_type_size_;
254 #endif // OBJECT_PRINT
255
256 DISALLOW_COPY_AND_ASSIGN(Serializer);
257 };
258
259 class Serializer::ObjectSerializer : public ObjectVisitor {
260 public:
261 ObjectSerializer(Serializer* serializer, HeapObject* obj,
262 SnapshotByteSink* sink, HowToCode how_to_code,
263 WhereToPoint where_to_point)
264 : serializer_(serializer),
265 object_(obj),
266 sink_(sink),
267 reference_representation_(how_to_code + where_to_point),
268 bytes_processed_so_far_(0),
269 code_has_been_output_(false) {}
270 ~ObjectSerializer() override {}
271 void Serialize();
272 void SerializeDeferred();
273 void VisitPointers(Object** start, Object** end) override;
274 void VisitEmbeddedPointer(RelocInfo* target) override;
275 void VisitExternalReference(Address* p) override;
276 void VisitExternalReference(RelocInfo* rinfo) override;
277 void VisitInternalReference(RelocInfo* rinfo) override;
278 void VisitCodeTarget(RelocInfo* target) override;
279 void VisitCodeEntry(Address entry_address) override;
280 void VisitCell(RelocInfo* rinfo) override;
281 void VisitRuntimeEntry(RelocInfo* reloc) override;
282 // Used for seralizing the external strings that hold the natives source.
283 void VisitExternalOneByteString(
284 v8::String::ExternalOneByteStringResource** resource) override;
285 // We can't serialize a heap with external two byte strings.
286 void VisitExternalTwoByteString(
287 v8::String::ExternalStringResource** resource) override {
288 UNREACHABLE();
289 }
290
291 private:
292 void SerializePrologue(AllocationSpace space, int size, Map* map);
293
294 bool SerializeExternalNativeSourceString(
295 int builtin_count,
296 v8::String::ExternalOneByteStringResource** resource_pointer,
297 FixedArray* source_cache, int resource_index);
298
299 enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn };
300 // This function outputs or skips the raw data between the last pointer and
301 // up to the current position. It optionally can just return the number of
302 // bytes to skip instead of performing a skip instruction, in case the skip
303 // can be merged into the next instruction.
304 int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn);
305 // External strings are serialized in a way to resemble sequential strings.
306 void SerializeExternalString();
307
308 Address PrepareCode();
309
310 Serializer* serializer_;
311 HeapObject* object_;
312 SnapshotByteSink* sink_;
313 int reference_representation_;
314 int bytes_processed_so_far_;
315 bool code_has_been_output_;
316 };
317
318 } // namespace internal
319 } // namespace v8
320
321 #endif // V8_SNAPSHOT_SERIALIZER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698