Index: src/arm/assembler-arm-inl.h |
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h |
index d09e700e82e1f5ea139e3e91c5fbc4e7a3bdae0c..0ca2314567bc08954eb456e9d7806721cb3f9f84 100644 |
--- a/src/arm/assembler-arm-inl.h |
+++ b/src/arm/assembler-arm-inl.h |
@@ -119,21 +119,14 @@ Address RelocInfo::target_address_address() { |
return reinterpret_cast<Address>(pc_); |
} else { |
ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); |
- return Assembler::target_pointer_address_at(pc_); |
+ return constant_pool_entry_address(); |
} |
} |
Address RelocInfo::constant_pool_entry_address() { |
ASSERT(IsInConstantPool()); |
- if (FLAG_enable_ool_constant_pool) { |
- ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc_))); |
- return Assembler::target_constant_pool_address_at(pc_, |
- host_->constant_pool()); |
- } else { |
- ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc_))); |
- return Assembler::target_pointer_address_at(pc_); |
- } |
+ return Assembler::constant_pool_entry_address(pc_, host_->constant_pool()); |
} |
@@ -314,8 +307,8 @@ bool RelocInfo::IsPatchedReturnSequence() { |
// A patched return sequence is: |
// ldr ip, [pc, #0] |
// blx ip |
- return ((current_instr & kLdrPCMask) == kLdrPCPattern) |
- && ((next_instr & kBlxRegMask) == kBlxRegPattern); |
+ return Assembler::IsLdrPcImmediateOffset(current_instr) && |
+ Assembler::IsBlxReg(next_instr); |
} |
@@ -428,42 +421,6 @@ void Assembler::emit(Instr x) { |
} |
-Address Assembler::target_pointer_address_at(Address pc) { |
- Instr instr = Memory::int32_at(pc); |
- return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; |
-} |
- |
- |
-Address Assembler::target_constant_pool_address_at( |
- Address pc, ConstantPoolArray* constant_pool) { |
- ASSERT(constant_pool != NULL); |
- ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); |
- Instr instr = Memory::int32_at(pc); |
- return reinterpret_cast<Address>(constant_pool) + |
- GetLdrRegisterImmediateOffset(instr); |
-} |
- |
- |
-Address Assembler::target_address_at(Address pc, |
- ConstantPoolArray* constant_pool) { |
- if (IsMovW(Memory::int32_at(pc))) { |
- ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); |
- Instruction* instr = Instruction::At(pc); |
- Instruction* next_instr = Instruction::At(pc + kInstrSize); |
- return reinterpret_cast<Address>( |
- (next_instr->ImmedMovwMovtValue() << 16) | |
- instr->ImmedMovwMovtValue()); |
- } else if (FLAG_enable_ool_constant_pool) { |
- ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); |
- return Memory::Address_at( |
- target_constant_pool_address_at(pc, constant_pool)); |
- } else { |
- ASSERT(IsLdrPcImmediateOffset(Memory::int32_at(pc))); |
- return Memory::Address_at(target_pointer_address_at(pc)); |
- } |
-} |
- |
- |
Address Assembler::target_address_from_return_address(Address pc) { |
// Returns the address of the call target from the return address that will |
// be returned to after a call. |
@@ -523,11 +480,63 @@ static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate) { |
} |
+static bool IsConstantPoolLoad(Address pc) { |
+ return !Assembler::IsMovW(Memory::int32_at(pc)); |
+} |
+ |
+ |
+Address Assembler::constant_pool_entry_address( |
+ Address pc, ConstantPoolArray* constant_pool) { |
+ if (FLAG_enable_ool_constant_pool) { |
+ ASSERT(constant_pool != NULL); |
+ ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc))); |
+ return reinterpret_cast<Address>(constant_pool) + |
+ GetLdrRegisterImmediateOffset(Memory::int32_at(pc)); |
+ } else { |
+ ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc))); |
+ Instr instr = Memory::int32_at(pc); |
+ return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta; |
+ } |
+} |
+ |
+ |
+Address Assembler::target_address_at(Address pc, |
+ ConstantPoolArray* constant_pool) { |
+ if (IsConstantPoolLoad(pc)) { |
+ // This is a constant pool lookup. Return the value in the constant pool. |
+ return Memory::Address_at(constant_pool_entry_address(pc, constant_pool)); |
+ } else { |
+ // This is an movw_movt immediate load. Return the immediate. |
+ ASSERT(IsMovW(Memory::int32_at(pc)) && |
+ IsMovT(Memory::int32_at(pc + kInstrSize))); |
+ Instruction* movw_instr = Instruction::At(pc); |
+ Instruction* movt_instr = Instruction::At(pc + kInstrSize); |
+ return reinterpret_cast<Address>( |
+ (movt_instr->ImmedMovwMovtValue() << 16) | |
+ movw_instr->ImmedMovwMovtValue()); |
+ } |
+} |
+ |
+ |
void Assembler::set_target_address_at(Address pc, |
ConstantPoolArray* constant_pool, |
Address target, |
ICacheFlushMode icache_flush_mode) { |
- if (IsMovW(Memory::int32_at(pc))) { |
+ if (IsConstantPoolLoad(pc)) { |
+ // This is a constant pool lookup. Update the entry in the constant pool. |
+ Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target; |
+ // Intuitively, we would think it is necessary to always flush the |
+ // instruction cache after patching a target address in the code as follows: |
+ // CPU::FlushICache(pc, sizeof(target)); |
+ // However, on ARM, no instruction is actually patched in the case |
+ // of embedded constants of the form: |
+ // ldr ip, [pp, #...] |
+ // since the instruction accessing this address in the constant pool remains |
+ // unchanged. |
+ } else { |
+ // This is an movw_movt immediate load. Patch the immediate embedded in the |
+ // instructions. |
+ ASSERT(IsMovW(Memory::int32_at(pc))); |
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize))); |
uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc); |
uint32_t immediate = reinterpret_cast<uint32_t>(target); |
@@ -538,21 +547,6 @@ void Assembler::set_target_address_at(Address pc, |
if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
CPU::FlushICache(pc, 2 * kInstrSize); |
} |
- } else if (FLAG_enable_ool_constant_pool) { |
- ASSERT(IsLdrPpImmediateOffset(Memory::int32_at(pc))); |
- Memory::Address_at( |
- target_constant_pool_address_at(pc, constant_pool)) = target; |
- } else { |
- ASSERT(IsLdrPcImmediateOffset(Memory::int32_at(pc))); |
- Memory::Address_at(target_pointer_address_at(pc)) = target; |
- // Intuitively, we would think it is necessary to always flush the |
- // instruction cache after patching a target address in the code as follows: |
- // CPU::FlushICache(pc, sizeof(target)); |
- // However, on ARM, no instruction is actually patched in the case |
- // of embedded constants of the form: |
- // ldr ip, [pc, #...] |
- // since the instruction accessing this address in the constant pool remains |
- // unchanged. |
} |
} |