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

Side by Side Diff: src/serialize.h

Issue 781443002: Encode reservation meta data in the snapshot blob. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@snapshotformat
Patch Set: Created 6 years 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
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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 383
384 // A bitmask for getting the space out of an instruction. 384 // A bitmask for getting the space out of an instruction.
385 static const int kSpaceMask = 7; 385 static const int kSpaceMask = 7;
386 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); 386 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
387 387
388 // Sentinel after a new object to indicate that double alignment is needed. 388 // Sentinel after a new object to indicate that double alignment is needed.
389 static const int kDoubleAlignmentSentinel = 0; 389 static const int kDoubleAlignmentSentinel = 0;
390 }; 390 };
391 391
392 392
393 class SerializedData {
394 public:
395 class Reservation {
396 public:
397 explicit Reservation(uint32_t size)
398 : reservation_(ChunkSizeBits::encode(size)) {}
399
400 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
401 bool is_last() const { return IsLastChunkBits::decode(reservation_); }
402
403 void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
404
405 private:
406 uint32_t reservation_;
407 };
408
409 SerializedData(byte* data, int size)
410 : data_(data), size_(size), owns_data_(false) {}
411 SerializedData() : data_(NULL), size_(0), owns_data_(true) {}
vogelheim 2014/12/03 18:49:25 Here, owns_data_ == (data_ == NULL), which doesn't
Yang 2014/12/04 08:51:43 Acknowledged.
412
413 virtual ~SerializedData() {
414 if (owns_data_) DeleteArray<byte>(data_);
415 }
416
417 virtual Vector<const Reservation> Reservations() const = 0;
418 virtual Vector<const byte> Payload() const = 0;
419
420 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
421 class IsLastChunkBits : public BitField<bool, 31, 1> {};
422
423 protected:
424 void SetHeaderValue(int offset, int value) {
425 reinterpret_cast<int*>(data_)[offset] = value;
426 }
427
428 int GetHeaderValue(int offset) const {
429 return reinterpret_cast<const int*>(data_)[offset];
430 }
431
432 byte* data_;
433 int size_;
434 bool owns_data_;
435 };
436
437
393 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 438 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
394 class Deserializer: public SerializerDeserializer { 439 class Deserializer: public SerializerDeserializer {
395 public: 440 public:
396 // Create a deserializer from a snapshot byte source. 441 // Create a deserializer from a snapshot byte source.
397 explicit Deserializer(SnapshotByteSource* source); 442 explicit Deserializer(SerializedData* serialized_data);
398 443
399 virtual ~Deserializer(); 444 virtual ~Deserializer();
400 445
401 // Deserialize the snapshot into an empty heap. 446 // Deserialize the snapshot into an empty heap.
402 void Deserialize(Isolate* isolate); 447 void Deserialize(Isolate* isolate);
403 448
404 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM }; 449 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM };
405 450
406 // Deserialize a single object and the objects reachable from it. 451 // Deserialize a single object and the objects reachable from it.
407 // We may want to abort gracefully even if deserialization fails. 452 // We may want to abort gracefully even if deserialization fails.
408 void DeserializePartial(Isolate* isolate, Object** root, 453 void DeserializePartial(Isolate* isolate, Object** root,
409 OnOOM on_oom = FATAL_ON_OOM); 454 OnOOM on_oom = FATAL_ON_OOM);
410 455
411 void AddReservation(int space, uint32_t chunk) {
412 DCHECK(space >= 0);
413 DCHECK(space < kNumberOfSpaces);
414 reservations_[space].Add({chunk, NULL, NULL});
415 }
416
417 void FlushICacheForNewCodeObjects(); 456 void FlushICacheForNewCodeObjects();
418 457
419 // Serialized user code reference certain objects that are provided in a list 458 // Serialized user code reference certain objects that are provided in a list
420 // By calling this method, we assume that we are deserializing user code. 459 // By calling this method, we assume that we are deserializing user code.
421 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { 460 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) {
422 attached_objects_ = attached_objects; 461 attached_objects_ = attached_objects;
423 } 462 }
424 463
425 bool deserializing_user_code() { return attached_objects_ != NULL; } 464 bool deserializing_user_code() { return attached_objects_ != NULL; }
426 465
(...skipping 21 matching lines...) Expand all
448 Address Allocate(int space_index, int size); 487 Address Allocate(int space_index, int size);
449 488
450 // Special handling for serialized code like hooking up internalized strings. 489 // Special handling for serialized code like hooking up internalized strings.
451 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 490 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
452 Object* ProcessBackRefInSerializedCode(Object* obj); 491 Object* ProcessBackRefInSerializedCode(Object* obj);
453 492
454 // This returns the address of an object that has been described in the 493 // This returns the address of an object that has been described in the
455 // snapshot by chunk index and offset. 494 // snapshot by chunk index and offset.
456 HeapObject* GetBackReferencedObject(int space) { 495 HeapObject* GetBackReferencedObject(int space) {
457 if (space == LO_SPACE) { 496 if (space == LO_SPACE) {
458 uint32_t index = source_->GetInt(); 497 uint32_t index = source_.GetInt();
459 return deserialized_large_objects_[index]; 498 return deserialized_large_objects_[index];
460 } else { 499 } else {
461 BackReference back_reference(source_->GetInt()); 500 BackReference back_reference(source_.GetInt());
462 DCHECK(space < kNumberOfPreallocatedSpaces); 501 DCHECK(space < kNumberOfPreallocatedSpaces);
463 uint32_t chunk_index = back_reference.chunk_index(); 502 uint32_t chunk_index = back_reference.chunk_index();
464 DCHECK_LE(chunk_index, current_chunk_[space]); 503 DCHECK_LE(chunk_index, current_chunk_[space]);
465 uint32_t chunk_offset = back_reference.chunk_offset(); 504 uint32_t chunk_offset = back_reference.chunk_offset();
466 return HeapObject::FromAddress(reservations_[space][chunk_index].start + 505 return HeapObject::FromAddress(reservations_[space][chunk_index].start +
467 chunk_offset); 506 chunk_offset);
468 } 507 }
469 } 508 }
470 509
471 // Cached current isolate. 510 // Cached current isolate.
472 Isolate* isolate_; 511 Isolate* isolate_;
473 512
474 // Objects from the attached object descriptions in the serialized user code. 513 // Objects from the attached object descriptions in the serialized user code.
475 Vector<Handle<Object> >* attached_objects_; 514 Vector<Handle<Object> >* attached_objects_;
476 515
477 SnapshotByteSource* source_; 516 SnapshotByteSource source_;
478 // The address of the next object that will be allocated in each space. 517 // The address of the next object that will be allocated in each space.
479 // Each space has a number of chunks reserved by the GC, with each chunk 518 // Each space has a number of chunks reserved by the GC, with each chunk
480 // fitting into a page. Deserialized objects are allocated into the 519 // fitting into a page. Deserialized objects are allocated into the
481 // current chunk of the target space by bumping up high water mark. 520 // current chunk of the target space by bumping up high water mark.
482 Heap::Reservation reservations_[kNumberOfSpaces]; 521 Heap::Reservation reservations_[kNumberOfSpaces];
483 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; 522 uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
484 Address high_water_[kNumberOfPreallocatedSpaces]; 523 Address high_water_[kNumberOfPreallocatedSpaces];
485 524
486 ExternalReferenceDecoder* external_reference_decoder_; 525 ExternalReferenceDecoder* external_reference_decoder_;
487 526
488 List<HeapObject*> deserialized_large_objects_; 527 List<HeapObject*> deserialized_large_objects_;
489 528
490 DISALLOW_COPY_AND_ASSIGN(Deserializer); 529 DISALLOW_COPY_AND_ASSIGN(Deserializer);
491 }; 530 };
492 531
493 532
494 class CodeAddressMap; 533 class CodeAddressMap;
495 534
496 // There can be only one serializer per V8 process. 535 // There can be only one serializer per V8 process.
497 class Serializer : public SerializerDeserializer { 536 class Serializer : public SerializerDeserializer {
498 public: 537 public:
499 Serializer(Isolate* isolate, SnapshotByteSink* sink); 538 Serializer(Isolate* isolate, SnapshotByteSink* sink);
500 ~Serializer(); 539 ~Serializer();
501 virtual void VisitPointers(Object** start, Object** end) OVERRIDE; 540 virtual void VisitPointers(Object** start, Object** end) OVERRIDE;
502 541
503 void FinalizeAllocation(); 542 void EncodeReservations(List<SerializedData::Reservation>* out) const;
504
505 Vector<const uint32_t> FinalAllocationChunks(int space) const {
506 if (space == LO_SPACE) {
507 return Vector<const uint32_t>(&large_objects_total_size_, 1);
508 } else {
509 DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks.
510 return completed_chunks_[space].ToConstVector();
511 }
512 }
513 543
514 Isolate* isolate() const { return isolate_; } 544 Isolate* isolate() const { return isolate_; }
515 545
516 BackReferenceMap* back_reference_map() { return &back_reference_map_; } 546 BackReferenceMap* back_reference_map() { return &back_reference_map_; }
517 RootIndexMap* root_index_map() { return &root_index_map_; } 547 RootIndexMap* root_index_map() { return &root_index_map_; }
518 548
519 protected: 549 protected:
520 class ObjectSerializer : public ObjectVisitor { 550 class ObjectSerializer : public ObjectVisitor {
521 public: 551 public:
522 ObjectSerializer(Serializer* serializer, 552 ObjectSerializer(Serializer* serializer,
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 Isolate* isolate, ScriptData* cached_data, Handle<String> source); 746 Isolate* isolate, ScriptData* cached_data, Handle<String> source);
717 747
718 static const int kSourceObjectIndex = 0; 748 static const int kSourceObjectIndex = 0;
719 static const int kCodeStubsBaseIndex = 1; 749 static const int kCodeStubsBaseIndex = 1;
720 750
721 String* source() const { 751 String* source() const {
722 DCHECK(!AllowHeapAllocation::IsAllowed()); 752 DCHECK(!AllowHeapAllocation::IsAllowed());
723 return source_; 753 return source_;
724 } 754 }
725 755
726 List<uint32_t>* stub_keys() { return &stub_keys_; } 756 const List<uint32_t>* stub_keys() const { return &stub_keys_; }
727 int num_internalized_strings() const { return num_internalized_strings_; } 757 int num_internalized_strings() const { return num_internalized_strings_; }
728 758
729 private: 759 private:
730 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source, 760 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source,
731 Code* main_code) 761 Code* main_code)
732 : Serializer(isolate, sink), 762 : Serializer(isolate, sink),
733 source_(source), 763 source_(source),
734 main_code_(main_code), 764 main_code_(main_code),
735 num_internalized_strings_(0) { 765 num_internalized_strings_(0) {
736 back_reference_map_.AddSourceString(source); 766 back_reference_map_.AddSourceString(source);
(...skipping 16 matching lines...) Expand all
753 783
754 DisallowHeapAllocation no_gc_; 784 DisallowHeapAllocation no_gc_;
755 String* source_; 785 String* source_;
756 Code* main_code_; 786 Code* main_code_;
757 int num_internalized_strings_; 787 int num_internalized_strings_;
758 List<uint32_t> stub_keys_; 788 List<uint32_t> stub_keys_;
759 DISALLOW_COPY_AND_ASSIGN(CodeSerializer); 789 DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
760 }; 790 };
761 791
762 792
793 // Wrapper around reservation sizes and the serialization payload.
794 class SnapshotData : public SerializedData {
795 public:
796 // Used when producing.
797 SnapshotData(const SnapshotByteSink& sink, const Serializer& ser);
798
799 // Used when consuming.
800 explicit SnapshotData(const byte* data, int size)
801 : SerializedData(const_cast<byte*>(data), size) {
802 CHECK(IsSane());
803 }
804
805 virtual Vector<const Reservation> Reservations() const OVERRIDE;
806 virtual Vector<const byte> Payload() const OVERRIDE;
807
808 Vector<const byte> RawData() const {
809 return Vector<const byte>(data_, size_);
810 }
811
812 private:
813 bool IsSane();
814 // The data header consists of int-sized entries:
815 // [0] version hash
816 // [1] number of reservation size entries
817 // [2] payload length
818 static const int kCheckSumOffset = 0;
819 static const int kReservationsOffset = 1;
820 static const int kPayloadLengthOffset = 2;
821 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
822 };
823
824
763 // Wrapper around ScriptData to provide code-serializer-specific functionality. 825 // Wrapper around ScriptData to provide code-serializer-specific functionality.
764 class SerializedCodeData { 826 class SerializedCodeData : public SerializedData {
765 public: 827 public:
766 // Used by when consuming. 828 // Used when consuming.
767 static SerializedCodeData* FromCachedData(ScriptData* cached_data, 829 static SerializedCodeData* FromCachedData(ScriptData* cached_data,
768 String* source) { 830 String* source) {
769 DisallowHeapAllocation no_gc; 831 DisallowHeapAllocation no_gc;
770 SerializedCodeData* scd = new SerializedCodeData(cached_data); 832 SerializedCodeData* scd = new SerializedCodeData(cached_data);
771 if (scd->IsSane(source)) return scd; 833 if (scd->IsSane(source)) return scd;
772 cached_data->Reject(); 834 cached_data->Reject();
773 delete scd; 835 delete scd;
774 return NULL; 836 return NULL;
775 } 837 }
776 838
777 // Used when producing. 839 // Used when producing.
778 SerializedCodeData(const List<byte>& payload, CodeSerializer* cs); 840 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs);
779
780 ~SerializedCodeData() {
781 if (owns_script_data_) DeleteArray<byte>(data_);
782 }
783 841
784 // Return ScriptData object and relinquish ownership over it to the caller. 842 // Return ScriptData object and relinquish ownership over it to the caller.
785 ScriptData* GetScriptData() { 843 ScriptData* GetScriptData();
786 DCHECK(owns_script_data_);
787 ScriptData* result = new ScriptData(data_, size_);
788 result->AcquireDataOwnership();
789 return result;
790 }
791 844
792 class Reservation { 845 virtual Vector<const Reservation> Reservations() const OVERRIDE;
793 public: 846 virtual Vector<const byte> Payload() const OVERRIDE;
794 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation); }
795 bool is_last_chunk() const { return IsLastChunkBits::decode(reservation); }
796 847
797 private: 848 int NumInternalizedStrings() const;
798 uint32_t reservation; 849 Vector<const uint32_t> CodeStubKeys() const;
799
800 DISALLOW_COPY_AND_ASSIGN(Reservation);
801 };
802
803 int NumInternalizedStrings() const {
804 return GetHeaderValue(kNumInternalizedStringsOffset);
805 }
806
807 Vector<const Reservation> Reservations() const {
808 return Vector<const Reservation>(
809 reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
810 GetHeaderValue(kReservationsOffset));
811 }
812
813 Vector<const uint32_t> CodeStubKeys() const {
814 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
815 const byte* start = data_ + kHeaderSize + reservations_size;
816 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
817 GetHeaderValue(kNumCodeStubKeysOffset));
818 }
819
820 const byte* Payload() const {
821 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
822 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
823 return data_ + kHeaderSize + reservations_size + code_stubs_size;
824 }
825
826 int PayloadLength() const {
827 int payload_length = GetHeaderValue(kPayloadLengthOffset);
828 DCHECK_EQ(data_ + size_, Payload() + payload_length);
829 return payload_length;
830 }
831 850
832 private: 851 private:
833 explicit SerializedCodeData(ScriptData* data) 852 explicit SerializedCodeData(ScriptData* data)
834 : data_(const_cast<byte*>(data->data())), 853 : SerializedData(const_cast<byte*>(data->data()), data->length()) {}
835 size_(data->length()),
836 owns_script_data_(false) {}
837
838 void SetHeaderValue(int offset, int value) {
839 reinterpret_cast<int*>(data_)[offset] = value;
840 }
841
842 int GetHeaderValue(int offset) const {
843 return reinterpret_cast<const int*>(data_)[offset];
844 }
845 854
846 bool IsSane(String* source); 855 bool IsSane(String* source);
847 856
848 int CheckSum(String* source); 857 int CheckSum(String* source);
849 858
850 // The data header consists of int-sized entries: 859 // The data header consists of int-sized entries:
851 // [0] version hash 860 // [0] version hash
852 // [1] number of internalized strings 861 // [1] number of internalized strings
853 // [2] number of code stub keys 862 // [2] number of code stub keys
854 // [3] number of reservation size entries 863 // [3] number of reservation size entries
855 // [3] payload length 864 // [4] payload length
856 static const int kCheckSumOffset = 0; 865 static const int kCheckSumOffset = 0;
857 static const int kNumInternalizedStringsOffset = 1; 866 static const int kNumInternalizedStringsOffset = 1;
858 static const int kReservationsOffset = 2; 867 static const int kReservationsOffset = 2;
859 static const int kNumCodeStubKeysOffset = 3; 868 static const int kNumCodeStubKeysOffset = 3;
860 static const int kPayloadLengthOffset = 4; 869 static const int kPayloadLengthOffset = 4;
861 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; 870 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
862
863 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
864 class IsLastChunkBits : public BitField<bool, 31, 1> {};
865
866 byte* data_;
867 int size_;
868 bool owns_script_data_;
869 }; 871 };
870 } } // namespace v8::internal 872 } } // namespace v8::internal
871 873
872 #endif // V8_SERIALIZE_H_ 874 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | src/serialize.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698