| 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 |