| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 37 namespace internal { | 37 namespace internal { | 
| 38 | 38 | 
| 39 | 39 | 
| 40 void RelocInfo::apply(intptr_t delta) { | 40 void RelocInfo::apply(intptr_t delta) { | 
| 41   UNIMPLEMENTED(); | 41   UNIMPLEMENTED(); | 
| 42 } | 42 } | 
| 43 | 43 | 
| 44 | 44 | 
| 45 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { | 45 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { | 
| 46   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 46   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 
| 47   Assembler::set_target_address_at(pc_, target); | 47   Assembler::set_target_address_at(pc_, host_, target); | 
| 48   if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { | 48   if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { | 
| 49     Object* target_code = Code::GetCodeFromTargetAddress(target); | 49     Object* target_code = Code::GetCodeFromTargetAddress(target); | 
| 50     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 50     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 
| 51         host(), this, HeapObject::cast(target_code)); | 51         host(), this, HeapObject::cast(target_code)); | 
| 52   } | 52   } | 
| 53 } | 53 } | 
| 54 | 54 | 
| 55 | 55 | 
| 56 inline unsigned CPURegister::code() const { | 56 inline unsigned CPURegister::code() const { | 
| 57   ASSERT(IsValid()); | 57   ASSERT(IsValid()); | 
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 551 | 551 | 
| 552 | 552 | 
| 553 Address Assembler::target_pointer_address_at(Address pc) { | 553 Address Assembler::target_pointer_address_at(Address pc) { | 
| 554   Instruction* instr = reinterpret_cast<Instruction*>(pc); | 554   Instruction* instr = reinterpret_cast<Instruction*>(pc); | 
| 555   ASSERT(instr->IsLdrLiteralX()); | 555   ASSERT(instr->IsLdrLiteralX()); | 
| 556   return reinterpret_cast<Address>(instr->ImmPCOffsetTarget()); | 556   return reinterpret_cast<Address>(instr->ImmPCOffsetTarget()); | 
| 557 } | 557 } | 
| 558 | 558 | 
| 559 | 559 | 
| 560 // Read/Modify the code target address in the branch/call instruction at pc. | 560 // Read/Modify the code target address in the branch/call instruction at pc. | 
| 561 Address Assembler::target_address_at(Address pc) { | 561 Address Assembler::target_address_at(Address pc, | 
|  | 562                                      ConstantPoolArray* constant_pool) { | 
| 562   return Memory::Address_at(target_pointer_address_at(pc)); | 563   return Memory::Address_at(target_pointer_address_at(pc)); | 
| 563 } | 564 } | 
| 564 | 565 | 
| 565 | 566 | 
|  | 567 Address Assembler::target_address_at(Address pc, Code* code) { | 
|  | 568   ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; | 
|  | 569   return target_address_at(pc, constant_pool); | 
|  | 570 } | 
|  | 571 | 
|  | 572 | 
| 566 Address Assembler::target_address_from_return_address(Address pc) { | 573 Address Assembler::target_address_from_return_address(Address pc) { | 
| 567   // Returns the address of the call target from the return address that will | 574   // Returns the address of the call target from the return address that will | 
| 568   // be returned to after a call. | 575   // be returned to after a call. | 
| 569   // Call sequence on A64 is: | 576   // Call sequence on A64 is: | 
| 570   //  ldr ip0, #... @ load from literal pool | 577   //  ldr ip0, #... @ load from literal pool | 
| 571   //  blr ip0 | 578   //  blr ip0 | 
| 572   Address candidate = pc - 2 * kInstructionSize; | 579   Address candidate = pc - 2 * kInstructionSize; | 
| 573   Instruction* instr = reinterpret_cast<Instruction*>(candidate); | 580   Instruction* instr = reinterpret_cast<Instruction*>(candidate); | 
| 574   USE(instr); | 581   USE(instr); | 
| 575   ASSERT(instr->IsLdrLiteralX()); | 582   ASSERT(instr->IsLdrLiteralX()); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 609   } else { | 616   } else { | 
| 610     // Verify the instruction sequence. | 617     // Verify the instruction sequence. | 
| 611     ASSERT(instr->IsLdrLiteralX()); | 618     ASSERT(instr->IsLdrLiteralX()); | 
| 612     ASSERT(instr->following(1)->IsBranchAndLinkToRegister()); | 619     ASSERT(instr->following(1)->IsBranchAndLinkToRegister()); | 
| 613     return pc + Assembler::kCallSizeWithRelocation; | 620     return pc + Assembler::kCallSizeWithRelocation; | 
| 614   } | 621   } | 
| 615 } | 622 } | 
| 616 | 623 | 
| 617 | 624 | 
| 618 void Assembler::deserialization_set_special_target_at( | 625 void Assembler::deserialization_set_special_target_at( | 
| 619     Address constant_pool_entry, Address target) { | 626     Address constant_pool_entry, Code* code, Address target) { | 
| 620   Memory::Address_at(constant_pool_entry) = target; | 627   Memory::Address_at(constant_pool_entry) = target; | 
| 621 } | 628 } | 
| 622 | 629 | 
| 623 | 630 | 
| 624 void Assembler::set_target_address_at(Address pc, Address target) { | 631 void Assembler::set_target_address_at(Address pc, | 
|  | 632                                       ConstantPoolArray* constant_pool, | 
|  | 633                                       Address target) { | 
| 625   Memory::Address_at(target_pointer_address_at(pc)) = target; | 634   Memory::Address_at(target_pointer_address_at(pc)) = target; | 
| 626   // Intuitively, we would think it is necessary to always flush the | 635   // Intuitively, we would think it is necessary to always flush the | 
| 627   // instruction cache after patching a target address in the code as follows: | 636   // instruction cache after patching a target address in the code as follows: | 
| 628   //   CPU::FlushICache(pc, sizeof(target)); | 637   //   CPU::FlushICache(pc, sizeof(target)); | 
| 629   // However, on ARM, an instruction is actually patched in the case of | 638   // However, on ARM, an instruction is actually patched in the case of | 
| 630   // embedded constants of the form: | 639   // embedded constants of the form: | 
| 631   // ldr   ip, [pc, #...] | 640   // ldr   ip, [pc, #...] | 
| 632   // since the instruction accessing this address in the constant pool remains | 641   // since the instruction accessing this address in the constant pool remains | 
| 633   // unchanged, a flush is not required. | 642   // unchanged, a flush is not required. | 
| 634 } | 643 } | 
| 635 | 644 | 
| 636 | 645 | 
|  | 646 void Assembler::set_target_address_at(Address pc, | 
|  | 647                                       Code* code, | 
|  | 648                                       Address target) { | 
|  | 649   ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; | 
|  | 650   set_target_address_at(pc, constant_pool, target); | 
|  | 651 } | 
|  | 652 | 
|  | 653 | 
| 637 int RelocInfo::target_address_size() { | 654 int RelocInfo::target_address_size() { | 
| 638   return kPointerSize; | 655   return kPointerSize; | 
| 639 } | 656 } | 
| 640 | 657 | 
| 641 | 658 | 
| 642 Address RelocInfo::target_address() { | 659 Address RelocInfo::target_address() { | 
| 643   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 660   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 
| 644   return Assembler::target_address_at(pc_); | 661   return Assembler::target_address_at(pc_, host_); | 
| 645 } | 662 } | 
| 646 | 663 | 
| 647 | 664 | 
| 648 Address RelocInfo::target_address_address() { | 665 Address RelocInfo::target_address_address() { | 
| 649   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 666   ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 
| 650                               || rmode_ == EMBEDDED_OBJECT | 667                               || rmode_ == EMBEDDED_OBJECT | 
| 651                               || rmode_ == EXTERNAL_REFERENCE); | 668                               || rmode_ == EXTERNAL_REFERENCE); | 
| 652   return Assembler::target_pointer_address_at(pc_); | 669   return Assembler::target_pointer_address_at(pc_); | 
| 653 } | 670 } | 
| 654 | 671 | 
| 655 | 672 | 
| 656 Address RelocInfo::constant_pool_entry_address() { | 673 Address RelocInfo::constant_pool_entry_address() { | 
| 657   ASSERT(IsInConstantPool()); | 674   ASSERT(IsInConstantPool()); | 
| 658   return Assembler::target_pointer_address_at(pc_); | 675   return Assembler::target_pointer_address_at(pc_); | 
| 659 } | 676 } | 
| 660 | 677 | 
| 661 | 678 | 
| 662 Object* RelocInfo::target_object() { | 679 Object* RelocInfo::target_object() { | 
| 663   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 680   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 
| 664   return reinterpret_cast<Object*>(Assembler::target_address_at(pc_)); | 681   return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_)); | 
| 665 } | 682 } | 
| 666 | 683 | 
| 667 | 684 | 
| 668 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 685 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 
| 669   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 686   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 
| 670   return Handle<Object>(reinterpret_cast<Object**>( | 687   return Handle<Object>(reinterpret_cast<Object**>( | 
| 671       Assembler::target_address_at(pc_))); | 688       Assembler::target_address_at(pc_, host_))); | 
| 672 } | 689 } | 
| 673 | 690 | 
| 674 | 691 | 
| 675 void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { | 692 void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { | 
| 676   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 693   ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 
| 677   ASSERT(!target->IsConsString()); | 694   ASSERT(!target->IsConsString()); | 
| 678   Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); | 695   Assembler::set_target_address_at(pc_, host_, | 
|  | 696                                    reinterpret_cast<Address>(target)); | 
| 679   if (mode == UPDATE_WRITE_BARRIER && | 697   if (mode == UPDATE_WRITE_BARRIER && | 
| 680       host() != NULL && | 698       host() != NULL && | 
| 681       target->IsHeapObject()) { | 699       target->IsHeapObject()) { | 
| 682     host()->GetHeap()->incremental_marking()->RecordWrite( | 700     host()->GetHeap()->incremental_marking()->RecordWrite( | 
| 683         host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 701         host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 
| 684   } | 702   } | 
| 685 } | 703 } | 
| 686 | 704 | 
| 687 | 705 | 
| 688 Address RelocInfo::target_reference() { | 706 Address RelocInfo::target_reference() { | 
| 689   ASSERT(rmode_ == EXTERNAL_REFERENCE); | 707   ASSERT(rmode_ == EXTERNAL_REFERENCE); | 
| 690   return Assembler::target_address_at(pc_); | 708   return Assembler::target_address_at(pc_, host_); | 
| 691 } | 709 } | 
| 692 | 710 | 
| 693 | 711 | 
| 694 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 712 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 
| 695   ASSERT(IsRuntimeEntry(rmode_)); | 713   ASSERT(IsRuntimeEntry(rmode_)); | 
| 696   return target_address(); | 714   return target_address(); | 
| 697 } | 715 } | 
| 698 | 716 | 
| 699 | 717 | 
| 700 void RelocInfo::set_target_runtime_entry(Address target, | 718 void RelocInfo::set_target_runtime_entry(Address target, | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 749   Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; | 767   Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; | 
| 750   Memory::Address_at(stub_entry_address) = stub->instruction_start(); | 768   Memory::Address_at(stub_entry_address) = stub->instruction_start(); | 
| 751 } | 769 } | 
| 752 | 770 | 
| 753 | 771 | 
| 754 Address RelocInfo::call_address() { | 772 Address RelocInfo::call_address() { | 
| 755   ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 773   ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 
| 756          (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 774          (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 
| 757   // For the above sequences the Relocinfo points to the load literal loading | 775   // For the above sequences the Relocinfo points to the load literal loading | 
| 758   // the call address. | 776   // the call address. | 
| 759   return Assembler::target_address_at(pc_); | 777   return Assembler::target_address_at(pc_, host_); | 
| 760 } | 778 } | 
| 761 | 779 | 
| 762 | 780 | 
| 763 void RelocInfo::set_call_address(Address target) { | 781 void RelocInfo::set_call_address(Address target) { | 
| 764   ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 782   ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 
| 765          (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 783          (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 
| 766   Assembler::set_target_address_at(pc_, target); | 784   Assembler::set_target_address_at(pc_, host_, target); | 
| 767   if (host() != NULL) { | 785   if (host() != NULL) { | 
| 768     Object* target_code = Code::GetCodeFromTargetAddress(target); | 786     Object* target_code = Code::GetCodeFromTargetAddress(target); | 
| 769     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 787     host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 
| 770         host(), this, HeapObject::cast(target_code)); | 788         host(), this, HeapObject::cast(target_code)); | 
| 771   } | 789   } | 
| 772 } | 790 } | 
| 773 | 791 | 
| 774 | 792 | 
| 775 void RelocInfo::WipeOut() { | 793 void RelocInfo::WipeOut() { | 
| 776   ASSERT(IsEmbeddedObject(rmode_) || | 794   ASSERT(IsEmbeddedObject(rmode_) || | 
| 777          IsCodeTarget(rmode_) || | 795          IsCodeTarget(rmode_) || | 
| 778          IsRuntimeEntry(rmode_) || | 796          IsRuntimeEntry(rmode_) || | 
| 779          IsExternalReference(rmode_)); | 797          IsExternalReference(rmode_)); | 
| 780   Assembler::set_target_address_at(pc_, NULL); | 798   Assembler::set_target_address_at(pc_, host_, NULL); | 
| 781 } | 799 } | 
| 782 | 800 | 
| 783 | 801 | 
| 784 bool RelocInfo::IsPatchedReturnSequence() { | 802 bool RelocInfo::IsPatchedReturnSequence() { | 
| 785   // The sequence must be: | 803   // The sequence must be: | 
| 786   //   ldr ip0, [pc, #offset] | 804   //   ldr ip0, [pc, #offset] | 
| 787   //   blr ip0 | 805   //   blr ip0 | 
| 788   // See a64/debug-a64.cc BreakLocationIterator::SetDebugBreakAtReturn(). | 806   // See a64/debug-a64.cc BreakLocationIterator::SetDebugBreakAtReturn(). | 
| 789   Instruction* i1 = reinterpret_cast<Instruction*>(pc_); | 807   Instruction* i1 = reinterpret_cast<Instruction*>(pc_); | 
| 790   Instruction* i2 = i1->following(); | 808   Instruction* i2 = i1->following(); | 
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1204 | 1222 | 
| 1205 | 1223 | 
| 1206 void Assembler::ClearRecordedAstId() { | 1224 void Assembler::ClearRecordedAstId() { | 
| 1207   recorded_ast_id_ = TypeFeedbackId::None(); | 1225   recorded_ast_id_ = TypeFeedbackId::None(); | 
| 1208 } | 1226 } | 
| 1209 | 1227 | 
| 1210 | 1228 | 
| 1211 } }  // namespace v8::internal | 1229 } }  // namespace v8::internal | 
| 1212 | 1230 | 
| 1213 #endif  // V8_A64_ASSEMBLER_A64_INL_H_ | 1231 #endif  // V8_A64_ASSEMBLER_A64_INL_H_ | 
| OLD | NEW | 
|---|