| 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 sink_->Put(kNewObject + back_reference.space(), "deferred object"); | 591 sink_->Put(kNewObject + back_reference.space(), "deferred object"); |
| 592 serializer_->PutBackReference(object_, back_reference); | 592 serializer_->PutBackReference(object_, back_reference); |
| 593 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size"); | 593 sink_->PutInt(size >> kPointerSizeLog2, "deferred object size"); |
| 594 | 594 |
| 595 UnlinkWeakNextScope unlink_weak_next(object_); | 595 UnlinkWeakNextScope unlink_weak_next(object_); |
| 596 | 596 |
| 597 object_->IterateBody(map->instance_type(), size, this); | 597 object_->IterateBody(map->instance_type(), size, this); |
| 598 OutputRawData(object_->address() + size); | 598 OutputRawData(object_->address() + size); |
| 599 } | 599 } |
| 600 | 600 |
| 601 void Serializer::ObjectSerializer::VisitPointers(Object** start, Object** end) { | 601 void Serializer::ObjectSerializer::VisitPointers(HeapObject* host, |
| 602 Object** start, Object** end) { |
| 602 Object** current = start; | 603 Object** current = start; |
| 603 while (current < end) { | 604 while (current < end) { |
| 604 while (current < end && (*current)->IsSmi()) current++; | 605 while (current < end && (*current)->IsSmi()) current++; |
| 605 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); | 606 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
| 606 | 607 |
| 607 while (current < end && !(*current)->IsSmi()) { | 608 while (current < end && !(*current)->IsSmi()) { |
| 608 HeapObject* current_contents = HeapObject::cast(*current); | 609 HeapObject* current_contents = HeapObject::cast(*current); |
| 609 int root_index = serializer_->root_index_map()->Lookup(current_contents); | 610 int root_index = serializer_->root_index_map()->Lookup(current_contents); |
| 610 // Repeats are not subject to the write barrier so we can only use | 611 // Repeats are not subject to the write barrier so we can only use |
| 611 // immortal immovable root members. They are never in new space. | 612 // immortal immovable root members. They are never in new space. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 629 } else { | 630 } else { |
| 630 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject, | 631 serializer_->SerializeObject(current_contents, kPlain, kStartOfObject, |
| 631 0); | 632 0); |
| 632 bytes_processed_so_far_ += kPointerSize; | 633 bytes_processed_so_far_ += kPointerSize; |
| 633 current++; | 634 current++; |
| 634 } | 635 } |
| 635 } | 636 } |
| 636 } | 637 } |
| 637 } | 638 } |
| 638 | 639 |
| 639 void Serializer::ObjectSerializer::VisitEmbeddedPointer(RelocInfo* rinfo) { | 640 void Serializer::ObjectSerializer::VisitEmbeddedPointer(Code* host, |
| 641 RelocInfo* rinfo) { |
| 640 int skip = OutputRawData(rinfo->target_address_address(), | 642 int skip = OutputRawData(rinfo->target_address_address(), |
| 641 kCanReturnSkipInsteadOfSkipping); | 643 kCanReturnSkipInsteadOfSkipping); |
| 642 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 644 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 643 Object* object = rinfo->target_object(); | 645 Object* object = rinfo->target_object(); |
| 644 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, | 646 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, |
| 645 kStartOfObject, skip); | 647 kStartOfObject, skip); |
| 646 bytes_processed_so_far_ += rinfo->target_address_size(); | 648 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 647 } | 649 } |
| 648 | 650 |
| 649 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { | 651 void Serializer::ObjectSerializer::VisitExternalReference(Foreign* host, |
| 652 Address* p) { |
| 650 int skip = OutputRawData(reinterpret_cast<Address>(p), | 653 int skip = OutputRawData(reinterpret_cast<Address>(p), |
| 651 kCanReturnSkipInsteadOfSkipping); | 654 kCanReturnSkipInsteadOfSkipping); |
| 652 Address target = *p; | 655 Address target = *p; |
| 653 if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) { | 656 if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) { |
| 654 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); | 657 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
| 655 sink_->PutInt(skip, "SkipB4ExternalRef"); | 658 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 656 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 659 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 657 } | 660 } |
| 658 bytes_processed_so_far_ += kPointerSize; | 661 bytes_processed_so_far_ += kPointerSize; |
| 659 } | 662 } |
| 660 | 663 |
| 661 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { | 664 void Serializer::ObjectSerializer::VisitExternalReference(Code* host, |
| 665 RelocInfo* rinfo) { |
| 662 int skip = OutputRawData(rinfo->target_address_address(), | 666 int skip = OutputRawData(rinfo->target_address_address(), |
| 663 kCanReturnSkipInsteadOfSkipping); | 667 kCanReturnSkipInsteadOfSkipping); |
| 664 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 668 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 665 Address target = rinfo->target_external_reference(); | 669 Address target = rinfo->target_external_reference(); |
| 666 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | 670 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
| 667 sink_->Put(kExternalReference + how_to_code + kStartOfObject, | 671 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
| 668 "ExternalRef"); | 672 "ExternalRef"); |
| 669 sink_->PutInt(skip, "SkipB4ExternalRef"); | 673 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 670 DCHECK_NOT_NULL(target); // Code does not reference null. | 674 DCHECK_NOT_NULL(target); // Code does not reference null. |
| 671 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 675 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 672 } | 676 } |
| 673 bytes_processed_so_far_ += rinfo->target_address_size(); | 677 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 674 } | 678 } |
| 675 | 679 |
| 676 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { | 680 void Serializer::ObjectSerializer::VisitInternalReference(Code* host, |
| 681 RelocInfo* rinfo) { |
| 677 // We can only reference to internal references of code that has been output. | 682 // We can only reference to internal references of code that has been output. |
| 678 DCHECK(object_->IsCode() && code_has_been_output_); | 683 DCHECK(object_->IsCode() && code_has_been_output_); |
| 679 // We do not use skip from last patched pc to find the pc to patch, since | 684 // We do not use skip from last patched pc to find the pc to patch, since |
| 680 // target_address_address may not return addresses in ascending order when | 685 // target_address_address may not return addresses in ascending order when |
| 681 // used for internal references. External references may be stored at the | 686 // used for internal references. External references may be stored at the |
| 682 // end of the code in the constant pool, whereas internal references are | 687 // end of the code in the constant pool, whereas internal references are |
| 683 // inline. That would cause the skip to be negative. Instead, we store the | 688 // inline. That would cause the skip to be negative. Instead, we store the |
| 684 // offset from code entry. | 689 // offset from code entry. |
| 685 Address entry = Code::cast(object_)->entry(); | 690 Address entry = Code::cast(object_)->entry(); |
| 686 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry; | 691 intptr_t pc_offset = rinfo->target_internal_reference_address() - entry; |
| 687 intptr_t target_offset = rinfo->target_internal_reference() - entry; | 692 intptr_t target_offset = rinfo->target_internal_reference() - entry; |
| 688 DCHECK(0 <= pc_offset && | 693 DCHECK(0 <= pc_offset && |
| 689 pc_offset <= Code::cast(object_)->instruction_size()); | 694 pc_offset <= Code::cast(object_)->instruction_size()); |
| 690 DCHECK(0 <= target_offset && | 695 DCHECK(0 <= target_offset && |
| 691 target_offset <= Code::cast(object_)->instruction_size()); | 696 target_offset <= Code::cast(object_)->instruction_size()); |
| 692 sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE | 697 sink_->Put(rinfo->rmode() == RelocInfo::INTERNAL_REFERENCE |
| 693 ? kInternalReference | 698 ? kInternalReference |
| 694 : kInternalReferenceEncoded, | 699 : kInternalReferenceEncoded, |
| 695 "InternalRef"); | 700 "InternalRef"); |
| 696 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); | 701 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); |
| 697 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); | 702 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); |
| 698 } | 703 } |
| 699 | 704 |
| 700 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 705 void Serializer::ObjectSerializer::VisitRuntimeEntry(Code* host, |
| 706 RelocInfo* rinfo) { |
| 701 int skip = OutputRawData(rinfo->target_address_address(), | 707 int skip = OutputRawData(rinfo->target_address_address(), |
| 702 kCanReturnSkipInsteadOfSkipping); | 708 kCanReturnSkipInsteadOfSkipping); |
| 703 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 709 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 704 Address target = rinfo->target_address(); | 710 Address target = rinfo->target_address(); |
| 705 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | 711 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
| 706 sink_->Put(kExternalReference + how_to_code + kStartOfObject, | 712 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
| 707 "ExternalRef"); | 713 "ExternalRef"); |
| 708 sink_->PutInt(skip, "SkipB4ExternalRef"); | 714 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 709 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 715 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 710 } | 716 } |
| 711 bytes_processed_so_far_ += rinfo->target_address_size(); | 717 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 712 } | 718 } |
| 713 | 719 |
| 714 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { | 720 void Serializer::ObjectSerializer::VisitCodeTarget(Code* host, |
| 721 RelocInfo* rinfo) { |
| 715 int skip = OutputRawData(rinfo->target_address_address(), | 722 int skip = OutputRawData(rinfo->target_address_address(), |
| 716 kCanReturnSkipInsteadOfSkipping); | 723 kCanReturnSkipInsteadOfSkipping); |
| 717 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 724 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 718 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); | 725 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); |
| 719 bytes_processed_so_far_ += rinfo->target_address_size(); | 726 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 720 } | 727 } |
| 721 | 728 |
| 722 void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) { | 729 void Serializer::ObjectSerializer::VisitCodeEntry(JSFunction* host, |
| 730 Address entry_address) { |
| 723 int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping); | 731 int skip = OutputRawData(entry_address, kCanReturnSkipInsteadOfSkipping); |
| 724 Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); | 732 Code* object = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); |
| 725 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); | 733 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); |
| 726 bytes_processed_so_far_ += kPointerSize; | 734 bytes_processed_so_far_ += kPointerSize; |
| 727 } | 735 } |
| 728 | 736 |
| 729 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { | 737 void Serializer::ObjectSerializer::VisitCellPointer(Code* host, |
| 738 RelocInfo* rinfo) { |
| 730 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); | 739 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); |
| 731 Cell* object = Cell::cast(rinfo->target_cell()); | 740 Cell* object = Cell::cast(rinfo->target_cell()); |
| 732 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); | 741 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); |
| 733 bytes_processed_so_far_ += kPointerSize; | 742 bytes_processed_so_far_ += kPointerSize; |
| 734 } | 743 } |
| 735 | 744 |
| 736 Address Serializer::ObjectSerializer::PrepareCode() { | 745 Address Serializer::ObjectSerializer::PrepareCode() { |
| 737 Code* code = Code::cast(object_); | 746 Code* code = Code::cast(object_); |
| 738 if (FLAG_predictable) { | 747 if (FLAG_predictable) { |
| 739 // To make snapshots reproducible, we make a copy of the code object | 748 // 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... |
| 798 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 807 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
| 799 sink_->Put(kSkip, "Skip"); | 808 sink_->Put(kSkip, "Skip"); |
| 800 sink_->PutInt(to_skip, "SkipDistance"); | 809 sink_->PutInt(to_skip, "SkipDistance"); |
| 801 to_skip = 0; | 810 to_skip = 0; |
| 802 } | 811 } |
| 803 return to_skip; | 812 return to_skip; |
| 804 } | 813 } |
| 805 | 814 |
| 806 } // namespace internal | 815 } // namespace internal |
| 807 } // namespace v8 | 816 } // namespace v8 |
| OLD | NEW |