OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/snapshot/serializer.h" | 5 #include "src/snapshot/serializer.h" |
6 | 6 |
7 #include "src/assembler-inl.h" | 7 #include "src/assembler-inl.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/heap/heap-inl.h" | 9 #include "src/heap/heap-inl.h" |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 sink_->Put(kNewObject + back_reference.space(), "deferred object"); | 626 sink_->Put(kNewObject + back_reference.space(), "deferred object"); |
627 serializer_->PutBackReference(object_, back_reference); | 627 serializer_->PutBackReference(object_, back_reference); |
628 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size"); | 628 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size"); |
629 | 629 |
630 UnlinkWeakNextScope unlink_weak_next(object_); | 630 UnlinkWeakNextScope unlink_weak_next(object_); |
631 | 631 |
632 object_->IterateBody(map->instance_type(), size, this); | 632 object_->IterateBody(map->instance_type(), size, this); |
633 OutputRawData(object_->address() + size); | 633 OutputRawData(object_->address() + size); |
634 } | 634 } |
635 | 635 |
636 void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) { | 636 void Serializer::ObjectSerializer::VisitPointers(HeapObject* host, |
| 637 Object** start, Object** end) { |
637 Object** current = start; | 638 Object** current = start; |
638 while (current < end) { | 639 while (current < end) { |
639 while (current < end && (*current)->IsSmi()) current++; | 640 while (current < end && (*current)->IsSmi()) current++; |
640 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); | 641 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
641 | 642 |
642 while (current < end && !(*current)->IsSmi()) { | 643 while (current < end && !(*current)->IsSmi()) { |
643 HeapObject* current_contents = HeapObject::cast(*current); | 644 HeapObject* current_contents = HeapObject::cast(*current); |
644 int root_index = serializer_->root_index_map()->Lookup(current_contents); | 645 int root_index = serializer_->root_index_map()->Lookup(current_contents); |
645 // Repeats are not subject to the write barrier so we can only use | 646 // Repeats are not subject to the write barrier so we can only use |
646 // immortal immovable root members. They are never in new space. | 647 // immortal immovable root members. They are never in new space. |
(...skipping 17 matching lines...) Expand all Loading... |
664 } else { | 665 } else { |
665 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject, | 666 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject, |
666 0); | 667 0); |
667 bytes_processed_so_far_ += kPointerSize; | 668 bytes_processed_so_far_ += kPointerSize; |
668 current++; | 669 current++; |
669 } | 670 } |
670 } | 671 } |
671 } | 672 } |
672 } | 673 } |
673 | 674 |
674 void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) { | 675 void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code* host, |
| 676 RelocInfo* rinfo) { |
675 int skip = OutputRawData(rinfo->target_address_address(), | 677 int skip = OutputRawData(rinfo->target_address_address(), |
676 kCanReturnSkipInsteadOfSkipping); | 678 kCanReturnSkipInsteadOfSkipping); |
677 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 679 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
678 Object* object = rinfo->target_object(); | 680 Object* object = rinfo->target_object(); |
679 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, | 681 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, |
680 kStartOfObject, skip); | 682 kStartOfObject, skip); |
681 bytes_processed_so_far_ += rinfo->target_address_size(); | 683 bytes_processed_so_far_ += rinfo->target_address_size(); |
682 } | 684 } |
683 | 685 |
684 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { | 686 void Serializer::ObjectSerializer::VisitExternalReference(Foreign* host, |
| 687 Address* p) { |
685 int skip = OutputRawData(reinterpret_cast<Address>(p), | 688 int skip = OutputRawData(reinterpret_cast<Address>(p), |
686 kCanReturnSkipInsteadOfSkipping); | 689 kCanReturnSkipInsteadOfSkipping); |
687 Address target = *p; | 690 Address target = *p; |
688 if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) { | 691 if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) { |
689 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); | 692 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
690 sink_->PutInt(skip, "SkipB4ExternalRef"); | 693 sink_->PutInt(skip, "SkipB4ExternalRef"); |
691 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 694 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
692 } | 695 } |
693 bytes_processed_so_far_ += kPointerSize; | 696 bytes_processed_so_far_ += kPointerSize; |
694 } | 697 } |
695 | 698 |
696 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { | 699 void Serializer::ObjectSerializer::VisitExternalReference(Code* host, |
| 700 RelocInfo* rinfo) { |
697 int skip = OutputRawData(rinfo->target_address_address(), | 701 int skip = OutputRawData(rinfo->target_address_address(), |
698 kCanReturnSkipInsteadOfSkipping); | 702 kCanReturnSkipInsteadOfSkipping); |
699 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 703 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
700 Address target = rinfo->target_external_reference(); | 704 Address target = rinfo->target_external_reference(); |
701 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | 705 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
702 sink_->Put(kExternalReference + how_to_code + kStartOfObject, | 706 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
703 "ExternalRef"); | 707 "ExternalRef"); |
704 sink_->PutInt(skip, "SkipB4ExternalRef"); | 708 sink_->PutInt(skip, "SkipB4ExternalRef"); |
705 DCHECK_NOT_NULL(target); // Code does not reference null. | 709 DCHECK_NOT_NULL(target); // Code does not reference null. |
706 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 710 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
707 } | 711 } |
708 bytes_processed_so_far_ += rinfo->target_address_size(); | 712 bytes_processed_so_far_ += rinfo->target_address_size(); |
709 } | 713 } |
710 | 714 |
711 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { | 715 void Serializer::ObjectSerializer::VisitInternalReference(Code* host, |
| 716 RelocInfo* rinfo) { |
712 // We can only reference to internal references of code that has been output. | 717 // We can only reference to internal references of code that has been output. |
713 DCHECK(object_->IsCode() && code_has_been_output_); | 718 DCHECK(object_->IsCode() && code_has_been_output_); |
714 // We do not use skip from last patched pc to find the pc to patch, since | 719 // We do not use skip from last patched pc to find the pc to patch, since |
715 // target_address_address may not return addresses in ascending order when | 720 // target_address_address may not return addresses in ascending order when |
716 // used for internal references. External references may be stored at the | 721 // used for internal references. External references may be stored at the |
717 // end of the code in the constant pool, whereas internal references are | 722 // end of the code in the constant pool, whereas internal references are |
718 // inline. That would cause the skip to be negative. Instead, we store the | 723 // inline. That would cause the skip to be negative. Instead, we store the |
719 // offset from code entry. | 724 // offset from code entry. |
720 Address entry = Code::cast(object_)->entry(); | 725 Address entry = Code::cast(object_)->entry(); |
721 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry; | 726 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry; |
722 intptr_t target_offset = rinfo->target_internal_reference() - entry; | 727 intptr_t target_offset = rinfo->target_internal_reference() - entry; |
723 DCHECK(0 <= pc_offset && | 728 DCHECK(0 <= pc_offset && |
724 pc_offset <= Code::cast(object_)->instruction_size()); | 729 pc_offset <= Code::cast(object_)->instruction_size()); |
725 DCHECK(0 <= target_offset && | 730 DCHECK(0 <= target_offset && |
726 target_offset <= Code::cast(object_)->instruction_size()); | 731 target_offset <= Code::cast(object_)->instruction_size()); |
727 sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE | 732 sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE |
728 ? kInternalReference | 733 ? kInternalReference |
729 : kInternalReferenceEncoded, | 734 : kInternalReferenceEncoded, |
730 "InternalRef"); | 735 "InternalRef"); |
731 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); | 736 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); |
732 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); | 737 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); |
733 } | 738 } |
734 | 739 |
735 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 740 void Serializer::ObjectSerializer::VisitRuntimeEntry(Code* host, |
| 741 RelocInfo* rinfo) { |
736 int skip = OutputRawData(rinfo->target_address_address(), | 742 int skip = OutputRawData(rinfo->target_address_address(), |
737 kCanReturnSkipInsteadOfSkipping); | 743 kCanReturnSkipInsteadOfSkipping); |
738 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 744 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
739 Address target = rinfo->target_address(); | 745 Address target = rinfo->target_address(); |
740 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | 746 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
741 sink_->Put(kExternalReference + how_to_code + kStartOfObject, | 747 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
742 "ExternalRef"); | 748 "ExternalRef"); |
743 sink_->PutInt(skip, "SkipB4ExternalRef"); | 749 sink_->PutInt(skip, "SkipB4ExternalRef"); |
744 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 750 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
745 } | 751 } |
746 bytes_processed_so_far_ += rinfo->target_address_size(); | 752 bytes_processed_so_far_ += rinfo->target_address_size(); |
747 } | 753 } |
748 | 754 |
749 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { | 755 void Serializer::ObjectSerializer::VisitCodeTarget(Code* host, |
| 756 RelocInfo* rinfo) { |
750 int skip = OutputRawData(rinfo->target_address_address(), | 757 int skip = OutputRawData(rinfo->target_address_address(), |
751 kCanReturnSkipInsteadOfSkipping); | 758 kCanReturnSkipInsteadOfSkipping); |
752 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 759 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
753 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); | 760 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); |
754 bytes_processed_so_far_ += rinfo->target_address_size(); | 761 bytes_processed_so_far_ += rinfo->target_address_size(); |
755 } | 762 } |
756 | 763 |
757 void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) { | 764 void Serializer::ObjectSerializer::VisitCodeEntry(JSFunction* host, |
| 765 Address entry_address) { |
758 int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping); | 766 int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping); |
759 Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); | 767 Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); |
760 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); | 768 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); |
761 bytes_processed_so_far_ += kPointerSize; | 769 bytes_processed_so_far_ += kPointerSize; |
762 } | 770 } |
763 | 771 |
764 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { | 772 void Serializer::ObjectSerializer::VisitCell(Code* host, RelocInfo* rinfo) { |
765 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); | 773 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); |
766 Cell* object = Cell::cast(rinfo->target_cell()); | 774 Cell* object = Cell::cast(rinfo->target_cell()); |
767 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); | 775 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); |
768 bytes_processed_so_far_ += kPointerSize; | 776 bytes_processed_so_far_ += kPointerSize; |
769 } | 777 } |
770 | 778 |
771 Address Serializer::ObjectSerializer::PrepareCode() { | 779 Address Serializer::ObjectSerializer::PrepareCode() { |
772 Code* code = Code::cast(object_); | 780 Code* code = Code::cast(object_); |
773 if (FLAG_predictable) { | 781 if (FLAG_predictable) { |
774 // To make snapshots reproducible, we make a copy of the code object | 782 // To make snapshots reproducible, we make a copy of the code object |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 841 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
834 sink_->Put(kSkip, "Skip"); | 842 sink_->Put(kSkip, "Skip"); |
835 sink_->PutInt(to_skip, "SkipDistance"); | 843 sink_->PutInt(to_skip, "SkipDistance"); |
836 to_skip = 0; | 844 to_skip = 0; |
837 } | 845 } |
838 return to_skip; | 846 return to_skip; |
839 } | 847 } |
840 | 848 |
841 } // namespace internal | 849 } // namespace internal |
842 } // namespace v8 | 850 } // namespace v8 |
OLD | NEW |