| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 Address RelocInfo::target_address() { | 111 Address RelocInfo::target_address() { |
| 112 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 112 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 113 return Assembler::target_address_at(pc_, host_); | 113 return Assembler::target_address_at(pc_, host_); |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 Address RelocInfo::target_address_address() { | 117 Address RelocInfo::target_address_address() { |
| 118 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 118 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
| 119 || rmode_ == EMBEDDED_OBJECT | 119 || rmode_ == EMBEDDED_OBJECT |
| 120 || rmode_ == EXTERNAL_REFERENCE); | 120 || rmode_ == EXTERNAL_REFERENCE); |
| 121 if (FLAG_enable_embedded_constant_pool || | 121 if (FLAG_enable_ool_constant_pool || |
| 122 Assembler::IsMovW(Memory::int32_at(pc_))) { | 122 Assembler::IsMovW(Memory::int32_at(pc_))) { |
| 123 // We return the PC for ool constant pool since this function is used by the | 123 // We return the PC for ool constant pool since this function is used by the |
| 124 // serializer and expects the address to reside within the code object. | 124 // serializer and expects the address to reside within the code object. |
| 125 return reinterpret_cast<Address>(pc_); | 125 return reinterpret_cast<Address>(pc_); |
| 126 } else { | 126 } else { |
| 127 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); | 127 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); |
| 128 return constant_pool_entry_address(); | 128 return constant_pool_entry_address(); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 // A mov / orr load immediate. | 538 // A mov / orr load immediate. |
| 539 return pc + kInstrSize * 5; | 539 return pc + kInstrSize * 5; |
| 540 } | 540 } |
| 541 } | 541 } |
| 542 } | 542 } |
| 543 } | 543 } |
| 544 | 544 |
| 545 | 545 |
| 546 void Assembler::deserialization_set_special_target_at( | 546 void Assembler::deserialization_set_special_target_at( |
| 547 Address constant_pool_entry, Code* code, Address target) { | 547 Address constant_pool_entry, Code* code, Address target) { |
| 548 if (FLAG_enable_embedded_constant_pool) { | 548 if (FLAG_enable_ool_constant_pool) { |
| 549 set_target_address_at(constant_pool_entry, code, target); | 549 set_target_address_at(constant_pool_entry, code, target); |
| 550 } else { | 550 } else { |
| 551 Memory::Address_at(constant_pool_entry) = target; | 551 Memory::Address_at(constant_pool_entry) = target; |
| 552 } | 552 } |
| 553 } | 553 } |
| 554 | 554 |
| 555 | 555 |
| 556 void Assembler::deserialization_set_target_internal_reference_at( | 556 void Assembler::deserialization_set_target_internal_reference_at( |
| 557 Address pc, Address target, RelocInfo::Mode mode) { | 557 Address pc, Address target, RelocInfo::Mode mode) { |
| 558 Memory::Address_at(pc) = target; | 558 Memory::Address_at(pc) = target; |
| 559 } | 559 } |
| 560 | 560 |
| 561 | 561 |
| 562 bool Assembler::is_constant_pool_load(Address pc) { | 562 bool Assembler::is_constant_pool_load(Address pc) { |
| 563 if (CpuFeatures::IsSupported(ARMv7)) { | 563 if (CpuFeatures::IsSupported(ARMv7)) { |
| 564 return !Assembler::IsMovW(Memory::int32_at(pc)) || | 564 return !Assembler::IsMovW(Memory::int32_at(pc)) || |
| 565 (FLAG_enable_embedded_constant_pool && | 565 (FLAG_enable_ool_constant_pool && |
| 566 Assembler::IsLdrPpRegOffset( | 566 Assembler::IsLdrPpRegOffset( |
| 567 Memory::int32_at(pc + 2 * Assembler::kInstrSize))); | 567 Memory::int32_at(pc + 2 * Assembler::kInstrSize))); |
| 568 } else { | 568 } else { |
| 569 return !Assembler::IsMovImmed(Memory::int32_at(pc)) || | 569 return !Assembler::IsMovImmed(Memory::int32_at(pc)) || |
| 570 (FLAG_enable_embedded_constant_pool && | 570 (FLAG_enable_ool_constant_pool && |
| 571 Assembler::IsLdrPpRegOffset( | 571 Assembler::IsLdrPpRegOffset( |
| 572 Memory::int32_at(pc + 4 * Assembler::kInstrSize))); | 572 Memory::int32_at(pc + 4 * Assembler::kInstrSize))); |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 Address Assembler::constant_pool_entry_address(Address pc, | 577 Address Assembler::constant_pool_entry_address( |
| 578 Address constant_pool) { | 578 Address pc, ConstantPoolArray* constant_pool) { |
| 579 if (FLAG_enable_embedded_constant_pool) { | 579 if (FLAG_enable_ool_constant_pool) { |
| 580 DCHECK(constant_pool != NULL); | 580 DCHECK(constant_pool != NULL); |
| 581 int cp_offset; | 581 int cp_offset; |
| 582 if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) { | 582 if (!CpuFeatures::IsSupported(ARMv7) && IsMovImmed(Memory::int32_at(pc))) { |
| 583 DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)) && | 583 DCHECK(IsOrrImmed(Memory::int32_at(pc + kInstrSize)) && |
| 584 IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) && | 584 IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) && |
| 585 IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)) && | 585 IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)) && |
| 586 IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))); | 586 IsLdrPpRegOffset(Memory::int32_at(pc + 4 * kInstrSize))); |
| 587 // This is an extended constant pool lookup (ARMv6). | 587 // This is an extended constant pool lookup (ARMv6). |
| 588 Instr mov_instr = instr_at(pc); | 588 Instr mov_instr = instr_at(pc); |
| 589 Instr orr_instr_1 = instr_at(pc + kInstrSize); | 589 Instr orr_instr_1 = instr_at(pc + kInstrSize); |
| 590 Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize); | 590 Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize); |
| 591 Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize); | 591 Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize); |
| 592 cp_offset = DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) | | 592 cp_offset = DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) | |
| 593 DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3); | 593 DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3); |
| 594 } else if (IsMovW(Memory::int32_at(pc))) { | 594 } else if (IsMovW(Memory::int32_at(pc))) { |
| 595 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)) && | 595 DCHECK(IsMovT(Memory::int32_at(pc + kInstrSize)) && |
| 596 IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))); | 596 IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize))); |
| 597 // This is an extended constant pool lookup (ARMv7). | 597 // This is an extended constant pool lookup (ARMv7). |
| 598 Instruction* movw_instr = Instruction::At(pc); | 598 Instruction* movw_instr = Instruction::At(pc); |
| 599 Instruction* movt_instr = Instruction::At(pc + kInstrSize); | 599 Instruction* movt_instr = Instruction::At(pc + kInstrSize); |
| 600 cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) | | 600 cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) | |
| 601 movw_instr->ImmedMovwMovtValue(); | 601 movw_instr->ImmedMovwMovtValue(); |
| 602 } else { | 602 } else { |
| 603 // This is a small constant pool lookup. | 603 // This is a small constant pool lookup. |
| 604 DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); | 604 DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); |
| 605 cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); | 605 cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); |
| 606 } | 606 } |
| 607 return constant_pool + cp_offset; | 607 return reinterpret_cast<Address>(constant_pool) + cp_offset; |
| 608 } else { | 608 } else { |
| 609 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); | 609 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); |
| 610 Instr instr = Memory::int32_at(pc); | 610 Instr instr = Memory::int32_at(pc); |
| 611 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; | 611 return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; |
| 612 } | 612 } |
| 613 } | 613 } |
| 614 | 614 |
| 615 | 615 |
| 616 Address Assembler::target_address_at(Address pc, Address constant_pool) { | 616 Address Assembler::target_address_at(Address pc, |
| 617 ConstantPoolArray* constant_pool) { |
| 617 if (is_constant_pool_load(pc)) { | 618 if (is_constant_pool_load(pc)) { |
| 618 // This is a constant pool lookup. Return the value in the constant pool. | 619 // This is a constant pool lookup. Return the value in the constant pool. |
| 619 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); | 620 return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); |
| 620 } else if (CpuFeatures::IsSupported(ARMv7)) { | 621 } else if (CpuFeatures::IsSupported(ARMv7)) { |
| 621 // This is an movw / movt immediate load. Return the immediate. | 622 // This is an movw / movt immediate load. Return the immediate. |
| 622 DCHECK(IsMovW(Memory::int32_at(pc)) && | 623 DCHECK(IsMovW(Memory::int32_at(pc)) && |
| 623 IsMovT(Memory::int32_at(pc + kInstrSize))); | 624 IsMovT(Memory::int32_at(pc + kInstrSize))); |
| 624 Instruction* movw_instr = Instruction::At(pc); | 625 Instruction* movw_instr = Instruction::At(pc); |
| 625 Instruction* movt_instr = Instruction::At(pc + kInstrSize); | 626 Instruction* movt_instr = Instruction::At(pc + kInstrSize); |
| 626 return reinterpret_cast<Address>( | 627 return reinterpret_cast<Address>( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 637 Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize); | 638 Instr orr_instr_2 = instr_at(pc + 2 * kInstrSize); |
| 638 Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize); | 639 Instr orr_instr_3 = instr_at(pc + 3 * kInstrSize); |
| 639 Address ret = reinterpret_cast<Address>( | 640 Address ret = reinterpret_cast<Address>( |
| 640 DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) | | 641 DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) | |
| 641 DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3)); | 642 DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3)); |
| 642 return ret; | 643 return ret; |
| 643 } | 644 } |
| 644 } | 645 } |
| 645 | 646 |
| 646 | 647 |
| 647 void Assembler::set_target_address_at(Address pc, Address constant_pool, | 648 void Assembler::set_target_address_at(Address pc, |
| 649 ConstantPoolArray* constant_pool, |
| 648 Address target, | 650 Address target, |
| 649 ICacheFlushMode icache_flush_mode) { | 651 ICacheFlushMode icache_flush_mode) { |
| 650 if (is_constant_pool_load(pc)) { | 652 if (is_constant_pool_load(pc)) { |
| 651 // This is a constant pool lookup. Update the entry in the constant pool. | 653 // This is a constant pool lookup. Update the entry in the constant pool. |
| 652 Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; | 654 Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; |
| 653 // Intuitively, we would think it is necessary to always flush the | 655 // Intuitively, we would think it is necessary to always flush the |
| 654 // instruction cache after patching a target address in the code as follows: | 656 // instruction cache after patching a target address in the code as follows: |
| 655 // CpuFeatures::FlushICache(pc, sizeof(target)); | 657 // CpuFeatures::FlushICache(pc, sizeof(target)); |
| 656 // However, on ARM, no instruction is actually patched in the case | 658 // However, on ARM, no instruction is actually patched in the case |
| 657 // of embedded constants of the form: | 659 // of embedded constants of the form: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 694 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 693 CpuFeatures::FlushICache(pc, 4 * kInstrSize); | 695 CpuFeatures::FlushICache(pc, 4 * kInstrSize); |
| 694 } | 696 } |
| 695 } | 697 } |
| 696 } | 698 } |
| 697 | 699 |
| 698 | 700 |
| 699 } } // namespace v8::internal | 701 } } // namespace v8::internal |
| 700 | 702 |
| 701 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ | 703 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ |
| OLD | NEW |