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

Side by Side Diff: src/serialize.h

Issue 654243003: Revert "Break deserializer reservations into chunks that fit onto a page." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #ifndef V8_SERIALIZE_H_ 5 #ifndef V8_SERIALIZE_H_
6 #define V8_SERIALIZE_H_ 6 #define V8_SERIALIZE_H_
7 7
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/heap-profiler.h" 10 #include "src/heap-profiler.h"
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 class SerializerDeserializer: public ObjectVisitor { 145 class SerializerDeserializer: public ObjectVisitor {
146 public: 146 public:
147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); 147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor);
148 148
149 static int nop() { return kNop; } 149 static int nop() { return kNop; }
150 150
151 // No reservation for large object space necessary. 151 // No reservation for large object space necessary.
152 static const int kNumberOfPreallocatedSpaces = LO_SPACE; 152 static const int kNumberOfPreallocatedSpaces = LO_SPACE;
153 static const int kNumberOfSpaces = INVALID_SPACE; 153 static const int kNumberOfSpaces = INVALID_SPACE;
154 154
155 // To encode object for back-references.
156 class OffsetBits : public BitField<uint32_t, 0, kPageSizeBits> {};
157 class ChunkIndexBits
158 : public BitField<uint32_t, kPageSizeBits, 32 - kPageSizeBits> {};
159
160 protected: 155 protected:
161 // Where the pointed-to object can be found: 156 // Where the pointed-to object can be found:
162 enum Where { 157 enum Where {
163 kNewObject = 0, // Object is next in snapshot. 158 kNewObject = 0, // Object is next in snapshot.
164 // 1-7 One per space. 159 // 1-7 One per space.
165 kRootArray = 0x9, // Object is found in root array. 160 kRootArray = 0x9, // Object is found in root array.
166 kPartialSnapshotCache = 0xa, // Object is in the cache. 161 kPartialSnapshotCache = 0xa, // Object is in the cache.
167 kExternalReference = 0xb, // Pointer to an external reference. 162 kExternalReference = 0xb, // Pointer to an external reference.
168 kSkip = 0xc, // Skip n bytes. 163 kSkip = 0xc, // Skip n bytes.
169 kBuiltin = 0xd, // Builtin code object. 164 kBuiltin = 0xd, // Builtin code object.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 class Deserializer: public SerializerDeserializer { 241 class Deserializer: public SerializerDeserializer {
247 public: 242 public:
248 // Create a deserializer from a snapshot byte source. 243 // Create a deserializer from a snapshot byte source.
249 explicit Deserializer(SnapshotByteSource* source); 244 explicit Deserializer(SnapshotByteSource* source);
250 245
251 virtual ~Deserializer(); 246 virtual ~Deserializer();
252 247
253 // Deserialize the snapshot into an empty heap. 248 // Deserialize the snapshot into an empty heap.
254 void Deserialize(Isolate* isolate); 249 void Deserialize(Isolate* isolate);
255 250
256 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM }; 251 // Deserialize a single object and the objects reachable from it.
252 void DeserializePartial(Isolate* isolate, Object** root);
257 253
258 // Deserialize a single object and the objects reachable from it. 254 void set_reservation(int space_number, int reservation) {
259 // We may want to abort gracefully even if deserialization fails. 255 DCHECK(space_number >= 0);
260 void DeserializePartial(Isolate* isolate, Object** root, 256 DCHECK(space_number < kNumberOfSpaces);
261 OnOOM on_oom = FATAL_ON_OOM); 257 reservations_[space_number] = reservation;
262
263 void AddReservation(int space, uint32_t chunk) {
264 DCHECK(space >= 0);
265 DCHECK(space < kNumberOfSpaces);
266 DCHECK(space == LO_SPACE || chunk < Page::kMaxRegularHeapObjectSize);
267 reservations_[space].Add({chunk, NULL, NULL});
268 } 258 }
269 259
270 void FlushICacheForNewCodeObjects(); 260 void FlushICacheForNewCodeObjects();
271 261
272 // Serialized user code reference certain objects that are provided in a list 262 // Serialized user code reference certain objects that are provided in a list
273 // By calling this method, we assume that we are deserializing user code. 263 // By calling this method, we assume that we are deserializing user code.
274 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { 264 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) {
275 attached_objects_ = attached_objects; 265 attached_objects_ = attached_objects;
276 } 266 }
277 267
278 bool deserializing_user_code() { return attached_objects_ != NULL; } 268 bool deserializing_user_code() { return attached_objects_ != NULL; }
279 269
280 private: 270 private:
281 virtual void VisitPointers(Object** start, Object** end); 271 virtual void VisitPointers(Object** start, Object** end);
282 272
283 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { 273 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {
284 UNREACHABLE(); 274 UNREACHABLE();
285 } 275 }
286 276
287 bool ReserveSpace();
288
289 // Allocation sites are present in the snapshot, and must be linked into 277 // Allocation sites are present in the snapshot, and must be linked into
290 // a list at deserialization time. 278 // a list at deserialization time.
291 void RelinkAllocationSite(AllocationSite* site); 279 void RelinkAllocationSite(AllocationSite* site);
292 280
293 // Fills in some heap data in an area from start to end (non-inclusive). The 281 // Fills in some heap data in an area from start to end (non-inclusive). The
294 // space id is used for the write barrier. The object_address is the address 282 // space id is used for the write barrier. The object_address is the address
295 // of the object we are writing into, or NULL if we are not writing into an 283 // of the object we are writing into, or NULL if we are not writing into an
296 // object, i.e. if we are writing a series of tagged values that are not on 284 // object, i.e. if we are writing a series of tagged values that are not on
297 // the heap. 285 // the heap.
298 void ReadData(Object** start, Object** end, int space, 286 void ReadChunk(
299 Address object_address); 287 Object** start, Object** end, int space, Address object_address);
300 void ReadObject(int space_number, Object** write_back); 288 void ReadObject(int space_number, Object** write_back);
301 Address Allocate(int space_index, int size); 289 Address Allocate(int space_index, int size);
302 290
303 // Special handling for serialized code like hooking up internalized strings. 291 // Special handling for serialized code like hooking up internalized strings.
304 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 292 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
305 Object* ProcessBackRefInSerializedCode(Object* obj); 293 Object* ProcessBackRefInSerializedCode(Object* obj);
306 294
307 // This returns the address of an object that has been described in the 295 // This returns the address of an object that has been described in the
308 // snapshot by chunk index and offset. 296 // snapshot as being offset bytes back in a particular space.
309 HeapObject* GetBackReferencedObject(int space) { 297 HeapObject* GetAddressFromEnd(int space) {
310 if (space == LO_SPACE) { 298 int offset = source_->GetInt();
311 uint32_t index = source_->GetInt(); 299 if (space == LO_SPACE) return deserialized_large_objects_[offset];
312 return deserialized_large_objects_[index]; 300 DCHECK(space < kNumberOfPreallocatedSpaces);
313 } else { 301 offset <<= kObjectAlignmentBits;
314 uint32_t allocation = source_->GetInt() << kObjectAlignmentBits; 302 return HeapObject::FromAddress(high_water_[space] - offset);
315 DCHECK(space < kNumberOfPreallocatedSpaces);
316 uint32_t chunk_index = ChunkIndexBits::decode(allocation);
317 uint32_t offset = OffsetBits::decode(allocation);
318 DCHECK_LE(chunk_index, current_chunk_[space]);
319 return HeapObject::FromAddress(reservations_[space][chunk_index].start +
320 offset);
321 }
322 } 303 }
323 304
324 // Cached current isolate. 305 // Cached current isolate.
325 Isolate* isolate_; 306 Isolate* isolate_;
326 307
327 // Objects from the attached object descriptions in the serialized user code. 308 // Objects from the attached object descriptions in the serialized user code.
328 Vector<Handle<Object> >* attached_objects_; 309 Vector<Handle<Object> >* attached_objects_;
329 310
330 SnapshotByteSource* source_; 311 SnapshotByteSource* source_;
331 // The address of the next object that will be allocated in each space. 312 // This is the address of the next object that will be allocated in each
332 // Each space has a number of chunks reserved by the GC, with each chunk 313 // space. It is used to calculate the addresses of back-references.
333 // fitting into a page. Deserialized objects are allocated into the
334 // current chunk of the target space by bumping up high water mark.
335 Heap::Reservation reservations_[kNumberOfSpaces];
336 uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
337 Address high_water_[kNumberOfPreallocatedSpaces]; 314 Address high_water_[kNumberOfPreallocatedSpaces];
338 315
316 int reservations_[kNumberOfSpaces];
317 static const intptr_t kUninitializedReservation = -1;
318
339 ExternalReferenceDecoder* external_reference_decoder_; 319 ExternalReferenceDecoder* external_reference_decoder_;
340 320
341 List<HeapObject*> deserialized_large_objects_; 321 List<HeapObject*> deserialized_large_objects_;
342 322
343 DISALLOW_COPY_AND_ASSIGN(Deserializer); 323 DISALLOW_COPY_AND_ASSIGN(Deserializer);
344 }; 324 };
345 325
346 326
347 // Mapping objects to their location after deserialization. 327 // Mapping objects to their location after deserialization.
348 // This is used during building, but not at runtime by V8. 328 // This is used during building, but not at runtime by V8.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 373
394 374
395 class CodeAddressMap; 375 class CodeAddressMap;
396 376
397 // There can be only one serializer per V8 process. 377 // There can be only one serializer per V8 process.
398 class Serializer : public SerializerDeserializer { 378 class Serializer : public SerializerDeserializer {
399 public: 379 public:
400 Serializer(Isolate* isolate, SnapshotByteSink* sink); 380 Serializer(Isolate* isolate, SnapshotByteSink* sink);
401 ~Serializer(); 381 ~Serializer();
402 void VisitPointers(Object** start, Object** end); 382 void VisitPointers(Object** start, Object** end);
403 383 // You can call this after serialization to find out how much space was used
404 void FinalizeAllocation(); 384 // in each space.
405 385 int CurrentAllocationAddress(int space) const {
406 Vector<const uint32_t> FinalAllocationChunks(int space) const { 386 DCHECK(space < kNumberOfSpaces);
407 DCHECK_EQ(1, completed_chunks_[LO_SPACE].length()); // Already finalized. 387 return fullness_[space];
408 DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks.
409 return completed_chunks_[space].ToConstVector();
410 } 388 }
411 389
412 Isolate* isolate() const { return isolate_; } 390 Isolate* isolate() const { return isolate_; }
413 391
414 SerializationAddressMapper* address_mapper() { return &address_mapper_; } 392 SerializationAddressMapper* address_mapper() { return &address_mapper_; }
415 void PutRoot(int index, 393 void PutRoot(int index,
416 HeapObject* object, 394 HeapObject* object,
417 HowToCode how, 395 HowToCode how,
418 WhereToPoint where, 396 WhereToPoint where,
419 int skip); 397 int skip);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 HowToCode how_to_code, 463 HowToCode how_to_code,
486 WhereToPoint where_to_point, 464 WhereToPoint where_to_point,
487 int skip) = 0; 465 int skip) = 0;
488 void SerializeReferenceToPreviousObject(HeapObject* heap_object, 466 void SerializeReferenceToPreviousObject(HeapObject* heap_object,
489 HowToCode how_to_code, 467 HowToCode how_to_code,
490 WhereToPoint where_to_point, 468 WhereToPoint where_to_point,
491 int skip); 469 int skip);
492 void InitializeAllocators(); 470 void InitializeAllocators();
493 // This will return the space for an object. 471 // This will return the space for an object.
494 static int SpaceOfObject(HeapObject* object); 472 static int SpaceOfObject(HeapObject* object);
495 uint32_t AllocateLargeObject(int size); 473 int AllocateLargeObject(int size);
496 uint32_t Allocate(int space, int size); 474 int Allocate(int space, int size);
497 int EncodeExternalReference(Address addr) { 475 int EncodeExternalReference(Address addr) {
498 return external_reference_encoder_->Encode(addr); 476 return external_reference_encoder_->Encode(addr);
499 } 477 }
500 478
501 int SpaceAreaSize(int space); 479 int SpaceAreaSize(int space);
502 480
503 // Some roots should not be serialized, because their actual value depends on 481 // Some roots should not be serialized, because their actual value depends on
504 // absolute addresses and they are reset after deserialization, anyway. 482 // absolute addresses and they are reset after deserialization, anyway.
505 bool ShouldBeSkipped(Object** current); 483 bool ShouldBeSkipped(Object** current);
506 484
507 Isolate* isolate_; 485 Isolate* isolate_;
508 486 // Keep track of the fullness of each space in order to generate
509 // Objects from the same space are put into chunks for bulk-allocation 487 // relative addresses for back references.
510 // when deserializing. We have to make sure that each chunk fits into a 488 int fullness_[kNumberOfSpaces];
511 // page. So we track the chunk size in pending_chunk_ of a space, but
512 // when it exceeds a page, we complete the current chunk and start a new one.
513 uint32_t pending_chunk_[kNumberOfSpaces];
514 List<uint32_t> completed_chunks_[kNumberOfSpaces];
515
516 SnapshotByteSink* sink_; 489 SnapshotByteSink* sink_;
517 ExternalReferenceEncoder* external_reference_encoder_; 490 ExternalReferenceEncoder* external_reference_encoder_;
518 491
519 SerializationAddressMapper address_mapper_; 492 SerializationAddressMapper address_mapper_;
520 intptr_t root_index_wave_front_; 493 intptr_t root_index_wave_front_;
521 void Pad(); 494 void Pad();
522 495
523 friend class ObjectSerializer; 496 friend class ObjectSerializer;
524 friend class Deserializer; 497 friend class Deserializer;
525 498
526 // We may not need the code address map for logging for every instance 499 // We may not need the code address map for logging for every instance
527 // of the serializer. Initialize it on demand. 500 // of the serializer. Initialize it on demand.
528 void InitializeCodeAddressMap(); 501 void InitializeCodeAddressMap();
529 502
530 private: 503 private:
531 CodeAddressMap* code_address_map_; 504 CodeAddressMap* code_address_map_;
532 // We map serialized large objects to indexes for back-referencing. 505 // We map serialized large objects to indexes for back-referencing.
533 uint32_t seen_large_objects_index_; 506 int seen_large_objects_index_;
534 DISALLOW_COPY_AND_ASSIGN(Serializer); 507 DISALLOW_COPY_AND_ASSIGN(Serializer);
535 }; 508 };
536 509
537 510
538 class PartialSerializer : public Serializer { 511 class PartialSerializer : public Serializer {
539 public: 512 public:
540 PartialSerializer(Isolate* isolate, 513 PartialSerializer(Isolate* isolate,
541 Serializer* startup_snapshot_serializer, 514 Serializer* startup_snapshot_serializer,
542 SnapshotByteSink* sink) 515 SnapshotByteSink* sink)
543 : Serializer(isolate, sink), 516 : Serializer(isolate, sink),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); 578 DISALLOW_COPY_AND_ASSIGN(StartupSerializer);
606 }; 579 };
607 580
608 581
609 class CodeSerializer : public Serializer { 582 class CodeSerializer : public Serializer {
610 public: 583 public:
611 static ScriptData* Serialize(Isolate* isolate, 584 static ScriptData* Serialize(Isolate* isolate,
612 Handle<SharedFunctionInfo> info, 585 Handle<SharedFunctionInfo> info,
613 Handle<String> source); 586 Handle<String> source);
614 587
615 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( 588 static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
616 Isolate* isolate, ScriptData* data, Handle<String> source); 589 ScriptData* data,
590 Handle<String> source);
617 591
618 static const int kSourceObjectIndex = 0; 592 static const int kSourceObjectIndex = 0;
619 static const int kCodeStubsBaseIndex = 1; 593 static const int kCodeStubsBaseIndex = 1;
620 594
621 String* source() { 595 String* source() {
622 DCHECK(!AllowHeapAllocation::IsAllowed()); 596 DCHECK(!AllowHeapAllocation::IsAllowed());
623 return source_; 597 return source_;
624 } 598 }
625 599
626 List<uint32_t>* stub_keys() { return &stub_keys_; } 600 List<uint32_t>* stub_keys() { return &stub_keys_; }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 647
674 // Return ScriptData object and relinquish ownership over it to the caller. 648 // Return ScriptData object and relinquish ownership over it to the caller.
675 ScriptData* GetScriptData() { 649 ScriptData* GetScriptData() {
676 ScriptData* result = script_data_; 650 ScriptData* result = script_data_;
677 script_data_ = NULL; 651 script_data_ = NULL;
678 DCHECK(owns_script_data_); 652 DCHECK(owns_script_data_);
679 owns_script_data_ = false; 653 owns_script_data_ = false;
680 return result; 654 return result;
681 } 655 }
682 656
683 class Reservation {
684 public:
685 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation); }
686 bool is_last_chunk() const { return IsLastChunkBits::decode(reservation); }
687
688 private:
689 uint32_t reservation;
690
691 DISALLOW_COPY_AND_ASSIGN(Reservation);
692 };
693
694 Vector<const Reservation> Reservations() const {
695 return Vector<const Reservation>(reinterpret_cast<const Reservation*>(
696 script_data_->data() + kHeaderSize),
697 GetHeaderValue(kReservationsOffset));
698 }
699
700 Vector<const uint32_t> CodeStubKeys() const { 657 Vector<const uint32_t> CodeStubKeys() const {
701 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; 658 return Vector<const uint32_t>(
702 const byte* start = script_data_->data() + kHeaderSize + reservations_size; 659 reinterpret_cast<const uint32_t*>(script_data_->data() + kHeaderSize),
703 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), 660 GetHeaderValue(kNumCodeStubKeysOffset));
704 GetHeaderValue(kNumCodeStubKeysOffset));
705 } 661 }
706 662
707 const byte* Payload() const { 663 const byte* Payload() const {
708 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
709 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; 664 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
710 return script_data_->data() + kHeaderSize + reservations_size + 665 return script_data_->data() + kHeaderSize + code_stubs_size;
711 code_stubs_size;
712 } 666 }
713 667
714 int PayloadLength() const { 668 int PayloadLength() const {
715 int payload_length = GetHeaderValue(kPayloadLengthOffset); 669 int payload_length = GetHeaderValue(kPayloadLengthOffset);
716 DCHECK_EQ(script_data_->data() + script_data_->length(), 670 DCHECK_EQ(script_data_->data() + script_data_->length(),
717 Payload() + payload_length); 671 Payload() + payload_length);
718 return payload_length; 672 return payload_length;
719 } 673 }
720 674
675 int GetReservation(int space) const {
676 return GetHeaderValue(kReservationsOffset + space);
677 }
678
721 private: 679 private:
722 void SetHeaderValue(int offset, int value) { 680 void SetHeaderValue(int offset, int value) {
723 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = 681 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] =
724 value; 682 value;
725 } 683 }
726 684
727 int GetHeaderValue(int offset) const { 685 int GetHeaderValue(int offset) const {
728 return reinterpret_cast<const int*>(script_data_->data())[offset]; 686 return reinterpret_cast<const int*>(script_data_->data())[offset];
729 } 687 }
730 688
731 bool IsSane(String* source); 689 bool IsSane(String* source);
732 690
733 int CheckSum(String* source); 691 int CheckSum(String* source);
734 692
735 // The data header consists of int-sized entries: 693 // The data header consists of int-sized entries:
736 // [0] version hash 694 // [0] version hash
737 // [1] number of code stub keys 695 // [1] number of code stub keys
738 // [2] payload length 696 // [2] payload length
739 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. 697 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE.
740 static const int kCheckSumOffset = 0; 698 static const int kCheckSumOffset = 0;
741 static const int kReservationsOffset = 1; 699 static const int kNumCodeStubKeysOffset = 1;
742 static const int kNumCodeStubKeysOffset = 2; 700 static const int kPayloadLengthOffset = 2;
743 static const int kPayloadLengthOffset = 3; 701 static const int kReservationsOffset = 3;
744 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
745 702
746 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {}; 703 static const int kHeaderEntries =
747 class IsLastChunkBits : public BitField<bool, 31, 1> {}; 704 kReservationsOffset + SerializerDeserializer::kNumberOfSpaces;
705 static const int kHeaderSize = kHeaderEntries * kIntSize;
748 706
749 // Following the header, we store, in sequential order 707 // Following the header, we store, in sequential order
750 // - code stub keys 708 // - code stub keys
751 // - serialization payload 709 // - serialization payload
752 710
753 ScriptData* script_data_; 711 ScriptData* script_data_;
754 bool owns_script_data_; 712 bool owns_script_data_;
755 }; 713 };
756 } } // namespace v8::internal 714 } } // namespace v8::internal
757 715
758 #endif // V8_SERIALIZE_H_ 716 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698