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

Side by Side Diff: src/serialize.h

Issue 781943002: Reland "Encode reservation meta data in the snapshot blob." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase 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
« no previous file with comments | « src/natives-external.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 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 // Sentinel after a new object to indicate that double alignment is needed. 446 // Sentinel after a new object to indicate that double alignment is needed.
447 static const int kDoubleAlignmentSentinel = 0; 447 static const int kDoubleAlignmentSentinel = 0;
448 448
449 // Used as index for the attached reference representing the source object. 449 // Used as index for the attached reference representing the source object.
450 static const int kSourceObjectReference = 0; 450 static const int kSourceObjectReference = 0;
451 451
452 HotObjectsList hot_objects_; 452 HotObjectsList hot_objects_;
453 }; 453 };
454 454
455 455
456 class SerializedData {
457 public:
458 class Reservation {
459 public:
460 explicit Reservation(uint32_t size)
461 : reservation_(ChunkSizeBits::encode(size)) {}
462
463 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
464 bool is_last() const { return IsLastChunkBits::decode(reservation_); }
465
466 void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
467
468 private:
469 uint32_t reservation_;
470 };
471
472 SerializedData(byte* data, int size)
473 : data_(data), size_(size), owns_data_(false) {}
474 SerializedData() : data_(NULL), size_(0), owns_data_(false) {}
475
476 ~SerializedData() {
477 if (owns_data_) DeleteArray<byte>(data_);
478 }
479
480 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
481 class IsLastChunkBits : public BitField<bool, 31, 1> {};
482
483 protected:
484 void SetHeaderValue(int offset, int value) {
485 reinterpret_cast<int*>(data_)[offset] = value;
486 }
487
488 int GetHeaderValue(int offset) const {
489 return reinterpret_cast<const int*>(data_)[offset];
490 }
491
492 void AllocateData(int size);
493
494 byte* data_;
495 int size_;
496 bool owns_data_;
497 };
498
499
456 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. 500 // A Deserializer reads a snapshot and reconstructs the Object graph it defines.
457 class Deserializer: public SerializerDeserializer { 501 class Deserializer: public SerializerDeserializer {
458 public: 502 public:
459 // Create a deserializer from a snapshot byte source. 503 // Create a deserializer from a snapshot byte source.
460 explicit Deserializer(SnapshotByteSource* source); 504 template <class Data>
505 explicit Deserializer(Data* data)
506 : isolate_(NULL),
507 attached_objects_(NULL),
508 source_(data->Payload()),
509 external_reference_decoder_(NULL),
510 deserialized_large_objects_(0) {
511 DecodeReservation(data->Reservations());
512 }
461 513
462 virtual ~Deserializer(); 514 virtual ~Deserializer();
463 515
464 // Deserialize the snapshot into an empty heap. 516 // Deserialize the snapshot into an empty heap.
465 void Deserialize(Isolate* isolate); 517 void Deserialize(Isolate* isolate);
466 518
467 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM }; 519 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM };
468 520
469 // Deserialize a single object and the objects reachable from it. 521 // Deserialize a single object and the objects reachable from it.
470 // We may want to abort gracefully even if deserialization fails. 522 // We may want to abort gracefully even if deserialization fails.
471 void DeserializePartial(Isolate* isolate, Object** root, 523 void DeserializePartial(Isolate* isolate, Object** root,
472 OnOOM on_oom = FATAL_ON_OOM); 524 OnOOM on_oom = FATAL_ON_OOM);
473 525
474 void AddReservation(int space, uint32_t chunk) {
475 DCHECK(space >= 0);
476 DCHECK(space < kNumberOfSpaces);
477 reservations_[space].Add({chunk, NULL, NULL});
478 }
479
480 void FlushICacheForNewCodeObjects(); 526 void FlushICacheForNewCodeObjects();
481 527
482 // Serialized user code reference certain objects that are provided in a list 528 // Serialized user code reference certain objects that are provided in a list
483 // By calling this method, we assume that we are deserializing user code. 529 // By calling this method, we assume that we are deserializing user code.
484 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { 530 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) {
485 attached_objects_ = attached_objects; 531 attached_objects_ = attached_objects;
486 } 532 }
487 533
488 bool deserializing_user_code() { return attached_objects_ != NULL; } 534 bool deserializing_user_code() { return attached_objects_ != NULL; }
489 535
490 private: 536 private:
491 virtual void VisitPointers(Object** start, Object** end); 537 virtual void VisitPointers(Object** start, Object** end);
492 538
493 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { 539 virtual void VisitRuntimeEntry(RelocInfo* rinfo) {
494 UNREACHABLE(); 540 UNREACHABLE();
495 } 541 }
496 542
543 void DecodeReservation(Vector<const SerializedData::Reservation> res);
544
497 bool ReserveSpace(); 545 bool ReserveSpace();
498 546
499 // Allocation sites are present in the snapshot, and must be linked into 547 // Allocation sites are present in the snapshot, and must be linked into
500 // a list at deserialization time. 548 // a list at deserialization time.
501 void RelinkAllocationSite(AllocationSite* site); 549 void RelinkAllocationSite(AllocationSite* site);
502 550
503 // Fills in some heap data in an area from start to end (non-inclusive). The 551 // Fills in some heap data in an area from start to end (non-inclusive). The
504 // space id is used for the write barrier. The object_address is the address 552 // space id is used for the write barrier. The object_address is the address
505 // of the object we are writing into, or NULL if we are not writing into an 553 // of the object we are writing into, or NULL if we are not writing into an
506 // object, i.e. if we are writing a series of tagged values that are not on 554 // object, i.e. if we are writing a series of tagged values that are not on
507 // the heap. 555 // the heap.
508 void ReadData(Object** start, Object** end, int space, 556 void ReadData(Object** start, Object** end, int space,
509 Address object_address); 557 Address object_address);
510 void ReadObject(int space_number, Object** write_back); 558 void ReadObject(int space_number, Object** write_back);
511 Address Allocate(int space_index, int size); 559 Address Allocate(int space_index, int size);
512 560
513 // Special handling for serialized code like hooking up internalized strings. 561 // Special handling for serialized code like hooking up internalized strings.
514 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 562 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
515 563
516 // This returns the address of an object that has been described in the 564 // This returns the address of an object that has been described in the
517 // snapshot by chunk index and offset. 565 // snapshot by chunk index and offset.
518 HeapObject* GetBackReferencedObject(int space); 566 HeapObject* GetBackReferencedObject(int space);
519 567
520 // Cached current isolate. 568 // Cached current isolate.
521 Isolate* isolate_; 569 Isolate* isolate_;
522 570
523 // Objects from the attached object descriptions in the serialized user code. 571 // Objects from the attached object descriptions in the serialized user code.
524 Vector<Handle<Object> >* attached_objects_; 572 Vector<Handle<Object> >* attached_objects_;
525 573
526 SnapshotByteSource* source_; 574 SnapshotByteSource source_;
527 // The address of the next object that will be allocated in each space. 575 // The address of the next object that will be allocated in each space.
528 // Each space has a number of chunks reserved by the GC, with each chunk 576 // Each space has a number of chunks reserved by the GC, with each chunk
529 // fitting into a page. Deserialized objects are allocated into the 577 // fitting into a page. Deserialized objects are allocated into the
530 // current chunk of the target space by bumping up high water mark. 578 // current chunk of the target space by bumping up high water mark.
531 Heap::Reservation reservations_[kNumberOfSpaces]; 579 Heap::Reservation reservations_[kNumberOfSpaces];
532 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; 580 uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
533 Address high_water_[kNumberOfPreallocatedSpaces]; 581 Address high_water_[kNumberOfPreallocatedSpaces];
534 582
535 ExternalReferenceDecoder* external_reference_decoder_; 583 ExternalReferenceDecoder* external_reference_decoder_;
536 584
537 List<HeapObject*> deserialized_large_objects_; 585 List<HeapObject*> deserialized_large_objects_;
538 586
539 DISALLOW_COPY_AND_ASSIGN(Deserializer); 587 DISALLOW_COPY_AND_ASSIGN(Deserializer);
540 }; 588 };
541 589
542 590
543 class CodeAddressMap; 591 class CodeAddressMap;
544 592
545 // There can be only one serializer per V8 process. 593 // There can be only one serializer per V8 process.
546 class Serializer : public SerializerDeserializer { 594 class Serializer : public SerializerDeserializer {
547 public: 595 public:
548 Serializer(Isolate* isolate, SnapshotByteSink* sink); 596 Serializer(Isolate* isolate, SnapshotByteSink* sink);
549 ~Serializer(); 597 ~Serializer();
550 virtual void VisitPointers(Object** start, Object** end) OVERRIDE; 598 virtual void VisitPointers(Object** start, Object** end) OVERRIDE;
551 599
552 void FinalizeAllocation(); 600 void EncodeReservations(List<SerializedData::Reservation>* out) const;
553
554 Vector<const uint32_t> FinalAllocationChunks(int space) const {
555 if (space == LO_SPACE) {
556 return Vector<const uint32_t>(&large_objects_total_size_, 1);
557 } else {
558 DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks.
559 return completed_chunks_[space].ToConstVector();
560 }
561 }
562 601
563 Isolate* isolate() const { return isolate_; } 602 Isolate* isolate() const { return isolate_; }
564 603
565 BackReferenceMap* back_reference_map() { return &back_reference_map_; } 604 BackReferenceMap* back_reference_map() { return &back_reference_map_; }
566 RootIndexMap* root_index_map() { return &root_index_map_; } 605 RootIndexMap* root_index_map() { return &root_index_map_; }
567 606
568 protected: 607 protected:
569 class ObjectSerializer : public ObjectVisitor { 608 class ObjectSerializer : public ObjectVisitor {
570 public: 609 public:
571 ObjectSerializer(Serializer* serializer, 610 ObjectSerializer(Serializer* serializer,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 static const int kSourceObjectIndex = 0; 814 static const int kSourceObjectIndex = 0;
776 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex); 815 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex);
777 816
778 static const int kCodeStubsBaseIndex = 1; 817 static const int kCodeStubsBaseIndex = 1;
779 818
780 String* source() const { 819 String* source() const {
781 DCHECK(!AllowHeapAllocation::IsAllowed()); 820 DCHECK(!AllowHeapAllocation::IsAllowed());
782 return source_; 821 return source_;
783 } 822 }
784 823
785 List<uint32_t>* stub_keys() { return &stub_keys_; } 824 const List<uint32_t>* stub_keys() const { return &stub_keys_; }
786 int num_internalized_strings() const { return num_internalized_strings_; } 825 int num_internalized_strings() const { return num_internalized_strings_; }
787 826
788 private: 827 private:
789 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source, 828 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source,
790 Code* main_code) 829 Code* main_code)
791 : Serializer(isolate, sink), 830 : Serializer(isolate, sink),
792 source_(source), 831 source_(source),
793 main_code_(main_code), 832 main_code_(main_code),
794 num_internalized_strings_(0) { 833 num_internalized_strings_(0) {
795 back_reference_map_.AddSourceString(source); 834 back_reference_map_.AddSourceString(source);
(...skipping 16 matching lines...) Expand all
812 851
813 DisallowHeapAllocation no_gc_; 852 DisallowHeapAllocation no_gc_;
814 String* source_; 853 String* source_;
815 Code* main_code_; 854 Code* main_code_;
816 int num_internalized_strings_; 855 int num_internalized_strings_;
817 List<uint32_t> stub_keys_; 856 List<uint32_t> stub_keys_;
818 DISALLOW_COPY_AND_ASSIGN(CodeSerializer); 857 DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
819 }; 858 };
820 859
821 860
861 // Wrapper around reservation sizes and the serialization payload.
862 class SnapshotData : public SerializedData {
863 public:
864 // Used when producing.
865 SnapshotData(const SnapshotByteSink& sink, const Serializer& ser);
866
867 // Used when consuming.
868 explicit SnapshotData(const byte* data, int size)
869 : SerializedData(const_cast<byte*>(data), size) {
870 CHECK(IsSane());
871 }
872
873 Vector<const Reservation> Reservations() const;
874 Vector<const byte> Payload() const;
875
876 Vector<const byte> RawData() const {
877 return Vector<const byte>(data_, size_);
878 }
879
880 private:
881 bool IsSane();
882 // The data header consists of int-sized entries:
883 // [0] version hash
884 // [1] number of reservation size entries
885 // [2] payload length
886 static const int kCheckSumOffset = 0;
887 static const int kReservationsOffset = 1;
888 static const int kPayloadLengthOffset = 2;
889 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
890 };
891
892
822 // Wrapper around ScriptData to provide code-serializer-specific functionality. 893 // Wrapper around ScriptData to provide code-serializer-specific functionality.
823 class SerializedCodeData { 894 class SerializedCodeData : public SerializedData {
824 public: 895 public:
825 // Used by when consuming. 896 // Used when consuming.
826 static SerializedCodeData* FromCachedData(ScriptData* cached_data, 897 static SerializedCodeData* FromCachedData(ScriptData* cached_data,
827 String* source) { 898 String* source) {
828 DisallowHeapAllocation no_gc; 899 DisallowHeapAllocation no_gc;
829 SerializedCodeData* scd = new SerializedCodeData(cached_data); 900 SerializedCodeData* scd = new SerializedCodeData(cached_data);
830 if (scd->IsSane(source)) return scd; 901 if (scd->IsSane(source)) return scd;
831 cached_data->Reject(); 902 cached_data->Reject();
832 delete scd; 903 delete scd;
833 return NULL; 904 return NULL;
834 } 905 }
835 906
836 // Used when producing. 907 // Used when producing.
837 SerializedCodeData(const List<byte>& payload, CodeSerializer* cs); 908 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs);
838
839 ~SerializedCodeData() {
840 if (owns_script_data_) delete script_data_;
841 }
842 909
843 // Return ScriptData object and relinquish ownership over it to the caller. 910 // Return ScriptData object and relinquish ownership over it to the caller.
844 ScriptData* GetScriptData() { 911 ScriptData* GetScriptData();
845 ScriptData* result = script_data_;
846 script_data_ = NULL;
847 DCHECK(owns_script_data_);
848 owns_script_data_ = false;
849 return result;
850 }
851 912
852 class Reservation { 913 Vector<const Reservation> Reservations() const;
853 public: 914 Vector<const byte> Payload() const;
854 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation); }
855 bool is_last_chunk() const { return IsLastChunkBits::decode(reservation); }
856 915
857 private: 916 int NumInternalizedStrings() const;
858 uint32_t reservation; 917 Vector<const uint32_t> CodeStubKeys() const;
859
860 DISALLOW_COPY_AND_ASSIGN(Reservation);
861 };
862
863 int NumInternalizedStrings() const {
864 return GetHeaderValue(kNumInternalizedStringsOffset);
865 }
866
867 Vector<const Reservation> Reservations() const {
868 return Vector<const Reservation>(reinterpret_cast<const Reservation*>(
869 script_data_->data() + kHeaderSize),
870 GetHeaderValue(kReservationsOffset));
871 }
872
873 Vector<const uint32_t> CodeStubKeys() const {
874 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
875 const byte* start = script_data_->data() + kHeaderSize + reservations_size;
876 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
877 GetHeaderValue(kNumCodeStubKeysOffset));
878 }
879
880 const byte* Payload() const {
881 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
882 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
883 return script_data_->data() + kHeaderSize + reservations_size +
884 code_stubs_size;
885 }
886
887 int PayloadLength() const {
888 int payload_length = GetHeaderValue(kPayloadLengthOffset);
889 DCHECK_EQ(script_data_->data() + script_data_->length(),
890 Payload() + payload_length);
891 return payload_length;
892 }
893 918
894 private: 919 private:
895 explicit SerializedCodeData(ScriptData* data) 920 explicit SerializedCodeData(ScriptData* data)
896 : script_data_(data), owns_script_data_(false) {} 921 : SerializedData(const_cast<byte*>(data->data()), data->length()) {}
897
898 void SetHeaderValue(int offset, int value) {
899 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] =
900 value;
901 }
902
903 int GetHeaderValue(int offset) const {
904 return reinterpret_cast<const int*>(script_data_->data())[offset];
905 }
906 922
907 bool IsSane(String* source); 923 bool IsSane(String* source);
908 924
909 int CheckSum(String* source); 925 int CheckSum(String* source);
910 926
911 // The data header consists of int-sized entries: 927 // The data header consists of int-sized entries:
912 // [0] version hash 928 // [0] version hash
913 // [1] number of internalized strings 929 // [1] number of internalized strings
914 // [2] number of code stub keys 930 // [2] number of code stub keys
915 // [3] payload length 931 // [3] number of reservation size entries
916 // [4..10] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. 932 // [4] payload length
917 static const int kCheckSumOffset = 0; 933 static const int kCheckSumOffset = 0;
918 static const int kNumInternalizedStringsOffset = 1; 934 static const int kNumInternalizedStringsOffset = 1;
919 static const int kReservationsOffset = 2; 935 static const int kReservationsOffset = 2;
920 static const int kNumCodeStubKeysOffset = 3; 936 static const int kNumCodeStubKeysOffset = 3;
921 static const int kPayloadLengthOffset = 4; 937 static const int kPayloadLengthOffset = 4;
922 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; 938 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
923
924 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
925 class IsLastChunkBits : public BitField<bool, 31, 1> {};
926
927 // Following the header, we store, in sequential order
928 // - code stub keys
929 // - serialization payload
930
931 ScriptData* script_data_;
932 bool owns_script_data_;
933 }; 939 };
934 } } // namespace v8::internal 940 } } // namespace v8::internal
935 941
936 #endif // V8_SERIALIZE_H_ 942 #endif // V8_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/natives-external.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698