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/heap/heap-inl.h" | 9 #include "src/heap/heap-inl.h" |
9 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
10 #include "src/snapshot/natives.h" | 11 #include "src/snapshot/natives.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 Serializer::Serializer(Isolate* isolate) | 16 Serializer::Serializer(Isolate* isolate) |
16 : isolate_(isolate), | 17 : isolate_(isolate), |
17 external_reference_encoder_(isolate), | 18 external_reference_encoder_(isolate), |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 return Code::cast(HeapObject::FromAddress(&code_buffer_.first())); | 328 return Code::cast(HeapObject::FromAddress(&code_buffer_.first())); |
328 } | 329 } |
329 | 330 |
330 bool Serializer::HasNotExceededFirstPageOfEachSpace() { | 331 bool Serializer::HasNotExceededFirstPageOfEachSpace() { |
331 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { | 332 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { |
332 if (!completed_chunks_[i].is_empty()) return false; | 333 if (!completed_chunks_[i].is_empty()) return false; |
333 } | 334 } |
334 return true; | 335 return true; |
335 } | 336 } |
336 | 337 |
| 338 bool Serializer::ObjectSerializer::TryEncodeDeoptimizationEntry( |
| 339 HowToCode how_to_code, Address target, int skip) { |
| 340 for (int bailout_type = 0; bailout_type <= Deoptimizer::kLastBailoutType; |
| 341 ++bailout_type) { |
| 342 int id = Deoptimizer::GetDeoptimizationId( |
| 343 serializer_->isolate(), target, |
| 344 static_cast<Deoptimizer::BailoutType>(bailout_type)); |
| 345 if (id == Deoptimizer::kNotDeoptimizationEntry) continue; |
| 346 sink_->Put(how_to_code == kPlain ? kDeoptimizerEntryPlain |
| 347 : kDeoptimizerEntryFromCode, |
| 348 "DeoptimizationEntry"); |
| 349 sink_->PutInt(skip, "SkipB4DeoptimizationEntry"); |
| 350 sink_->Put(bailout_type, "BailoutType"); |
| 351 sink_->PutInt(id, "EntryId"); |
| 352 return true; |
| 353 } |
| 354 return false; |
| 355 } |
| 356 |
337 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, | 357 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
338 int size, Map* map) { | 358 int size, Map* map) { |
339 if (serializer_->code_address_map_) { | 359 if (serializer_->code_address_map_) { |
340 const char* code_name = | 360 const char* code_name = |
341 serializer_->code_address_map_->Lookup(object_->address()); | 361 serializer_->code_address_map_->Lookup(object_->address()); |
342 LOG(serializer_->isolate_, | 362 LOG(serializer_->isolate_, |
343 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 363 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
344 } | 364 } |
345 | 365 |
346 SerializerReference back_reference; | 366 SerializerReference back_reference; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 624 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
605 Object* object = rinfo->target_object(); | 625 Object* object = rinfo->target_object(); |
606 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, | 626 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, |
607 kStartOfObject, skip); | 627 kStartOfObject, skip); |
608 bytes_processed_so_far_ += rinfo->target_address_size(); | 628 bytes_processed_so_far_ += rinfo->target_address_size(); |
609 } | 629 } |
610 | 630 |
611 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { | 631 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { |
612 int skip = OutputRawData(reinterpret_cast<Address>(p), | 632 int skip = OutputRawData(reinterpret_cast<Address>(p), |
613 kCanReturnSkipInsteadOfSkipping); | 633 kCanReturnSkipInsteadOfSkipping); |
614 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); | |
615 sink_->PutInt(skip, "SkipB4ExternalRef"); | |
616 Address target = *p; | 634 Address target = *p; |
617 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 635 if (!TryEncodeDeoptimizationEntry(kPlain, target, skip)) { |
| 636 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
| 637 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 638 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 639 } |
618 bytes_processed_so_far_ += kPointerSize; | 640 bytes_processed_so_far_ += kPointerSize; |
619 } | 641 } |
620 | 642 |
621 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { | 643 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { |
622 int skip = OutputRawData(rinfo->target_address_address(), | 644 int skip = OutputRawData(rinfo->target_address_address(), |
623 kCanReturnSkipInsteadOfSkipping); | 645 kCanReturnSkipInsteadOfSkipping); |
624 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 646 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
625 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | |
626 sink_->PutInt(skip, "SkipB4ExternalRef"); | |
627 Address target = rinfo->target_external_reference(); | 647 Address target = rinfo->target_external_reference(); |
628 DCHECK_NOT_NULL(target); // Code does not reference null. | 648 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
629 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 649 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
| 650 "ExternalRef"); |
| 651 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 652 DCHECK_NOT_NULL(target); // Code does not reference null. |
| 653 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 654 } |
630 bytes_processed_so_far_ += rinfo->target_address_size(); | 655 bytes_processed_so_far_ += rinfo->target_address_size(); |
631 } | 656 } |
632 | 657 |
633 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { | 658 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { |
634 // We can only reference to internal references of code that has been output. | 659 // We can only reference to internal references of code that has been output. |
635 DCHECK(object_->IsCode() && code_has_been_output_); | 660 DCHECK(object_->IsCode() && code_has_been_output_); |
636 // We do not use skip from last patched pc to find the pc to patch, since | 661 // We do not use skip from last patched pc to find the pc to patch, since |
637 // target_address_address may not return addresses in ascending order when | 662 // target_address_address may not return addresses in ascending order when |
638 // used for internal references. External references may be stored at the | 663 // used for internal references. External references may be stored at the |
639 // end of the code in the constant pool, whereas internal references are | 664 // end of the code in the constant pool, whereas internal references are |
(...skipping 11 matching lines...) Expand all Loading... |
651 : kInternalReferenceEncoded, | 676 : kInternalReferenceEncoded, |
652 "InternalRef"); | 677 "InternalRef"); |
653 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); | 678 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); |
654 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); | 679 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); |
655 } | 680 } |
656 | 681 |
657 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 682 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { |
658 int skip = OutputRawData(rinfo->target_address_address(), | 683 int skip = OutputRawData(rinfo->target_address_address(), |
659 kCanReturnSkipInsteadOfSkipping); | 684 kCanReturnSkipInsteadOfSkipping); |
660 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 685 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
661 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | |
662 sink_->PutInt(skip, "SkipB4ExternalRef"); | |
663 Address target = rinfo->target_address(); | 686 Address target = rinfo->target_address(); |
664 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 687 if (!TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { |
| 688 sink_->Put(kExternalReference + how_to_code + kStartOfObject, |
| 689 "ExternalRef"); |
| 690 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 691 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 692 } |
665 bytes_processed_so_far_ += rinfo->target_address_size(); | 693 bytes_processed_so_far_ += rinfo->target_address_size(); |
666 } | 694 } |
667 | 695 |
668 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { | 696 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { |
669 int skip = OutputRawData(rinfo->target_address_address(), | 697 int skip = OutputRawData(rinfo->target_address_address(), |
670 kCanReturnSkipInsteadOfSkipping); | 698 kCanReturnSkipInsteadOfSkipping); |
671 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 699 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
672 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); | 700 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); |
673 bytes_processed_so_far_ += rinfo->target_address_size(); | 701 bytes_processed_so_far_ += rinfo->target_address_size(); |
674 } | 702 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 826 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
799 sink_->Put(kSkip, "Skip"); | 827 sink_->Put(kSkip, "Skip"); |
800 sink_->PutInt(to_skip, "SkipDistance"); | 828 sink_->PutInt(to_skip, "SkipDistance"); |
801 to_skip = 0; | 829 to_skip = 0; |
802 } | 830 } |
803 return to_skip; | 831 return to_skip; |
804 } | 832 } |
805 | 833 |
806 } // namespace internal | 834 } // namespace internal |
807 } // namespace v8 | 835 } // namespace v8 |
OLD | NEW |