| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/constants_arm.h" | 9 #include "vm/constants_arm.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| 11 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 CallPattern::CallPattern(uword pc, const Code& code) | 16 CallPattern::CallPattern(uword pc, const Code& code) |
| 17 : object_pool_(Array::Handle(code.ObjectPool())), | 17 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
| 18 end_(pc), | 18 end_(pc), |
| 19 args_desc_load_end_(0), | 19 args_desc_load_end_(0), |
| 20 ic_data_load_end_(0), | 20 ic_data_load_end_(0), |
| 21 target_address_pool_index_(-1), | 21 target_address_pool_index_(-1), |
| 22 args_desc_(Array::Handle()), | 22 args_desc_(Array::Handle()), |
| 23 ic_data_(ICData::Handle()) { | 23 ic_data_(ICData::Handle()) { |
| 24 ASSERT(code.ContainsInstructionAt(pc)); | 24 ASSERT(code.ContainsInstructionAt(pc)); |
| 25 // Last instruction: blx lr. | 25 // Last instruction: blx lr. |
| 26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); | 26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); |
| 27 | 27 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 | 46 |
| 47 | 47 |
| 48 // Decodes a load sequence ending at 'end' (the last instruction of the load | 48 // Decodes a load sequence ending at 'end' (the last instruction of the load |
| 49 // sequence is the instruction before the one at end). Returns a pointer to | 49 // sequence is the instruction before the one at end). Returns a pointer to |
| 50 // the first instruction in the sequence. Returns the register being loaded | 50 // the first instruction in the sequence. Returns the register being loaded |
| 51 // and the loaded object in the output parameters 'reg' and 'obj' | 51 // and the loaded object in the output parameters 'reg' and 'obj' |
| 52 // respectively. | 52 // respectively. |
| 53 uword InstructionPattern::DecodeLoadObject(uword end, | 53 uword InstructionPattern::DecodeLoadObject(uword end, |
| 54 const Array& object_pool, | 54 const ObjectPool& object_pool, |
| 55 Register* reg, | 55 Register* reg, |
| 56 Object* obj) { | 56 Object* obj) { |
| 57 uword start = 0; | 57 uword start = 0; |
| 58 Instr* instr = Instr::At(end - Instr::kInstrSize); | 58 Instr* instr = Instr::At(end - Instr::kInstrSize); |
| 59 if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) { | 59 if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) { |
| 60 // ldr reg, [reg, #+offset] | 60 // ldr reg, [reg, #+offset] |
| 61 intptr_t index = 0; | 61 intptr_t index = 0; |
| 62 start = DecodeLoadWordFromPool(end, reg, &index); | 62 start = DecodeLoadWordFromPool(end, reg, &index); |
| 63 *obj = object_pool.At(index); | 63 *obj = object_pool.ObjectAt(index); |
| 64 } else { | 64 } else { |
| 65 intptr_t value = 0; | 65 intptr_t value = 0; |
| 66 start = DecodeLoadWordImmediate(end, reg, &value); | 66 start = DecodeLoadWordImmediate(end, reg, &value); |
| 67 *obj = reinterpret_cast<RawObject*>(value); | 67 *obj = reinterpret_cast<RawObject*>(value); |
| 68 } | 68 } |
| 69 return start; | 69 return start; |
| 70 } | 70 } |
| 71 | 71 |
| 72 | 72 |
| 73 // Decodes a load sequence ending at 'end' (the last instruction of the load | 73 // Decodes a load sequence ending at 'end' (the last instruction of the load |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 object_pool_, | 179 object_pool_, |
| 180 ®, | 180 ®, |
| 181 &args_desc_); | 181 &args_desc_); |
| 182 ASSERT(reg == R4); | 182 ASSERT(reg == R4); |
| 183 } | 183 } |
| 184 return args_desc_.raw(); | 184 return args_desc_.raw(); |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 uword CallPattern::TargetAddress() const { | 188 uword CallPattern::TargetAddress() const { |
| 189 ASSERT(target_address_pool_index_ >= 0); | 189 return object_pool_.RawValueAt(target_address_pool_index_); |
| 190 const Object& target_address = | |
| 191 Object::Handle(object_pool_.At(target_address_pool_index_)); | |
| 192 ASSERT(target_address.IsSmi()); | |
| 193 // The address is stored in the object array as a RawSmi. | |
| 194 return reinterpret_cast<uword>(target_address.raw()); | |
| 195 } | 190 } |
| 196 | 191 |
| 197 | 192 |
| 198 void CallPattern::SetTargetAddress(uword target_address) const { | 193 void CallPattern::SetTargetAddress(uword target_address) const { |
| 199 ASSERT(Utils::IsAligned(target_address, 4)); | 194 object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
| 200 // The address is stored in the object array as a RawSmi. | |
| 201 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); | |
| 202 object_pool_.SetAt(target_address_pool_index_, smi); | |
| 203 // No need to flush the instruction cache, since the code is not modified. | 195 // No need to flush the instruction cache, since the code is not modified. |
| 204 } | 196 } |
| 205 | 197 |
| 206 | 198 |
| 207 void CallPattern::InsertAt(uword pc, uword target_address) { | 199 void CallPattern::InsertAt(uword pc, uword target_address) { |
| 208 const ARMVersion version = TargetCPUFeatures::arm_version(); | 200 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 209 if ((version == ARMv5TE) || (version == ARMv6)) { | 201 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 210 const uint32_t byte0 = (target_address & 0x000000ff); | 202 const uint32_t byte0 = (target_address & 0x000000ff); |
| 211 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; | 203 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; |
| 212 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; | 204 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } else { | 356 } else { |
| 365 ASSERT(version == ARMv7); | 357 ASSERT(version == ARMv7); |
| 366 return bx_lr->InstructionBits() == instruction; | 358 return bx_lr->InstructionBits() == instruction; |
| 367 } | 359 } |
| 368 return false; | 360 return false; |
| 369 } | 361 } |
| 370 | 362 |
| 371 } // namespace dart | 363 } // namespace dart |
| 372 | 364 |
| 373 #endif // defined TARGET_ARCH_ARM | 365 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |