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.cc

Issue 1992723002: [serializer] prepare attached references for general use. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: address comments Created 4 years, 7 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
« no previous file with comments | « src/snapshot/serializer.h ('k') | src/snapshot/serializer-common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/snapshot/serializer.h" 5 #include "src/snapshot/serializer.h"
6 6
7 #include "src/macro-assembler.h" 7 #include "src/macro-assembler.h"
8 #include "src/snapshot/natives.h" 8 #include "src/snapshot/natives.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 out->Add(SerializedData::Reservation(pending_chunk_[i])); 117 out->Add(SerializedData::Reservation(pending_chunk_[i]));
118 } 118 }
119 out->last().mark_as_last(); 119 out->last().mark_as_last();
120 } 120 }
121 121
122 out->Add(SerializedData::Reservation(large_objects_total_size_)); 122 out->Add(SerializedData::Reservation(large_objects_total_size_));
123 out->last().mark_as_last(); 123 out->last().mark_as_last();
124 } 124 }
125 125
126 #ifdef DEBUG 126 #ifdef DEBUG
127 bool Serializer::BackReferenceIsAlreadyAllocated(BackReference reference) { 127 bool Serializer::BackReferenceIsAlreadyAllocated(
128 DCHECK(reference.is_valid()); 128 SerializerReference reference) {
129 DCHECK(!reference.is_source()); 129 DCHECK(reference.is_back_reference());
130 DCHECK(!reference.is_global_proxy());
131 AllocationSpace space = reference.space(); 130 AllocationSpace space = reference.space();
132 int chunk_index = reference.chunk_index(); 131 int chunk_index = reference.chunk_index();
133 if (space == LO_SPACE) { 132 if (space == LO_SPACE) {
134 return chunk_index == 0 && 133 return chunk_index == 0 &&
135 reference.large_object_index() < seen_large_objects_index_; 134 reference.large_object_index() < seen_large_objects_index_;
136 } else if (chunk_index == completed_chunks_[space].length()) { 135 } else if (chunk_index == completed_chunks_[space].length()) {
137 return reference.chunk_offset() < pending_chunk_[space]; 136 return reference.chunk_offset() < pending_chunk_[space];
138 } else { 137 } else {
139 return chunk_index < completed_chunks_[space].length() && 138 return chunk_index < completed_chunks_[space].length() &&
140 reference.chunk_offset() < completed_chunks_[space][chunk_index]; 139 reference.chunk_offset() < completed_chunks_[space][chunk_index];
(...skipping 15 matching lines...) Expand all
156 } 155 }
157 if (skip != 0) { 156 if (skip != 0) {
158 sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip"); 157 sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
159 sink_->PutInt(skip, "HotObjectSkipDistance"); 158 sink_->PutInt(skip, "HotObjectSkipDistance");
160 } else { 159 } else {
161 sink_->Put(kHotObject + index, "HotObject"); 160 sink_->Put(kHotObject + index, "HotObject");
162 } 161 }
163 return true; 162 return true;
164 } 163 }
165 } 164 }
166 BackReference back_reference = back_reference_map_.Lookup(obj); 165 SerializerReference reference = reference_map_.Lookup(obj);
167 if (back_reference.is_valid()) { 166 if (reference.is_valid()) {
168 // Encode the location of an already deserialized object in order to write 167 // Encode the location of an already deserialized object in order to write
169 // its location into a later object. We can encode the location as an 168 // its location into a later object. We can encode the location as an
170 // offset fromthe start of the deserialized objects or as an offset 169 // offset fromthe start of the deserialized objects or as an offset
171 // backwards from thecurrent allocation pointer. 170 // backwards from thecurrent allocation pointer.
172 if (back_reference.is_source()) { 171 if (reference.is_attached_reference()) {
173 FlushSkip(skip); 172 FlushSkip(skip);
174 if (FLAG_trace_serializer) PrintF(" Encoding source object\n"); 173 if (FLAG_trace_serializer) {
175 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); 174 PrintF(" Encoding attached reference %d\n",
176 sink_->Put(kAttachedReference + kPlain + kStartOfObject, "Source"); 175 reference.attached_reference_index());
177 sink_->PutInt(kSourceObjectReference, "kSourceObjectReference"); 176 }
178 } else if (back_reference.is_global_proxy()) { 177 PutAttachedReference(reference, how_to_code, where_to_point);
179 FlushSkip(skip);
180 if (FLAG_trace_serializer) PrintF(" Encoding global proxy\n");
181 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
182 sink_->Put(kAttachedReference + kPlain + kStartOfObject, "Global Proxy");
183 sink_->PutInt(kGlobalProxyReference, "kGlobalProxyReference");
184 } else { 178 } else {
179 DCHECK(reference.is_back_reference());
185 if (FLAG_trace_serializer) { 180 if (FLAG_trace_serializer) {
186 PrintF(" Encoding back reference to: "); 181 PrintF(" Encoding back reference to: ");
187 obj->ShortPrint(); 182 obj->ShortPrint();
188 PrintF("\n"); 183 PrintF("\n");
189 } 184 }
190 185
191 PutAlignmentPrefix(obj); 186 PutAlignmentPrefix(obj);
192 AllocationSpace space = back_reference.space(); 187 AllocationSpace space = reference.space();
193 if (skip == 0) { 188 if (skip == 0) {
194 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef"); 189 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef");
195 } else { 190 } else {
196 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, 191 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
197 "BackRefWithSkip"); 192 "BackRefWithSkip");
198 sink_->PutInt(skip, "BackRefSkipDistance"); 193 sink_->PutInt(skip, "BackRefSkipDistance");
199 } 194 }
200 PutBackReference(obj, back_reference); 195 PutBackReference(obj, reference);
201 } 196 }
202 return true; 197 return true;
203 } 198 }
204 return false; 199 return false;
205 } 200 }
206 201
207 void Serializer::PutRoot(int root_index, HeapObject* object, 202 void Serializer::PutRoot(int root_index, HeapObject* object,
208 SerializerDeserializer::HowToCode how_to_code, 203 SerializerDeserializer::HowToCode how_to_code,
209 SerializerDeserializer::WhereToPoint where_to_point, 204 SerializerDeserializer::WhereToPoint where_to_point,
210 int skip) { 205 int skip) {
(...skipping 18 matching lines...) Expand all
229 sink_->PutInt(root_index, "root_index"); 224 sink_->PutInt(root_index, "root_index");
230 } 225 }
231 } 226 }
232 227
233 void Serializer::PutSmi(Smi* smi) { 228 void Serializer::PutSmi(Smi* smi) {
234 sink_->Put(kOnePointerRawData, "Smi"); 229 sink_->Put(kOnePointerRawData, "Smi");
235 byte* bytes = reinterpret_cast<byte*>(&smi); 230 byte* bytes = reinterpret_cast<byte*>(&smi);
236 for (int i = 0; i < kPointerSize; i++) sink_->Put(bytes[i], "Byte"); 231 for (int i = 0; i < kPointerSize; i++) sink_->Put(bytes[i], "Byte");
237 } 232 }
238 233
239 void Serializer::PutBackReference(HeapObject* object, BackReference reference) { 234 void Serializer::PutBackReference(HeapObject* object,
235 SerializerReference reference) {
240 DCHECK(BackReferenceIsAlreadyAllocated(reference)); 236 DCHECK(BackReferenceIsAlreadyAllocated(reference));
241 sink_->PutInt(reference.reference(), "BackRefValue"); 237 sink_->PutInt(reference.back_reference(), "BackRefValue");
242 hot_objects_.Add(object); 238 hot_objects_.Add(object);
243 } 239 }
244 240
241 void Serializer::PutAttachedReference(SerializerReference reference,
242 HowToCode how_to_code,
243 WhereToPoint where_to_point) {
244 DCHECK(reference.is_attached_reference());
245 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
246 (how_to_code == kPlain && where_to_point == kInnerPointer) ||
247 (how_to_code == kFromCode && where_to_point == kInnerPointer));
248 sink_->Put(kAttachedReference + how_to_code + where_to_point, "AttachedRef");
249 sink_->PutInt(reference.attached_reference_index(), "AttachedRefIndex");
250 }
251
245 int Serializer::PutAlignmentPrefix(HeapObject* object) { 252 int Serializer::PutAlignmentPrefix(HeapObject* object) {
246 AllocationAlignment alignment = object->RequiredAlignment(); 253 AllocationAlignment alignment = object->RequiredAlignment();
247 if (alignment != kWordAligned) { 254 if (alignment != kWordAligned) {
248 DCHECK(1 <= alignment && alignment <= 3); 255 DCHECK(1 <= alignment && alignment <= 3);
249 byte prefix = (kAlignmentPrefix - 1) + alignment; 256 byte prefix = (kAlignmentPrefix - 1) + alignment;
250 sink_->Put(prefix, "Alignment"); 257 sink_->Put(prefix, "Alignment");
251 return Heap::GetMaximumFillToAlign(alignment); 258 return Heap::GetMaximumFillToAlign(alignment);
252 } 259 }
253 return 0; 260 return 0;
254 } 261 }
255 262
256 BackReference Serializer::AllocateLargeObject(int size) { 263 SerializerReference Serializer::AllocateLargeObject(int size) {
257 // Large objects are allocated one-by-one when deserializing. We do not 264 // Large objects are allocated one-by-one when deserializing. We do not
258 // have to keep track of multiple chunks. 265 // have to keep track of multiple chunks.
259 large_objects_total_size_ += size; 266 large_objects_total_size_ += size;
260 return BackReference::LargeObjectReference(seen_large_objects_index_++); 267 return SerializerReference::LargeObjectReference(seen_large_objects_index_++);
261 } 268 }
262 269
263 BackReference Serializer::Allocate(AllocationSpace space, int size) { 270 SerializerReference Serializer::Allocate(AllocationSpace space, int size) {
264 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 271 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
265 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); 272 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
266 uint32_t new_chunk_size = pending_chunk_[space] + size; 273 uint32_t new_chunk_size = pending_chunk_[space] + size;
267 if (new_chunk_size > max_chunk_size(space)) { 274 if (new_chunk_size > max_chunk_size(space)) {
268 // The new chunk size would not fit onto a single page. Complete the 275 // The new chunk size would not fit onto a single page. Complete the
269 // current chunk and start a new one. 276 // current chunk and start a new one.
270 sink_->Put(kNextChunk, "NextChunk"); 277 sink_->Put(kNextChunk, "NextChunk");
271 sink_->Put(space, "NextChunkSpace"); 278 sink_->Put(space, "NextChunkSpace");
272 completed_chunks_[space].Add(pending_chunk_[space]); 279 completed_chunks_[space].Add(pending_chunk_[space]);
273 DCHECK_LE(completed_chunks_[space].length(), BackReference::kMaxChunkIndex);
274 pending_chunk_[space] = 0; 280 pending_chunk_[space] = 0;
275 new_chunk_size = size; 281 new_chunk_size = size;
276 } 282 }
277 uint32_t offset = pending_chunk_[space]; 283 uint32_t offset = pending_chunk_[space];
278 pending_chunk_[space] = new_chunk_size; 284 pending_chunk_[space] = new_chunk_size;
279 return BackReference::Reference(space, completed_chunks_[space].length(), 285 return SerializerReference::BackReference(
280 offset); 286 space, completed_chunks_[space].length(), offset);
281 } 287 }
282 288
283 void Serializer::Pad() { 289 void Serializer::Pad() {
284 // The non-branching GetInt will read up to 3 bytes too far, so we need 290 // The non-branching GetInt will read up to 3 bytes too far, so we need
285 // to pad the snapshot to make sure we don't read over the end. 291 // to pad the snapshot to make sure we don't read over the end.
286 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) { 292 for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
287 sink_->Put(kNop, "Padding"); 293 sink_->Put(kNop, "Padding");
288 } 294 }
289 // Pad up to pointer size for checksum. 295 // Pad up to pointer size for checksum.
290 while (!IsAligned(sink_->Position(), kPointerAlignment)) { 296 while (!IsAligned(sink_->Position(), kPointerAlignment)) {
(...skipping 22 matching lines...) Expand all
313 319
314 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, 320 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
315 int size, Map* map) { 321 int size, Map* map) {
316 if (serializer_->code_address_map_) { 322 if (serializer_->code_address_map_) {
317 const char* code_name = 323 const char* code_name =
318 serializer_->code_address_map_->Lookup(object_->address()); 324 serializer_->code_address_map_->Lookup(object_->address());
319 LOG(serializer_->isolate_, 325 LOG(serializer_->isolate_,
320 CodeNameEvent(object_->address(), sink_->Position(), code_name)); 326 CodeNameEvent(object_->address(), sink_->Position(), code_name));
321 } 327 }
322 328
323 BackReference back_reference; 329 SerializerReference back_reference;
324 if (space == LO_SPACE) { 330 if (space == LO_SPACE) {
325 sink_->Put(kNewObject + reference_representation_ + space, 331 sink_->Put(kNewObject + reference_representation_ + space,
326 "NewLargeObject"); 332 "NewLargeObject");
327 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); 333 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
328 if (object_->IsCode()) { 334 if (object_->IsCode()) {
329 sink_->Put(EXECUTABLE, "executable large object"); 335 sink_->Put(EXECUTABLE, "executable large object");
330 } else { 336 } else {
331 sink_->Put(NOT_EXECUTABLE, "not executable large object"); 337 sink_->Put(NOT_EXECUTABLE, "not executable large object");
332 } 338 }
333 back_reference = serializer_->AllocateLargeObject(size); 339 back_reference = serializer_->AllocateLargeObject(size);
334 } else { 340 } else {
335 int fill = serializer_->PutAlignmentPrefix(object_); 341 int fill = serializer_->PutAlignmentPrefix(object_);
336 back_reference = serializer_->Allocate(space, size + fill); 342 back_reference = serializer_->Allocate(space, size + fill);
337 sink_->Put(kNewObject + reference_representation_ + space, "NewObject"); 343 sink_->Put(kNewObject + reference_representation_ + space, "NewObject");
338 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); 344 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
339 } 345 }
340 346
341 #ifdef OBJECT_PRINT 347 #ifdef OBJECT_PRINT
342 if (FLAG_serialization_statistics) { 348 if (FLAG_serialization_statistics) {
343 serializer_->CountInstanceType(map, size); 349 serializer_->CountInstanceType(map, size);
344 } 350 }
345 #endif // OBJECT_PRINT 351 #endif // OBJECT_PRINT
346 352
347 // Mark this object as already serialized. 353 // Mark this object as already serialized.
348 serializer_->back_reference_map()->Add(object_, back_reference); 354 serializer_->reference_map()->Add(object_, back_reference);
349 355
350 // Serialize the map (first word of the object). 356 // Serialize the map (first word of the object).
351 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); 357 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
352 } 358 }
353 359
354 void Serializer::ObjectSerializer::SerializeExternalString() { 360 void Serializer::ObjectSerializer::SerializeExternalString() {
355 // Instead of serializing this as an external string, we serialize 361 // Instead of serializing this as an external string, we serialize
356 // an imaginary sequential string with the same content. 362 // an imaginary sequential string with the same content.
357 Isolate* isolate = serializer_->isolate(); 363 Isolate* isolate = serializer_->isolate();
358 DCHECK(object_->IsExternalString()); 364 DCHECK(object_->IsExternalString());
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 512
507 void Serializer::ObjectSerializer::SerializeDeferred() { 513 void Serializer::ObjectSerializer::SerializeDeferred() {
508 if (FLAG_trace_serializer) { 514 if (FLAG_trace_serializer) {
509 PrintF(" Encoding deferred heap object: "); 515 PrintF(" Encoding deferred heap object: ");
510 object_->ShortPrint(); 516 object_->ShortPrint();
511 PrintF("\n"); 517 PrintF("\n");
512 } 518 }
513 519
514 int size = object_->Size(); 520 int size = object_->Size();
515 Map* map = object_->map(); 521 Map* map = object_->map();
516 BackReference reference = serializer_->back_reference_map()->Lookup(object_); 522 SerializerReference back_reference =
523 serializer_->reference_map()->Lookup(object_);
524 DCHECK(back_reference.is_back_reference());
517 525
518 // Serialize the rest of the object. 526 // Serialize the rest of the object.
519 CHECK_EQ(0, bytes_processed_so_far_); 527 CHECK_EQ(0, bytes_processed_so_far_);
520 bytes_processed_so_far_ = kPointerSize; 528 bytes_processed_so_far_ = kPointerSize;
521 529
522 serializer_->PutAlignmentPrefix(object_); 530 serializer_->PutAlignmentPrefix(object_);
523 sink_->Put(kNewObject + reference.space(), "deferred object"); 531 sink_->Put(kNewObject + back_reference.space(), "deferred object");
524 serializer_->PutBackReference(object_, reference); 532 serializer_->PutBackReference(object_, back_reference);
525 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size"); 533 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size");
526 534
527 UnlinkWeakNextScope unlink_weak_next(object_); 535 UnlinkWeakNextScope unlink_weak_next(object_);
528 536
529 object_->IterateBody(map->instance_type(), size, this); 537 object_->IterateBody(map->instance_type(), size, this);
530 OutputRawData(object_->address() + size); 538 OutputRawData(object_->address() + size);
531 } 539 }
532 540
533 void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) { 541 void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) {
534 Object** current = start; 542 Object** current = start;
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 if (to_skip != 0 && return_skip == kIgnoringReturn) { 769 if (to_skip != 0 && return_skip == kIgnoringReturn) {
762 sink_->Put(kSkip, "Skip"); 770 sink_->Put(kSkip, "Skip");
763 sink_->PutInt(to_skip, "SkipDistance"); 771 sink_->PutInt(to_skip, "SkipDistance");
764 to_skip = 0; 772 to_skip = 0;
765 } 773 }
766 return to_skip; 774 return to_skip;
767 } 775 }
768 776
769 } // namespace internal 777 } // namespace internal
770 } // namespace v8 778 } // namespace v8
OLDNEW
« no previous file with comments | « src/snapshot/serializer.h ('k') | src/snapshot/serializer-common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698