| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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. | 563 |
| 558 void RelinkAllocationSite(AllocationSite* site); | 564 void CommitNewInternalizedStrings(Isolate* isolate); |
| 559 | 565 |
| 560 // Fills in some heap data in an area from start to end (non-inclusive). The | 566 // 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 | 567 // 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 | 568 // 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 | 569 // object, i.e. if we are writing a series of tagged values that are not on |
| 564 // the heap. | 570 // the heap. Return false if the object content has been deferred. |
| 565 void ReadData(Object** start, Object** end, int space, | 571 bool ReadData(Object** start, Object** end, int space, |
| 566 Address object_address); | 572 Address object_address); |
| 567 void ReadObject(int space_number, Object** write_back); | 573 void ReadObject(int space_number, Object** write_back); |
| 568 Address Allocate(int space_index, int size); | 574 Address Allocate(int space_index, int size); |
| 569 | 575 |
| 570 // Special handling for serialized code like hooking up internalized strings. | 576 // Special handling for serialized code like hooking up internalized strings. |
| 571 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); | 577 HeapObject* PostProcessNewObject(HeapObject* obj, int space); |
| 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_; |
| 582 | 588 |
| 583 SnapshotByteSource source_; | 589 SnapshotByteSource source_; |
| 584 uint32_t magic_number_; | 590 uint32_t magic_number_; |
| 585 | 591 |
| 586 // The address of the next object that will be allocated in each space. | 592 // The address of the next object that will be allocated in each space. |
| 587 // Each space has a number of chunks reserved by the GC, with each chunk | 593 // Each space has a number of chunks reserved by the GC, with each chunk |
| 588 // fitting into a page. Deserialized objects are allocated into the | 594 // fitting into a page. Deserialized objects are allocated into the |
| 589 // current chunk of the target space by bumping up high water mark. | 595 // current chunk of the target space by bumping up high water mark. |
| 590 Heap::Reservation reservations_[kNumberOfSpaces]; | 596 Heap::Reservation reservations_[kNumberOfSpaces]; |
| 591 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; | 597 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; |
| 592 Address high_water_[kNumberOfPreallocatedSpaces]; | 598 Address high_water_[kNumberOfPreallocatedSpaces]; |
| 593 | 599 |
| 594 ExternalReferenceTable* external_reference_table_; | 600 ExternalReferenceTable* external_reference_table_; |
| 595 | 601 |
| 596 List<HeapObject*> deserialized_large_objects_; | 602 List<HeapObject*> deserialized_large_objects_; |
| 603 List<Code*> new_code_objects_; |
| 604 List<Handle<String> > new_internalized_strings_; |
| 597 | 605 |
| 598 bool deserializing_user_code_; | 606 bool deserializing_user_code_; |
| 599 | 607 |
| 600 DISALLOW_COPY_AND_ASSIGN(Deserializer); | 608 DISALLOW_COPY_AND_ASSIGN(Deserializer); |
| 601 }; | 609 }; |
| 602 | 610 |
| 603 | 611 |
| 604 class CodeAddressMap; | 612 class CodeAddressMap; |
| 605 | 613 |
| 606 // There can be only one serializer per V8 process. | 614 // There can be only one serializer per V8 process. |
| 607 class Serializer : public SerializerDeserializer { | 615 class Serializer : public SerializerDeserializer { |
| 608 public: | 616 public: |
| 609 Serializer(Isolate* isolate, SnapshotByteSink* sink); | 617 Serializer(Isolate* isolate, SnapshotByteSink* sink); |
| 610 ~Serializer(); | 618 ~Serializer(); |
| 611 void VisitPointers(Object** start, Object** end) override; | 619 void VisitPointers(Object** start, Object** end) override; |
| 612 | 620 |
| 613 void EncodeReservations(List<SerializedData::Reservation>* out) const; | 621 void EncodeReservations(List<SerializedData::Reservation>* out) const; |
| 614 | 622 |
| 623 void SerializeDeferredObjects(); |
| 624 |
| 615 Isolate* isolate() const { return isolate_; } | 625 Isolate* isolate() const { return isolate_; } |
| 616 | 626 |
| 617 BackReferenceMap* back_reference_map() { return &back_reference_map_; } | 627 BackReferenceMap* back_reference_map() { return &back_reference_map_; } |
| 618 RootIndexMap* root_index_map() { return &root_index_map_; } | 628 RootIndexMap* root_index_map() { return &root_index_map_; } |
| 619 | 629 |
| 620 #ifdef OBJECT_PRINT | 630 #ifdef OBJECT_PRINT |
| 621 void CountInstanceType(Map* map, int size); | 631 void CountInstanceType(Map* map, int size); |
| 622 #endif // OBJECT_PRINT | 632 #endif // OBJECT_PRINT |
| 623 | 633 |
| 624 protected: | 634 protected: |
| 625 class ObjectSerializer : public ObjectVisitor { | 635 class ObjectSerializer : public ObjectVisitor { |
| 626 public: | 636 public: |
| 627 ObjectSerializer(Serializer* serializer, Object* o, SnapshotByteSink* sink, | 637 ObjectSerializer(Serializer* serializer, Object* o, SnapshotByteSink* sink, |
| 628 HowToCode how_to_code, WhereToPoint where_to_point) | 638 HowToCode how_to_code, WhereToPoint where_to_point) |
| 629 : serializer_(serializer), | 639 : serializer_(serializer), |
| 630 object_(HeapObject::cast(o)), | 640 object_(HeapObject::cast(o)), |
| 631 sink_(sink), | 641 sink_(sink), |
| 632 reference_representation_(how_to_code + where_to_point), | 642 reference_representation_(how_to_code + where_to_point), |
| 633 bytes_processed_so_far_(0), | 643 bytes_processed_so_far_(0), |
| 634 is_code_object_(o->IsCode()), | 644 is_code_object_(o->IsCode()), |
| 635 code_has_been_output_(false) {} | 645 code_has_been_output_(false) {} |
| 636 void Serialize(); | 646 void Serialize(); |
| 647 void SerializeDeferred(); |
| 637 void VisitPointers(Object** start, Object** end); | 648 void VisitPointers(Object** start, Object** end); |
| 638 void VisitEmbeddedPointer(RelocInfo* target); | 649 void VisitEmbeddedPointer(RelocInfo* target); |
| 639 void VisitExternalReference(Address* p); | 650 void VisitExternalReference(Address* p); |
| 640 void VisitExternalReference(RelocInfo* rinfo); | 651 void VisitExternalReference(RelocInfo* rinfo); |
| 641 void VisitInternalReference(RelocInfo* rinfo); | 652 void VisitInternalReference(RelocInfo* rinfo); |
| 642 void VisitCodeTarget(RelocInfo* target); | 653 void VisitCodeTarget(RelocInfo* target); |
| 643 void VisitCodeEntry(Address entry_address); | 654 void VisitCodeEntry(Address entry_address); |
| 644 void VisitCell(RelocInfo* rinfo); | 655 void VisitCell(RelocInfo* rinfo); |
| 645 void VisitRuntimeEntry(RelocInfo* reloc); | 656 void VisitRuntimeEntry(RelocInfo* reloc); |
| 646 // Used for seralizing the external strings that hold the natives source. | 657 // Used for seralizing the external strings that hold the natives source. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 668 | 679 |
| 669 Serializer* serializer_; | 680 Serializer* serializer_; |
| 670 HeapObject* object_; | 681 HeapObject* object_; |
| 671 SnapshotByteSink* sink_; | 682 SnapshotByteSink* sink_; |
| 672 int reference_representation_; | 683 int reference_representation_; |
| 673 int bytes_processed_so_far_; | 684 int bytes_processed_so_far_; |
| 674 bool is_code_object_; | 685 bool is_code_object_; |
| 675 bool code_has_been_output_; | 686 bool code_has_been_output_; |
| 676 }; | 687 }; |
| 677 | 688 |
| 689 class RecursionScope { |
| 690 public: |
| 691 explicit RecursionScope(Serializer* serializer) : serializer_(serializer) { |
| 692 serializer_->recursion_depth_++; |
| 693 } |
| 694 ~RecursionScope() { serializer_->recursion_depth_--; } |
| 695 bool ExceedsMaximum() { |
| 696 return serializer_->recursion_depth_ >= kMaxRecursionDepth; |
| 697 } |
| 698 |
| 699 private: |
| 700 static const int kMaxRecursionDepth = 32; |
| 701 Serializer* serializer_; |
| 702 }; |
| 703 |
| 678 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, | 704 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, |
| 679 WhereToPoint where_to_point, int skip) = 0; | 705 WhereToPoint where_to_point, int skip) = 0; |
| 680 | 706 |
| 681 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, | 707 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, |
| 682 int skip); | 708 int skip); |
| 683 | 709 |
| 710 void PutBackReference(HeapObject* object, BackReference reference); |
| 711 |
| 684 // Returns true if the object was successfully serialized. | 712 // Returns true if the object was successfully serialized. |
| 685 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, | 713 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, |
| 686 WhereToPoint where_to_point, int skip); | 714 WhereToPoint where_to_point, int skip); |
| 687 | 715 |
| 688 inline void FlushSkip(int skip) { | 716 inline void FlushSkip(int skip) { |
| 689 if (skip != 0) { | 717 if (skip != 0) { |
| 690 sink_->Put(kSkip, "SkipFromSerializeObject"); | 718 sink_->Put(kSkip, "SkipFromSerializeObject"); |
| 691 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 719 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
| 692 } | 720 } |
| 693 } | 721 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 715 Code* CopyCode(Code* code); | 743 Code* CopyCode(Code* code); |
| 716 | 744 |
| 717 inline uint32_t max_chunk_size(int space) const { | 745 inline uint32_t max_chunk_size(int space) const { |
| 718 DCHECK_LE(0, space); | 746 DCHECK_LE(0, space); |
| 719 DCHECK_LT(space, kNumberOfSpaces); | 747 DCHECK_LT(space, kNumberOfSpaces); |
| 720 return max_chunk_size_[space]; | 748 return max_chunk_size_[space]; |
| 721 } | 749 } |
| 722 | 750 |
| 723 SnapshotByteSink* sink() const { return sink_; } | 751 SnapshotByteSink* sink() const { return sink_; } |
| 724 | 752 |
| 753 void QueueDeferredObject(HeapObject* obj) { |
| 754 DCHECK(back_reference_map_.Lookup(obj).is_valid()); |
| 755 deferred_objects_.Add(obj); |
| 756 } |
| 757 |
| 725 void OutputStatistics(const char* name); | 758 void OutputStatistics(const char* name); |
| 726 | 759 |
| 727 Isolate* isolate_; | 760 Isolate* isolate_; |
| 728 | 761 |
| 729 SnapshotByteSink* sink_; | 762 SnapshotByteSink* sink_; |
| 730 ExternalReferenceEncoder external_reference_encoder_; | 763 ExternalReferenceEncoder external_reference_encoder_; |
| 731 | 764 |
| 732 BackReferenceMap back_reference_map_; | 765 BackReferenceMap back_reference_map_; |
| 733 RootIndexMap root_index_map_; | 766 RootIndexMap root_index_map_; |
| 734 | 767 |
| 768 int recursion_depth_; |
| 769 |
| 735 friend class Deserializer; | 770 friend class Deserializer; |
| 736 friend class ObjectSerializer; | 771 friend class ObjectSerializer; |
| 772 friend class RecursionScope; |
| 737 friend class SnapshotData; | 773 friend class SnapshotData; |
| 738 | 774 |
| 739 private: | 775 private: |
| 740 CodeAddressMap* code_address_map_; | 776 CodeAddressMap* code_address_map_; |
| 741 // Objects from the same space are put into chunks for bulk-allocation | 777 // 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 | 778 // 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 | 779 // 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. | 780 // when it exceeds a page, we complete the current chunk and start a new one. |
| 745 uint32_t pending_chunk_[kNumberOfPreallocatedSpaces]; | 781 uint32_t pending_chunk_[kNumberOfPreallocatedSpaces]; |
| 746 List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces]; | 782 List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces]; |
| 747 uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces]; | 783 uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces]; |
| 748 | 784 |
| 749 // We map serialized large objects to indexes for back-referencing. | 785 // We map serialized large objects to indexes for back-referencing. |
| 750 uint32_t large_objects_total_size_; | 786 uint32_t large_objects_total_size_; |
| 751 uint32_t seen_large_objects_index_; | 787 uint32_t seen_large_objects_index_; |
| 752 | 788 |
| 753 List<byte> code_buffer_; | 789 List<byte> code_buffer_; |
| 754 | 790 |
| 791 // To handle stack overflow. |
| 792 List<HeapObject*> deferred_objects_; |
| 793 |
| 755 #ifdef OBJECT_PRINT | 794 #ifdef OBJECT_PRINT |
| 756 static const int kInstanceTypes = 256; | 795 static const int kInstanceTypes = 256; |
| 757 int* instance_type_count_; | 796 int* instance_type_count_; |
| 758 size_t* instance_type_size_; | 797 size_t* instance_type_size_; |
| 759 #endif // OBJECT_PRINT | 798 #endif // OBJECT_PRINT |
| 760 | 799 |
| 761 DISALLOW_COPY_AND_ASSIGN(Serializer); | 800 DISALLOW_COPY_AND_ASSIGN(Serializer); |
| 762 }; | 801 }; |
| 763 | 802 |
| 764 | 803 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 790 DCHECK(!o->IsScript()); | 829 DCHECK(!o->IsScript()); |
| 791 return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() || | 830 return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() || |
| 792 o->IsCode() || o->IsScopeInfo() || o->IsExecutableAccessorInfo() || | 831 o->IsCode() || o->IsScopeInfo() || o->IsExecutableAccessorInfo() || |
| 793 o->map() == | 832 o->map() == |
| 794 startup_serializer_->isolate()->heap()->fixed_cow_array_map(); | 833 startup_serializer_->isolate()->heap()->fixed_cow_array_map(); |
| 795 } | 834 } |
| 796 | 835 |
| 797 void SerializeOutdatedContextsAsFixedArray(); | 836 void SerializeOutdatedContextsAsFixedArray(); |
| 798 | 837 |
| 799 Serializer* startup_serializer_; | 838 Serializer* startup_serializer_; |
| 800 List<BackReference> outdated_contexts_; | 839 List<Context*> outdated_contexts_; |
| 801 Object* global_object_; | 840 Object* global_object_; |
| 802 PartialCacheIndexMap partial_cache_index_map_; | 841 PartialCacheIndexMap partial_cache_index_map_; |
| 803 DISALLOW_COPY_AND_ASSIGN(PartialSerializer); | 842 DISALLOW_COPY_AND_ASSIGN(PartialSerializer); |
| 804 }; | 843 }; |
| 805 | 844 |
| 806 | 845 |
| 807 class StartupSerializer : public Serializer { | 846 class StartupSerializer : public Serializer { |
| 808 public: | 847 public: |
| 809 StartupSerializer(Isolate* isolate, SnapshotByteSink* sink) | 848 StartupSerializer(Isolate* isolate, SnapshotByteSink* sink) |
| 810 : Serializer(isolate, sink), root_index_wave_front_(0) { | 849 : Serializer(isolate, sink), root_index_wave_front_(0) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 822 // different. | 861 // different. |
| 823 void VisitPointers(Object** start, Object** end) override; | 862 void VisitPointers(Object** start, Object** end) override; |
| 824 | 863 |
| 825 // Serialize the current state of the heap. The order is: | 864 // Serialize the current state of the heap. The order is: |
| 826 // 1) Strong references. | 865 // 1) Strong references. |
| 827 // 2) Partial snapshot cache. | 866 // 2) Partial snapshot cache. |
| 828 // 3) Weak references (e.g. the string table). | 867 // 3) Weak references (e.g. the string table). |
| 829 virtual void SerializeStrongReferences(); | 868 virtual void SerializeStrongReferences(); |
| 830 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, | 869 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, |
| 831 WhereToPoint where_to_point, int skip) override; | 870 WhereToPoint where_to_point, int skip) override; |
| 832 void SerializeWeakReferences(); | 871 void SerializeWeakReferencesAndDeferred(); |
| 833 void Serialize() { | 872 void Serialize() { |
| 834 SerializeStrongReferences(); | 873 SerializeStrongReferences(); |
| 835 SerializeWeakReferences(); | 874 SerializeWeakReferencesAndDeferred(); |
| 836 Pad(); | |
| 837 } | 875 } |
| 838 | 876 |
| 839 private: | 877 private: |
| 840 intptr_t root_index_wave_front_; | 878 intptr_t root_index_wave_front_; |
| 841 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); | 879 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); |
| 842 }; | 880 }; |
| 843 | 881 |
| 844 | 882 |
| 845 class CodeSerializer : public Serializer { | 883 class CodeSerializer : public Serializer { |
| 846 public: | 884 public: |
| 847 static ScriptData* Serialize(Isolate* isolate, | 885 static ScriptData* Serialize(Isolate* isolate, |
| 848 Handle<SharedFunctionInfo> info, | 886 Handle<SharedFunctionInfo> info, |
| 849 Handle<String> source); | 887 Handle<String> source); |
| 850 | 888 |
| 851 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( | 889 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( |
| 852 Isolate* isolate, ScriptData* cached_data, Handle<String> source); | 890 Isolate* isolate, ScriptData* cached_data, Handle<String> source); |
| 853 | 891 |
| 854 static const int kSourceObjectIndex = 0; | 892 static const int kSourceObjectIndex = 0; |
| 855 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex); | 893 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex); |
| 856 | 894 |
| 857 static const int kCodeStubsBaseIndex = 1; | 895 static const int kCodeStubsBaseIndex = 1; |
| 858 | 896 |
| 859 String* source() const { | 897 String* source() const { |
| 860 DCHECK(!AllowHeapAllocation::IsAllowed()); | 898 DCHECK(!AllowHeapAllocation::IsAllowed()); |
| 861 return source_; | 899 return source_; |
| 862 } | 900 } |
| 863 | 901 |
| 864 const List<uint32_t>* stub_keys() const { return &stub_keys_; } | 902 const List<uint32_t>* stub_keys() const { return &stub_keys_; } |
| 865 int num_internalized_strings() const { return num_internalized_strings_; } | |
| 866 | 903 |
| 867 private: | 904 private: |
| 868 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source, | 905 CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source, |
| 869 Code* main_code) | 906 Code* main_code) |
| 870 : Serializer(isolate, sink), | 907 : Serializer(isolate, sink), source_(source), main_code_(main_code) { |
| 871 source_(source), | |
| 872 main_code_(main_code), | |
| 873 num_internalized_strings_(0) { | |
| 874 back_reference_map_.AddSourceString(source); | 908 back_reference_map_.AddSourceString(source); |
| 875 } | 909 } |
| 876 | 910 |
| 877 ~CodeSerializer() { OutputStatistics("CodeSerializer"); } | 911 ~CodeSerializer() { OutputStatistics("CodeSerializer"); } |
| 878 | 912 |
| 879 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, | 913 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, |
| 880 WhereToPoint where_to_point, int skip) override; | 914 WhereToPoint where_to_point, int skip) override; |
| 881 | 915 |
| 882 void SerializeBuiltin(int builtin_index, HowToCode how_to_code, | 916 void SerializeBuiltin(int builtin_index, HowToCode how_to_code, |
| 883 WhereToPoint where_to_point); | 917 WhereToPoint where_to_point); |
| 884 void SerializeIC(Code* ic, HowToCode how_to_code, | 918 void SerializeIC(Code* ic, HowToCode how_to_code, |
| 885 WhereToPoint where_to_point); | 919 WhereToPoint where_to_point); |
| 886 void SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, | 920 void SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, |
| 887 WhereToPoint where_to_point); | 921 WhereToPoint where_to_point); |
| 888 void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code, | 922 void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code, |
| 889 WhereToPoint where_to_point); | 923 WhereToPoint where_to_point); |
| 890 int AddCodeStubKey(uint32_t stub_key); | 924 int AddCodeStubKey(uint32_t stub_key); |
| 891 | 925 |
| 892 DisallowHeapAllocation no_gc_; | 926 DisallowHeapAllocation no_gc_; |
| 893 String* source_; | 927 String* source_; |
| 894 Code* main_code_; | 928 Code* main_code_; |
| 895 int num_internalized_strings_; | |
| 896 List<uint32_t> stub_keys_; | 929 List<uint32_t> stub_keys_; |
| 897 DISALLOW_COPY_AND_ASSIGN(CodeSerializer); | 930 DISALLOW_COPY_AND_ASSIGN(CodeSerializer); |
| 898 }; | 931 }; |
| 899 | 932 |
| 900 | 933 |
| 901 // Wrapper around reservation sizes and the serialization payload. | 934 // Wrapper around reservation sizes and the serialization payload. |
| 902 class SnapshotData : public SerializedData { | 935 class SnapshotData : public SerializedData { |
| 903 public: | 936 public: |
| 904 // Used when producing. | 937 // Used when producing. |
| 905 explicit SnapshotData(const Serializer& ser); | 938 explicit SnapshotData(const Serializer& ser); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 | 977 |
| 945 // Used when producing. | 978 // Used when producing. |
| 946 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs); | 979 SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs); |
| 947 | 980 |
| 948 // Return ScriptData object and relinquish ownership over it to the caller. | 981 // Return ScriptData object and relinquish ownership over it to the caller. |
| 949 ScriptData* GetScriptData(); | 982 ScriptData* GetScriptData(); |
| 950 | 983 |
| 951 Vector<const Reservation> Reservations() const; | 984 Vector<const Reservation> Reservations() const; |
| 952 Vector<const byte> Payload() const; | 985 Vector<const byte> Payload() const; |
| 953 | 986 |
| 954 int NumInternalizedStrings() const; | |
| 955 Vector<const uint32_t> CodeStubKeys() const; | 987 Vector<const uint32_t> CodeStubKeys() const; |
| 956 | 988 |
| 957 private: | 989 private: |
| 958 explicit SerializedCodeData(ScriptData* data); | 990 explicit SerializedCodeData(ScriptData* data); |
| 959 | 991 |
| 960 enum SanityCheckResult { | 992 enum SanityCheckResult { |
| 961 CHECK_SUCCESS = 0, | 993 CHECK_SUCCESS = 0, |
| 962 MAGIC_NUMBER_MISMATCH = 1, | 994 MAGIC_NUMBER_MISMATCH = 1, |
| 963 VERSION_MISMATCH = 2, | 995 VERSION_MISMATCH = 2, |
| 964 SOURCE_MISMATCH = 3, | 996 SOURCE_MISMATCH = 3, |
| 965 CPU_FEATURES_MISMATCH = 4, | 997 CPU_FEATURES_MISMATCH = 4, |
| 966 FLAGS_MISMATCH = 5, | 998 FLAGS_MISMATCH = 5, |
| 967 CHECKSUM_MISMATCH = 6 | 999 CHECKSUM_MISMATCH = 6 |
| 968 }; | 1000 }; |
| 969 | 1001 |
| 970 SanityCheckResult SanityCheck(Isolate* isolate, String* source) const; | 1002 SanityCheckResult SanityCheck(Isolate* isolate, String* source) const; |
| 971 | 1003 |
| 972 uint32_t SourceHash(String* source) const { return source->length(); } | 1004 uint32_t SourceHash(String* source) const { return source->length(); } |
| 973 | 1005 |
| 974 // The data header consists of uint32_t-sized entries: | 1006 // The data header consists of uint32_t-sized entries: |
| 975 // [ 0] magic number and external reference count | 1007 // [0] magic number and external reference count |
| 976 // [ 1] version hash | 1008 // [1] version hash |
| 977 // [ 2] source hash | 1009 // [2] source hash |
| 978 // [ 3] cpu features | 1010 // [3] cpu features |
| 979 // [ 4] flag hash | 1011 // [4] flag hash |
| 980 // [ 5] number of internalized strings | 1012 // [5] number of code stub keys |
| 981 // [ 6] number of code stub keys | 1013 // [6] number of reservation size entries |
| 982 // [ 7] number of reservation size entries | 1014 // [7] payload length |
| 983 // [ 8] payload length | 1015 // [8] payload checksum part 1 |
| 984 // [ 9] payload checksum part 1 | 1016 // [9] payload checksum part 2 |
| 985 // [10] payload checksum part 2 | |
| 986 // ... reservations | 1017 // ... reservations |
| 987 // ... code stub keys | 1018 // ... code stub keys |
| 988 // ... serialized payload | 1019 // ... serialized payload |
| 989 static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size; | 1020 static const int kVersionHashOffset = kMagicNumberOffset + kInt32Size; |
| 990 static const int kSourceHashOffset = kVersionHashOffset + kInt32Size; | 1021 static const int kSourceHashOffset = kVersionHashOffset + kInt32Size; |
| 991 static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size; | 1022 static const int kCpuFeaturesOffset = kSourceHashOffset + kInt32Size; |
| 992 static const int kFlagHashOffset = kCpuFeaturesOffset + kInt32Size; | 1023 static const int kFlagHashOffset = kCpuFeaturesOffset + kInt32Size; |
| 993 static const int kNumInternalizedStringsOffset = kFlagHashOffset + kInt32Size; | 1024 static const int kNumReservationsOffset = kFlagHashOffset + kInt32Size; |
| 994 static const int kNumReservationsOffset = | |
| 995 kNumInternalizedStringsOffset + kInt32Size; | |
| 996 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size; | 1025 static const int kNumCodeStubKeysOffset = kNumReservationsOffset + kInt32Size; |
| 997 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size; | 1026 static const int kPayloadLengthOffset = kNumCodeStubKeysOffset + kInt32Size; |
| 998 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size; | 1027 static const int kChecksum1Offset = kPayloadLengthOffset + kInt32Size; |
| 999 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size; | 1028 static const int kChecksum2Offset = kChecksum1Offset + kInt32Size; |
| 1000 static const int kHeaderSize = kChecksum2Offset + kInt32Size; | 1029 static const int kHeaderSize = kChecksum2Offset + kInt32Size; |
| 1001 }; | 1030 }; |
| 1002 } } // namespace v8::internal | 1031 } } // namespace v8::internal |
| 1003 | 1032 |
| 1004 #endif // V8_SNAPSHOT_SERIALIZE_H_ | 1033 #endif // V8_SNAPSHOT_SERIALIZE_H_ |
| OLD | NEW |