| 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 | 
|---|