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

Side by Side Diff: src/serialize.h

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