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 |