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

Side by Side Diff: src/snapshot/serialize.h

Issue 1125073004: Prevent stack overflow in the serializer/deserializer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixed all Created 5 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/objects.cc ('k') | src/snapshot/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_SNAPSHOT_SERIALIZE_H_ 5 #ifndef V8_SNAPSHOT_SERIALIZE_H_
6 #define V8_SNAPSHOT_SERIALIZE_H_ 6 #define V8_SNAPSHOT_SERIALIZE_H_
7 7
8 #include "src/hashmap.h" 8 #include "src/hashmap.h"
9 #include "src/heap-profiler.h" 9 #include "src/heap-profiler.h"
10 #include "src/isolate.h" 10 #include "src/isolate.h"
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 public: 299 public:
300 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); 300 static void Iterate(Isolate* isolate, ObjectVisitor* visitor);
301 301
302 static int nop() { return kNop; } 302 static int nop() { return kNop; }
303 303
304 // No reservation for large object space necessary. 304 // No reservation for large object space necessary.
305 static const int kNumberOfPreallocatedSpaces = LAST_PAGED_SPACE + 1; 305 static const int kNumberOfPreallocatedSpaces = LAST_PAGED_SPACE + 1;
306 static const int kNumberOfSpaces = LAST_SPACE + 1; 306 static const int kNumberOfSpaces = LAST_SPACE + 1;
307 307
308 protected: 308 protected:
309 static bool CanBeDeferred(HeapObject* o) {
310 return !o->IsString() && !o->IsScript();
311 }
312
309 // ---------- byte code range 0x00..0x7f ---------- 313 // ---------- byte code range 0x00..0x7f ----------
310 // Byte codes in this range represent Where, HowToCode and WhereToPoint. 314 // Byte codes in this range represent Where, HowToCode and WhereToPoint.
311 // Where the pointed-to object can be found: 315 // Where the pointed-to object can be found:
312 // The static assert below will trigger when the number of preallocated spaces 316 // The static assert below will trigger when the number of preallocated spaces
313 // changed. If that happens, update the bytecode ranges in the comments below. 317 // changed. If that happens, update the bytecode ranges in the comments below.
314 STATIC_ASSERT(5 == kNumberOfSpaces); 318 STATIC_ASSERT(5 == kNumberOfSpaces);
315 enum Where { 319 enum Where {
316 // 0x00..0x04 Allocate new object, in specified space. 320 // 0x00..0x04 Allocate new object, in specified space.
317 kNewObject = 0, 321 kNewObject = 0,
318 // 0x05 Unused (including 0x25, 0x45, 0x65). 322 // 0x05 Unused (including 0x25, 0x45, 0x65).
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 // ---------- Misc ---------- 370 // ---------- Misc ----------
367 // Skip. 371 // Skip.
368 static const int kSkip = 0x1d; 372 static const int kSkip = 0x1d;
369 // Internal reference encoded as offsets of pc and target from code entry. 373 // Internal reference encoded as offsets of pc and target from code entry.
370 static const int kInternalReference = 0x1e; 374 static const int kInternalReference = 0x1e;
371 static const int kInternalReferenceEncoded = 0x1f; 375 static const int kInternalReferenceEncoded = 0x1f;
372 // Do nothing, used for padding. 376 // Do nothing, used for padding.
373 static const int kNop = 0x3d; 377 static const int kNop = 0x3d;
374 // Move to next reserved chunk. 378 // Move to next reserved chunk.
375 static const int kNextChunk = 0x3e; 379 static const int kNextChunk = 0x3e;
380 // Deferring object content.
381 static const int kDeferred = 0x3f;
376 // A tag emitted at strategic points in the snapshot to delineate sections. 382 // A tag emitted at strategic points in the snapshot to delineate sections.
377 // If the deserializer does not find these at the expected moments then it 383 // If the deserializer does not find these at the expected moments then it
378 // is an indication that the snapshot and the VM do not fit together. 384 // is an indication that the snapshot and the VM do not fit together.
379 // Examine the build process for architecture, version or configuration 385 // Examine the build process for architecture, version or configuration
380 // mismatches. 386 // mismatches.
381 static const int kSynchronize = 0x5d; 387 static const int kSynchronize = 0x5d;
382 // Used for the source code of the natives, which is in the executable, but 388 // Used for the source code of the natives, which is in the executable, but
383 // is referred to from external strings in the snapshot. 389 // is referred to from external strings in the snapshot.
384 static const int kNativesStringResource = 0x5e; 390 static const int kNativesStringResource = 0x5e;
385 // Raw data of variable length. 391 // Raw data of variable length.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 bool deserializing_user_code() { return deserializing_user_code_; } 552 bool deserializing_user_code() { return deserializing_user_code_; }
547 553
548 void DecodeReservation(Vector<const SerializedData::Reservation> res); 554 void DecodeReservation(Vector<const SerializedData::Reservation> res);
549 555
550 bool ReserveSpace(); 556 bool ReserveSpace();
551 557
552 void UnalignedCopy(Object** dest, Object** src) { 558 void UnalignedCopy(Object** dest, Object** src) {
553 memcpy(dest, src, sizeof(*src)); 559 memcpy(dest, src, sizeof(*src));
554 } 560 }
555 561
556 // Allocation sites are present in the snapshot, and must be linked into 562 void DeserializeDeferredObjects();
557 // a list at deserialization time.
558 void RelinkAllocationSite(AllocationSite* site);
559 563
560 // Fills in some heap data in an area from start to end (non-inclusive). The 564 // Fills in some heap data in an area from start to end (non-inclusive). The
561 // space id is used for the write barrier. The object_address is the address 565 // space id is used for the write barrier. The object_address is the address
562 // of the object we are writing into, or NULL if we are not writing into an 566 // of the object we are writing into, or NULL if we are not writing into an
563 // object, i.e. if we are writing a series of tagged values that are not on 567 // object, i.e. if we are writing a series of tagged values that are not on
564 // the heap. 568 // the heap. Return false if the object content has been deferred.
565 void ReadData(Object** start, Object** end, int space, 569 bool ReadData(Object** start, Object** end, int space,
566 Address object_address); 570 Address object_address);
567 void ReadObject(int space_number, Object** write_back); 571 void ReadObject(int space_number, Object** write_back);
568 Address Allocate(int space_index, int size); 572 Address Allocate(int space_index, int size);
569 573
570 // Special handling for serialized code like hooking up internalized strings. 574 // Special handling for serialized code like hooking up internalized strings.
571 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); 575 HeapObject* PostProcessNewObject(HeapObject* obj);
576
577 void RelinkAllocationSite(AllocationSite* obj);
572 578
573 // This returns the address of an object that has been described in the 579 // This returns the address of an object that has been described in the
574 // snapshot by chunk index and offset. 580 // snapshot by chunk index and offset.
575 HeapObject* GetBackReferencedObject(int space); 581 HeapObject* GetBackReferencedObject(int space);
576 582
577 // Cached current isolate. 583 // Cached current isolate.
578 Isolate* isolate_; 584 Isolate* isolate_;
579 585
580 // Objects from the attached object descriptions in the serialized user code. 586 // Objects from the attached object descriptions in the serialized user code.
581 Vector<Handle<Object> > attached_objects_; 587 Vector<Handle<Object> > attached_objects_;
(...skipping 23 matching lines...) Expand all
605 611
606 // There can be only one serializer per V8 process. 612 // There can be only one serializer per V8 process.
607 class Serializer : public SerializerDeserializer { 613 class Serializer : public SerializerDeserializer {
608 public: 614 public:
609 Serializer(Isolate* isolate, SnapshotByteSink* sink); 615 Serializer(Isolate* isolate, SnapshotByteSink* sink);
610 ~Serializer(); 616 ~Serializer();
611 void VisitPointers(Object** start, Object** end) override; 617 void VisitPointers(Object** start, Object** end) override;
612 618
613 void EncodeReservations(List<SerializedData::Reservation>* out) const; 619 void EncodeReservations(List<SerializedData::Reservation>* out) const;
614 620
621 void SerializeDeferredObjects();
622
615 Isolate* isolate() const { return isolate_; } 623 Isolate* isolate() const { return isolate_; }
616 624
617 BackReferenceMap* back_reference_map() { return &back_reference_map_; } 625 BackReferenceMap* back_reference_map() { return &back_reference_map_; }
618 RootIndexMap* root_index_map() { return &root_index_map_; } 626 RootIndexMap* root_index_map() { return &root_index_map_; }
619 627
620 #ifdef OBJECT_PRINT 628 #ifdef OBJECT_PRINT
621 void CountInstanceType(Map* map, int size); 629 void CountInstanceType(Map* map, int size);
622 #endif // OBJECT_PRINT 630 #endif // OBJECT_PRINT
623 631
624 protected: 632 protected:
625 class ObjectSerializer : public ObjectVisitor { 633 class ObjectSerializer : public ObjectVisitor {
626 public: 634 public:
627 ObjectSerializer(Serializer* serializer, Object* o, SnapshotByteSink* sink, 635 ObjectSerializer(Serializer* serializer, Object* o, SnapshotByteSink* sink,
628 HowToCode how_to_code, WhereToPoint where_to_point) 636 HowToCode how_to_code, WhereToPoint where_to_point)
629 : serializer_(serializer), 637 : serializer_(serializer),
630 object_(HeapObject::cast(o)), 638 object_(HeapObject::cast(o)),
631 sink_(sink), 639 sink_(sink),
632 reference_representation_(how_to_code + where_to_point), 640 reference_representation_(how_to_code + where_to_point),
633 bytes_processed_so_far_(0), 641 bytes_processed_so_far_(0),
634 is_code_object_(o->IsCode()), 642 is_code_object_(o->IsCode()),
635 code_has_been_output_(false) {} 643 code_has_been_output_(false) {}
636 void Serialize(); 644 void Serialize();
645 void SerializeDeferred();
637 void VisitPointers(Object** start, Object** end); 646 void VisitPointers(Object** start, Object** end);
638 void VisitEmbeddedPointer(RelocInfo* target); 647 void VisitEmbeddedPointer(RelocInfo* target);
639 void VisitExternalReference(Address* p); 648 void VisitExternalReference(Address* p);
640 void VisitExternalReference(RelocInfo* rinfo); 649 void VisitExternalReference(RelocInfo* rinfo);
641 void VisitInternalReference(RelocInfo* rinfo); 650 void VisitInternalReference(RelocInfo* rinfo);
642 void VisitCodeTarget(RelocInfo* target); 651 void VisitCodeTarget(RelocInfo* target);
643 void VisitCodeEntry(Address entry_address); 652 void VisitCodeEntry(Address entry_address);
644 void VisitCell(RelocInfo* rinfo); 653 void VisitCell(RelocInfo* rinfo);
645 void VisitRuntimeEntry(RelocInfo* reloc); 654 void VisitRuntimeEntry(RelocInfo* reloc);
646 // Used for seralizing the external strings that hold the natives source. 655 // Used for seralizing the external strings that hold the natives source.
(...skipping 21 matching lines...) Expand all
668 677
669 Serializer* serializer_; 678 Serializer* serializer_;
670 HeapObject* object_; 679 HeapObject* object_;
671 SnapshotByteSink* sink_; 680 SnapshotByteSink* sink_;
672 int reference_representation_; 681 int reference_representation_;
673 int bytes_processed_so_far_; 682 int bytes_processed_so_far_;
674 bool is_code_object_; 683 bool is_code_object_;
675 bool code_has_been_output_; 684 bool code_has_been_output_;
676 }; 685 };
677 686
687 class RecursionScope {
688 public:
689 explicit RecursionScope(Serializer* serializer) : serializer_(serializer) {
690 serializer_->recursion_depth_++;
691 }
692 ~RecursionScope() { serializer_->recursion_depth_--; }
693 bool ExceedsMaximum() {
694 return serializer_->recursion_depth_ >= kMaxRecursionDepth;
695 }
696
697 private:
698 static const int kMaxRecursionDepth = 32;
699 Serializer* serializer_;
700 };
701
678 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, 702 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
679 WhereToPoint where_to_point, int skip) = 0; 703 WhereToPoint where_to_point, int skip) = 0;
680 704
681 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, 705 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
682 int skip); 706 int skip);
683 707
708 void PutBackReference(HeapObject* object, BackReference reference);
709
684 // Returns true if the object was successfully serialized. 710 // Returns true if the object was successfully serialized.
685 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, 711 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
686 WhereToPoint where_to_point, int skip); 712 WhereToPoint where_to_point, int skip);
687 713
688 inline void FlushSkip(int skip) { 714 inline void FlushSkip(int skip) {
689 if (skip != 0) { 715 if (skip != 0) {
690 sink_->Put(kSkip, "SkipFromSerializeObject"); 716 sink_->Put(kSkip, "SkipFromSerializeObject");
691 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); 717 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
692 } 718 }
693 } 719 }
(...skipping 21 matching lines...) Expand all
715 Code* CopyCode(Code* code); 741 Code* CopyCode(Code* code);
716 742
717 inline uint32_t max_chunk_size(int space) const { 743 inline uint32_t max_chunk_size(int space) const {
718 DCHECK_LE(0, space); 744 DCHECK_LE(0, space);
719 DCHECK_LT(space, kNumberOfSpaces); 745 DCHECK_LT(space, kNumberOfSpaces);
720 return max_chunk_size_[space]; 746 return max_chunk_size_[space];
721 } 747 }
722 748
723 SnapshotByteSink* sink() const { return sink_; } 749 SnapshotByteSink* sink() const { return sink_; }
724 750
751 void QueueDeferredObject(HeapObject* obj) {
752 DCHECK(back_reference_map_.Lookup(obj).is_valid());
753 deferred_objects_.Add(obj);
754 }
755
725 void OutputStatistics(const char* name); 756 void OutputStatistics(const char* name);
726 757
727 Isolate* isolate_; 758 Isolate* isolate_;
728 759
729 SnapshotByteSink* sink_; 760 SnapshotByteSink* sink_;
730 ExternalReferenceEncoder external_reference_encoder_; 761 ExternalReferenceEncoder external_reference_encoder_;
731 762
732 BackReferenceMap back_reference_map_; 763 BackReferenceMap back_reference_map_;
733 RootIndexMap root_index_map_; 764 RootIndexMap root_index_map_;
734 765
766 int recursion_depth_;
767
735 friend class Deserializer; 768 friend class Deserializer;
736 friend class ObjectSerializer; 769 friend class ObjectSerializer;
770 friend class RecursionScope;
737 friend class SnapshotData; 771 friend class SnapshotData;
738 772
739 private: 773 private:
740 CodeAddressMap* code_address_map_; 774 CodeAddressMap* code_address_map_;
741 // Objects from the same space are put into chunks for bulk-allocation 775 // Objects from the same space are put into chunks for bulk-allocation
742 // when deserializing. We have to make sure that each chunk fits into a 776 // when deserializing. We have to make sure that each chunk fits into a
743 // page. So we track the chunk size in pending_chunk_ of a space, but 777 // page. So we track the chunk size in pending_chunk_ of a space, but
744 // when it exceeds a page, we complete the current chunk and start a new one. 778 // when it exceeds a page, we complete the current chunk and start a new one.
745 uint32_t pending_chunk_[kNumberOfPreallocatedSpaces]; 779 uint32_t pending_chunk_[kNumberOfPreallocatedSpaces];
746 List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces]; 780 List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces];
747 uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces]; 781 uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces];
748 782
749 // We map serialized large objects to indexes for back-referencing. 783 // We map serialized large objects to indexes for back-referencing.
750 uint32_t large_objects_total_size_; 784 uint32_t large_objects_total_size_;
751 uint32_t seen_large_objects_index_; 785 uint32_t seen_large_objects_index_;
752 786
753 List<byte> code_buffer_; 787 List<byte> code_buffer_;
754 788
789 // To handle stack overflow.
790 List<HeapObject*> deferred_objects_;
791
755 #ifdef OBJECT_PRINT 792 #ifdef OBJECT_PRINT
756 static const int kInstanceTypes = 256; 793 static const int kInstanceTypes = 256;
757 int* instance_type_count_; 794 int* instance_type_count_;
758 size_t* instance_type_size_; 795 size_t* instance_type_size_;
759 #endif // OBJECT_PRINT 796 #endif // OBJECT_PRINT
760 797
761 DISALLOW_COPY_AND_ASSIGN(Serializer); 798 DISALLOW_COPY_AND_ASSIGN(Serializer);
762 }; 799 };
763 800
764 801
(...skipping 25 matching lines...) Expand all
790 DCHECK(!o->IsScript()); 827 DCHECK(!o->IsScript());
791 return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() || 828 return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() ||
792 o->IsCode() || o->IsScopeInfo() || o->IsExecutableAccessorInfo() || 829 o->IsCode() || o->IsScopeInfo() || o->IsExecutableAccessorInfo() ||
793 o->map() == 830 o->map() ==
794 startup_serializer_->isolate()->heap()->fixed_cow_array_map(); 831 startup_serializer_->isolate()->heap()->fixed_cow_array_map();
795 } 832 }
796 833
797 void SerializeOutdatedContextsAsFixedArray(); 834 void SerializeOutdatedContextsAsFixedArray();
798 835
799 Serializer* startup_serializer_; 836 Serializer* startup_serializer_;
800 List<BackReference> outdated_contexts_; 837 List<Context*> outdated_contexts_;
801 Object* global_object_; 838 Object* global_object_;
802 PartialCacheIndexMap partial_cache_index_map_; 839 PartialCacheIndexMap partial_cache_index_map_;
803 DISALLOW_COPY_AND_ASSIGN(PartialSerializer); 840 DISALLOW_COPY_AND_ASSIGN(PartialSerializer);
804 }; 841 };
805 842
806 843
807 class StartupSerializer : public Serializer { 844 class StartupSerializer : public Serializer {
808 public: 845 public:
809 StartupSerializer(Isolate* isolate, SnapshotByteSink* sink) 846 StartupSerializer(Isolate* isolate, SnapshotByteSink* sink)
810 : Serializer(isolate, sink), root_index_wave_front_(0) { 847 : Serializer(isolate, sink), root_index_wave_front_(0) {
(...skipping 11 matching lines...) Expand all
822 // different. 859 // different.
823 void VisitPointers(Object** start, Object** end) override; 860 void VisitPointers(Object** start, Object** end) override;
824 861
825 // Serialize the current state of the heap. The order is: 862 // Serialize the current state of the heap. The order is:
826 // 1) Strong references. 863 // 1) Strong references.
827 // 2) Partial snapshot cache. 864 // 2) Partial snapshot cache.
828 // 3) Weak references (e.g. the string table). 865 // 3) Weak references (e.g. the string table).
829 virtual void SerializeStrongReferences(); 866 virtual void SerializeStrongReferences();
830 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, 867 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
831 WhereToPoint where_to_point, int skip) override; 868 WhereToPoint where_to_point, int skip) override;
832 void SerializeWeakReferences(); 869 void SerializeWeakReferencesAndDeferred();
833 void Serialize() { 870 void Serialize() {
834 SerializeStrongReferences(); 871 SerializeStrongReferences();
835 SerializeWeakReferences(); 872 SerializeWeakReferencesAndDeferred();
836 Pad();
837 } 873 }
838 874
839 private: 875 private:
840 intptr_t root_index_wave_front_; 876 intptr_t root_index_wave_front_;
841 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); 877 DISALLOW_COPY_AND_ASSIGN(StartupSerializer);
842 }; 878 };
843 879
844 880
845 class CodeSerializer : public Serializer { 881 class CodeSerializer : public Serializer {
846 public: 882 public:
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 kNumInternalizedStringsOffset + kInt32Size; 1031 kNumInternalizedStringsOffset + kInt32Size;
996 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size; 1032 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size;
997 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size; 1033 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size;
998 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size; 1034 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size;
999 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size; 1035 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size;
1000 static const int kHeaderSize = kChecksum2Offset + kInt32Size; 1036 static const int kHeaderSize = kChecksum2Offset + kInt32Size;
1001 }; 1037 };
1002 } } // namespace v8::internal 1038 } } // namespace v8::internal
1003 1039
1004 #endif // V8_SNAPSHOT_SERIALIZE_H_ 1040 #endif // V8_SNAPSHOT_SERIALIZE_H_
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/snapshot/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698