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 |