Chromium Code Reviews| 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 if (how_to_code == kPlain) | |
| 347 sink_->Put(kDeoptimizerEntryPlain, "DeoptimizationEntry"); | |
|
Yang
2017/04/04 07:59:21
please use brackets with if-else. You could also u
Slava Chigrin
2017/04/04 10:12:24
Done.
| |
| 348 else | |
| 349 sink_->Put(kDeoptimizerEntryFromCode, "DeoptimizationEntry"); | |
| 350 sink_->PutInt(skip, "SkipB4DeoptimizationEntry"); | |
| 351 sink_->Put(bailout_type, "BailoutType"); | |
| 352 sink_->PutInt(id, "EntryId"); | |
| 353 return true; | |
| 354 } | |
| 355 return false; | |
| 356 } | |
| 357 | |
| 337 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, | 358 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
| 338 int size, Map* map) { | 359 int size, Map* map) { |
| 339 if (serializer_->code_address_map_) { | 360 if (serializer_->code_address_map_) { |
| 340 const char* code_name = | 361 const char* code_name = |
| 341 serializer_->code_address_map_->Lookup(object_->address()); | 362 serializer_->code_address_map_->Lookup(object_->address()); |
| 342 LOG(serializer_->isolate_, | 363 LOG(serializer_->isolate_, |
| 343 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 364 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
| 344 } | 365 } |
| 345 | 366 |
| 346 SerializerReference back_reference; | 367 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; | 625 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 605 Object* object = rinfo->target_object(); | 626 Object* object = rinfo->target_object(); |
| 606 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, | 627 serializer_->SerializeObject(HeapObject::cast(object), how_to_code, |
| 607 kStartOfObject, skip); | 628 kStartOfObject, skip); |
| 608 bytes_processed_so_far_ += rinfo->target_address_size(); | 629 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 609 } | 630 } |
| 610 | 631 |
| 611 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { | 632 void Serializer::ObjectSerializer::VisitExternalReference(Address* p) { |
| 612 int skip = OutputRawData(reinterpret_cast<Address>(p), | 633 int skip = OutputRawData(reinterpret_cast<Address>(p), |
| 613 kCanReturnSkipInsteadOfSkipping); | 634 kCanReturnSkipInsteadOfSkipping); |
| 635 Address target = *p; | |
| 636 if (TryEncodeDeoptimizationEntry(kPlain, target, skip)) { | |
|
Yang
2017/04/04 07:59:21
I'd prefer something like
if (!TryEncode...) {
..
Slava Chigrin
2017/04/04 10:12:24
Done.
| |
| 637 bytes_processed_so_far_ += kPointerSize; | |
| 638 return; | |
| 639 } | |
| 614 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); | 640 sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
| 615 sink_->PutInt(skip, "SkipB4ExternalRef"); | 641 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 616 Address target = *p; | |
| 617 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 642 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 618 bytes_processed_so_far_ += kPointerSize; | 643 bytes_processed_so_far_ += kPointerSize; |
| 619 } | 644 } |
| 620 | 645 |
| 621 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { | 646 void Serializer::ObjectSerializer::VisitExternalReference(RelocInfo* rinfo) { |
| 622 int skip = OutputRawData(rinfo->target_address_address(), | 647 int skip = OutputRawData(rinfo->target_address_address(), |
| 623 kCanReturnSkipInsteadOfSkipping); | 648 kCanReturnSkipInsteadOfSkipping); |
| 624 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 649 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 650 Address target = rinfo->target_external_reference(); | |
| 651 if (TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | |
| 652 bytes_processed_so_far_ += rinfo->target_address_size(); | |
|
Yang
2017/04/04 07:59:21
same here
Slava Chigrin
2017/04/04 10:12:24
Done.
| |
| 653 return; | |
| 654 } | |
| 625 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 655 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
| 626 sink_->PutInt(skip, "SkipB4ExternalRef"); | 656 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 627 Address target = rinfo->target_external_reference(); | |
| 628 DCHECK_NOT_NULL(target); // Code does not reference null. | 657 DCHECK_NOT_NULL(target); // Code does not reference null. |
| 629 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 658 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 630 bytes_processed_so_far_ += rinfo->target_address_size(); | 659 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 631 } | 660 } |
| 632 | 661 |
| 633 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { | 662 void Serializer::ObjectSerializer::VisitInternalReference(RelocInfo* rinfo) { |
| 634 // We can only reference to internal references of code that has been output. | 663 // We can only reference to internal references of code that has been output. |
| 635 DCHECK(object_->IsCode() && code_has_been_output_); | 664 DCHECK(object_->IsCode() && code_has_been_output_); |
| 636 // We do not use skip from last patched pc to find the pc to patch, since | 665 // 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 | 666 // target_address_address may not return addresses in ascending order when |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 651 : kInternalReferenceEncoded, | 680 : kInternalReferenceEncoded, |
| 652 "InternalRef"); | 681 "InternalRef"); |
| 653 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); | 682 sink_->PutInt(static_cast<uintptr_t>(pc_offset), "internal ref address"); |
| 654 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); | 683 sink_->PutInt(static_cast<uintptr_t>(target_offset), "internal ref value"); |
| 655 } | 684 } |
| 656 | 685 |
| 657 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { | 686 void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) { |
| 658 int skip = OutputRawData(rinfo->target_address_address(), | 687 int skip = OutputRawData(rinfo->target_address_address(), |
| 659 kCanReturnSkipInsteadOfSkipping); | 688 kCanReturnSkipInsteadOfSkipping); |
| 660 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; | 689 HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain; |
| 690 Address target = rinfo->target_address(); | |
| 691 if (TryEncodeDeoptimizationEntry(how_to_code, target, skip)) { | |
| 692 bytes_processed_so_far_ += rinfo->target_address_size(); | |
|
Yang
2017/04/04 07:59:21
same here.
Slava Chigrin
2017/04/04 10:12:24
Done.
| |
| 693 return; | |
| 694 } | |
| 661 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); | 695 sink_->Put(kExternalReference + how_to_code + kStartOfObject, "ExternalRef"); |
| 662 sink_->PutInt(skip, "SkipB4ExternalRef"); | 696 sink_->PutInt(skip, "SkipB4ExternalRef"); |
| 663 Address target = rinfo->target_address(); | |
| 664 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); | 697 sink_->PutInt(serializer_->EncodeExternalReference(target), "reference id"); |
| 665 bytes_processed_so_far_ += rinfo->target_address_size(); | 698 bytes_processed_so_far_ += rinfo->target_address_size(); |
| 666 } | 699 } |
| 667 | 700 |
| 668 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { | 701 void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) { |
| 669 int skip = OutputRawData(rinfo->target_address_address(), | 702 int skip = OutputRawData(rinfo->target_address_address(), |
| 670 kCanReturnSkipInsteadOfSkipping); | 703 kCanReturnSkipInsteadOfSkipping); |
| 671 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 704 Code* object = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 672 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); | 705 serializer_->SerializeObject(object, kFromCode, kInnerPointer, skip); |
| 673 bytes_processed_so_far_ += rinfo->target_address_size(); | 706 bytes_processed_so_far_ += rinfo->target_address_size(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 798 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 831 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
| 799 sink_->Put(kSkip, "Skip"); | 832 sink_->Put(kSkip, "Skip"); |
| 800 sink_->PutInt(to_skip, "SkipDistance"); | 833 sink_->PutInt(to_skip, "SkipDistance"); |
| 801 to_skip = 0; | 834 to_skip = 0; |
| 802 } | 835 } |
| 803 return to_skip; | 836 return to_skip; |
| 804 } | 837 } |
| 805 | 838 |
| 806 } // namespace internal | 839 } // namespace internal |
| 807 } // namespace v8 | 840 } // namespace v8 |
| OLD | NEW |