OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/constants_arm64.h" | 9 #include "vm/constants_arm64.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: blr ip0. | 25 // Last instruction: blr ip0. |
26 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); | 26 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); |
27 | 27 |
(...skipping 10 matching lines...) Expand all Loading... |
38 return Array::element_offset(index); | 38 return Array::element_offset(index); |
39 } | 39 } |
40 | 40 |
41 | 41 |
42 // Decodes a load sequence ending at 'end' (the last instruction of the load | 42 // Decodes a load sequence ending at 'end' (the last instruction of the load |
43 // sequence is the instruction before the one at end). Returns a pointer to | 43 // sequence is the instruction before the one at end). Returns a pointer to |
44 // the first instruction in the sequence. Returns the register being loaded | 44 // the first instruction in the sequence. Returns the register being loaded |
45 // and the loaded object in the output parameters 'reg' and 'obj' | 45 // and the loaded object in the output parameters 'reg' and 'obj' |
46 // respectively. | 46 // respectively. |
47 uword InstructionPattern::DecodeLoadObject(uword end, | 47 uword InstructionPattern::DecodeLoadObject(uword end, |
48 const Array& object_pool, | 48 const ObjectPool& object_pool, |
49 Register* reg, | 49 Register* reg, |
50 Object* obj) { | 50 Object* obj) { |
51 // 1. LoadWordFromPool | 51 // 1. LoadWordFromPool |
52 // or | 52 // or |
53 // 2. LoadDecodableImmediate | 53 // 2. LoadDecodableImmediate |
54 uword start = 0; | 54 uword start = 0; |
55 Instr* instr = Instr::At(end - Instr::kInstrSize); | 55 Instr* instr = Instr::At(end - Instr::kInstrSize); |
56 if (instr->IsLoadStoreRegOp()) { | 56 if (instr->IsLoadStoreRegOp()) { |
57 // Case 1. | 57 // Case 1. |
58 intptr_t index = 0; | 58 intptr_t index = 0; |
59 start = DecodeLoadWordFromPool(end, reg, &index); | 59 start = DecodeLoadWordFromPool(end, reg, &index); |
60 *obj = object_pool.At(index); | 60 *obj = object_pool.ObjectAt(index); |
61 } else { | 61 } else { |
62 // Case 2. | 62 // Case 2. |
63 intptr_t value = 0; | 63 intptr_t value = 0; |
64 start = DecodeLoadWordImmediate(end, reg, &value); | 64 start = DecodeLoadWordImmediate(end, reg, &value); |
65 *obj = reinterpret_cast<RawObject*>(value); | 65 *obj = reinterpret_cast<RawObject*>(value); |
66 } | 66 } |
67 return start; | 67 return start; |
68 } | 68 } |
69 | 69 |
70 | 70 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 object_pool_, | 257 object_pool_, |
258 ®, | 258 ®, |
259 &args_desc_); | 259 &args_desc_); |
260 ASSERT(reg == R4); | 260 ASSERT(reg == R4); |
261 } | 261 } |
262 return args_desc_.raw(); | 262 return args_desc_.raw(); |
263 } | 263 } |
264 | 264 |
265 | 265 |
266 uword CallPattern::TargetAddress() const { | 266 uword CallPattern::TargetAddress() const { |
267 ASSERT(target_address_pool_index_ >= 0); | 267 return object_pool_.RawValueAt(target_address_pool_index_); |
268 const Object& target_address = | |
269 Object::Handle(object_pool_.At(target_address_pool_index_)); | |
270 ASSERT(target_address.IsSmi()); | |
271 // The address is stored in the object array as a RawSmi. | |
272 return reinterpret_cast<uword>(target_address.raw()); | |
273 } | 268 } |
274 | 269 |
275 | 270 |
276 void CallPattern::SetTargetAddress(uword target_address) const { | 271 void CallPattern::SetTargetAddress(uword target_address) const { |
277 ASSERT(Utils::IsAligned(target_address, 4)); | 272 object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
278 // The address is stored in the object array as a RawSmi. | |
279 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); | |
280 object_pool_.SetAt(target_address_pool_index_, smi); | |
281 // No need to flush the instruction cache, since the code is not modified. | 273 // No need to flush the instruction cache, since the code is not modified. |
282 } | 274 } |
283 | 275 |
284 | 276 |
285 void CallPattern::InsertAt(uword pc, uword target_address) { | 277 void CallPattern::InsertAt(uword pc, uword target_address) { |
286 Instr* movz0 = Instr::At(pc + (0 * Instr::kInstrSize)); | 278 Instr* movz0 = Instr::At(pc + (0 * Instr::kInstrSize)); |
287 Instr* movk1 = Instr::At(pc + (1 * Instr::kInstrSize)); | 279 Instr* movk1 = Instr::At(pc + (1 * Instr::kInstrSize)); |
288 Instr* movk2 = Instr::At(pc + (2 * Instr::kInstrSize)); | 280 Instr* movk2 = Instr::At(pc + (2 * Instr::kInstrSize)); |
289 Instr* movk3 = Instr::At(pc + (3 * Instr::kInstrSize)); | 281 Instr* movk3 = Instr::At(pc + (3 * Instr::kInstrSize)); |
290 Instr* blr = Instr::At(pc + (4 * Instr::kInstrSize)); | 282 Instr* blr = Instr::At(pc + (4 * Instr::kInstrSize)); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 bool ReturnPattern::IsValid() const { | 366 bool ReturnPattern::IsValid() const { |
375 Instr* bx_lr = Instr::At(pc_); | 367 Instr* bx_lr = Instr::At(pc_); |
376 const Register crn = ConcreteRegister(LR); | 368 const Register crn = ConcreteRegister(LR); |
377 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); | 369 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); |
378 return bx_lr->InstructionBits() == instruction; | 370 return bx_lr->InstructionBits() == instruction; |
379 } | 371 } |
380 | 372 |
381 } // namespace dart | 373 } // namespace dart |
382 | 374 |
383 #endif // defined TARGET_ARCH_ARM64 | 375 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |