Index: runtime/vm/instructions_arm.cc |
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc |
index 9002d50fb33bc51a778f998db3d4809bcfd64572..1533a20391accad78729da4d64c6158abb1e0f21 100644 |
--- a/runtime/vm/instructions_arm.cc |
+++ b/runtime/vm/instructions_arm.cc |
@@ -17,7 +17,7 @@ CallPattern::CallPattern(uword pc, const Code& code) |
: object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
end_(pc), |
ic_data_load_end_(0), |
- target_address_pool_index_(-1), |
+ target_code_pool_index_(-1), |
ic_data_(ICData::Handle()) { |
ASSERT(code.ContainsInstructionAt(pc)); |
// Last instruction: blx lr. |
@@ -25,14 +25,14 @@ CallPattern::CallPattern(uword pc, const Code& code) |
Register reg; |
ic_data_load_end_ = |
- InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, |
+ InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, |
®, |
- &target_address_pool_index_); |
- ASSERT(reg == LR); |
+ &target_code_pool_index_); |
+ ASSERT(reg == CODE_REG); |
} |
-int CallPattern::LengthInBytes() { |
+int CallPattern::DeoptCallPatternLengthInBytes() { |
const ARMVersion version = TargetCPUFeatures::arm_version(); |
if ((version == ARMv5TE) || (version == ARMv6)) { |
return 5 * Instr::kInstrSize; |
@@ -47,17 +47,17 @@ NativeCallPattern::NativeCallPattern(uword pc, const Code& code) |
: object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
end_(pc), |
native_function_pool_index_(-1), |
- target_address_pool_index_(-1) { |
+ target_code_pool_index_(-1) { |
ASSERT(code.ContainsInstructionAt(pc)); |
// Last instruction: blx lr. |
ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); |
Register reg; |
uword native_function_load_end = |
- InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, |
+ InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, |
®, |
- &target_address_pool_index_); |
- ASSERT(reg == LR); |
+ &target_code_pool_index_); |
+ ASSERT(reg == CODE_REG); |
InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, |
®, |
&native_function_pool_index_); |
@@ -65,13 +65,14 @@ NativeCallPattern::NativeCallPattern(uword pc, const Code& code) |
} |
-uword NativeCallPattern::target() const { |
- return object_pool_.RawValueAt(target_address_pool_index_); |
+RawCode* NativeCallPattern::target() const { |
+ return reinterpret_cast<RawCode*>( |
+ object_pool_.ObjectAt(target_code_pool_index_)); |
} |
-void NativeCallPattern::set_target(uword target_address) const { |
- object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
+void NativeCallPattern::set_target(const Code& new_target) const { |
+ object_pool_.SetObjectAt(target_code_pool_index_, new_target); |
// No need to flush the instruction cache, since the code is not modified. |
} |
@@ -175,7 +176,7 @@ uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
uword start = end - Instr::kInstrSize; |
int32_t instr = Instr::At(start)->InstructionBits(); |
intptr_t offset = 0; |
- if ((instr & 0xffff0000) == 0xe59a0000) { // ldr reg, [pp, #+offset] |
+ if ((instr & 0xffff0000) == 0xe5990000) { // ldr reg, [pp, #+offset] |
offset = instr & 0xfff; |
*reg = static_cast<Register>((instr & 0xf000) >> 12); |
} else { |
@@ -183,13 +184,13 @@ uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
offset = instr & 0xfff; |
start -= Instr::kInstrSize; |
instr = Instr::At(start)->InstructionBits(); |
- if ((instr & 0xffff0000) == 0xe28a0000) { // add reg, pp, operand |
+ if ((instr & 0xffff0000) == 0xe2890000) { // add reg, pp, operand |
const intptr_t rot = (instr & 0xf00) >> 7; |
const intptr_t imm8 = instr & 0xff; |
offset += (imm8 >> rot) | (imm8 << (32 - rot)); |
*reg = static_cast<Register>((instr & 0xf000) >> 12); |
} else { |
- ASSERT((instr & 0xffff0000) == 0xe08a0000); // add reg, pp, reg |
+ ASSERT((instr & 0xffff0000) == 0xe0890000); // add reg, pp, reg |
end = DecodeLoadWordImmediate(end, reg, &offset); |
} |
} |
@@ -211,18 +212,18 @@ RawICData* CallPattern::IcData() { |
} |
-uword CallPattern::TargetAddress() const { |
- return object_pool_.RawValueAt(target_address_pool_index_); |
+RawCode* CallPattern::TargetCode() const { |
+ return reinterpret_cast<RawCode*>( |
+ object_pool_.ObjectAt(target_code_pool_index_)); |
} |
-void CallPattern::SetTargetAddress(uword target_address) const { |
- object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
- // No need to flush the instruction cache, since the code is not modified. |
+void CallPattern::SetTargetCode(const Code& target_code) const { |
+ object_pool_.SetObjectAt(target_code_pool_index_, target_code); |
} |
-void CallPattern::InsertAt(uword pc, uword target_address) { |
+void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) { |
const ARMVersion version = TargetCPUFeatures::arm_version(); |
if ((version == ARMv5TE) || (version == ARMv6)) { |
const uint32_t byte0 = (target_address & 0x000000ff); |
@@ -242,8 +243,8 @@ void CallPattern::InsertAt(uword pc, uword target_address) { |
*reinterpret_cast<uword*>(pc + (3 * Instr::kInstrSize)) = or3_ip; |
*reinterpret_cast<uword*>(pc + (4 * Instr::kInstrSize)) = blx_ip; |
- ASSERT(LengthInBytes() == 5 * Instr::kInstrSize); |
- CPU::FlushICache(pc, LengthInBytes()); |
+ ASSERT(DeoptCallPatternLengthInBytes() == 5 * Instr::kInstrSize); |
+ CPU::FlushICache(pc, DeoptCallPatternLengthInBytes()); |
} else { |
ASSERT(version == ARMv7); |
const uint16_t target_lo = target_address & 0xffff; |
@@ -259,106 +260,8 @@ void CallPattern::InsertAt(uword pc, uword target_address) { |
*reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip; |
*reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip; |
- ASSERT(LengthInBytes() == 3 * Instr::kInstrSize); |
- CPU::FlushICache(pc, LengthInBytes()); |
- } |
-} |
- |
- |
-JumpPattern::JumpPattern(uword pc, const Code& code) : pc_(pc) { } |
- |
- |
-int JumpPattern::pattern_length_in_bytes() { |
- const ARMVersion version = TargetCPUFeatures::arm_version(); |
- if ((version == ARMv5TE) || (version == ARMv6)) { |
- return 5 * Instr::kInstrSize; |
- } else { |
- ASSERT(version == ARMv7); |
- return 3 * Instr::kInstrSize; |
- } |
-} |
- |
- |
-bool JumpPattern::IsValid() const { |
- const ARMVersion version = TargetCPUFeatures::arm_version(); |
- if ((version == ARMv5TE) || (version == ARMv6)) { |
- Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); |
- Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); |
- Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
- Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); |
- Instr* bx_ip = Instr::At(pc_ + (4 * Instr::kInstrSize)); |
- return ((mov_ip->InstructionBits() & 0xffffff00) == 0xe3a0c400) && |
- ((or1_ip->InstructionBits() & 0xffffff00) == 0xe38cc800) && |
- ((or2_ip->InstructionBits() & 0xffffff00) == 0xe38ccc00) && |
- ((or3_ip->InstructionBits() & 0xffffff00) == 0xe38cc000) && |
- ((bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c); |
- } else { |
- ASSERT(version == ARMv7); |
- Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo |
- Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi |
- Instr* bx_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
- return (movw_ip->InstructionBits() & 0xfff0f000) == 0xe300c000 && |
- (movt_ip->InstructionBits() & 0xfff0f000) == 0xe340c000 && |
- (bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c; |
- } |
-} |
- |
- |
-uword JumpPattern::TargetAddress() const { |
- const ARMVersion version = TargetCPUFeatures::arm_version(); |
- if ((version == ARMv5TE) || (version == ARMv6)) { |
- Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); |
- Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); |
- Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
- Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); |
- uword imm = 0; |
- imm |= or3_ip->Immed8Field(); |
- imm |= or2_ip->Immed8Field() << 8; |
- imm |= or1_ip->Immed8Field() << 16; |
- imm |= mov_ip->Immed8Field() << 24; |
- return imm; |
- } else { |
- ASSERT(version == ARMv7); |
- Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo |
- Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi |
- uint16_t target_lo = movw_ip->MovwField(); |
- uint16_t target_hi = movt_ip->MovwField(); |
- return (target_hi << 16) | target_lo; |
- } |
-} |
- |
- |
-void JumpPattern::SetTargetAddress(uword target_address) const { |
- const ARMVersion version = TargetCPUFeatures::arm_version(); |
- if ((version == ARMv5TE) || (version == ARMv6)) { |
- const uint32_t byte0 = (target_address & 0x000000ff); |
- const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; |
- const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; |
- const uint32_t byte3 = (target_address & 0xff000000) >> 24; |
- |
- const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) |
- const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) |
- const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) |
- const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 |
- |
- *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = mov_ip; |
- *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = or1_ip; |
- *reinterpret_cast<uword*>(pc_ + (2 * Instr::kInstrSize)) = or2_ip; |
- *reinterpret_cast<uword*>(pc_ + (3 * Instr::kInstrSize)) = or3_ip; |
- CPU::FlushICache(pc_, 4 * Instr::kInstrSize); |
- } else { |
- ASSERT(version == ARMv7); |
- const uint16_t target_lo = target_address & 0xffff; |
- const uint16_t target_hi = target_address >> 16; |
- |
- const uword movw_ip = |
- 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); |
- const uword movt_ip = |
- 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); |
- |
- *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip; |
- *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip; |
- CPU::FlushICache(pc_, 2 * Instr::kInstrSize); |
+ ASSERT(DeoptCallPatternLengthInBytes() == 3 * Instr::kInstrSize); |
+ CPU::FlushICache(pc, DeoptCallPatternLengthInBytes()); |
} |
} |