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_(ObjectPool::Handle(code.GetObjectPool())), | 17 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
18 end_(pc), | 18 end_(pc), |
19 args_desc_load_end_(0), | |
20 ic_data_load_end_(0), | 19 ic_data_load_end_(0), |
21 target_address_pool_index_(-1), | 20 target_address_pool_index_(-1), |
22 args_desc_(Array::Handle()), | |
23 ic_data_(ICData::Handle()) { | 21 ic_data_(ICData::Handle()) { |
24 ASSERT(code.ContainsInstructionAt(pc)); | 22 ASSERT(code.ContainsInstructionAt(pc)); |
25 // Last instruction: blr ip0. | 23 // Last instruction: blr ip0. |
26 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); | 24 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); |
27 | 25 |
28 Register reg; | 26 Register reg; |
29 ic_data_load_end_ = | 27 ic_data_load_end_ = |
30 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, | 28 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, |
31 ®, | 29 ®, |
32 &target_address_pool_index_); | 30 &target_address_pool_index_); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 start -= Instr::kInstrSize; | 230 start -= Instr::kInstrSize; |
233 instr = Instr::At(start); | 231 instr = Instr::At(start); |
234 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12); | 232 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12); |
235 instr->SetInstructionBits(instr->InstructionBits() | B22); | 233 instr->SetInstructionBits(instr->InstructionBits() | B22); |
236 } | 234 } |
237 | 235 |
238 | 236 |
239 RawICData* CallPattern::IcData() { | 237 RawICData* CallPattern::IcData() { |
240 if (ic_data_.IsNull()) { | 238 if (ic_data_.IsNull()) { |
241 Register reg; | 239 Register reg; |
242 args_desc_load_end_ = | 240 InstructionPattern::DecodeLoadObject(ic_data_load_end_, |
243 InstructionPattern::DecodeLoadObject(ic_data_load_end_, | 241 object_pool_, |
244 object_pool_, | 242 ®, |
245 ®, | 243 &ic_data_); |
246 &ic_data_); | |
247 ASSERT(reg == R5); | 244 ASSERT(reg == R5); |
248 } | 245 } |
249 return ic_data_.raw(); | 246 return ic_data_.raw(); |
250 } | 247 } |
251 | 248 |
252 | 249 |
253 RawArray* CallPattern::ClosureArgumentsDescriptor() { | |
254 if (args_desc_.IsNull()) { | |
255 IcData(); // Loading of the ic_data must be decoded first, if not already. | |
256 Register reg; | |
257 InstructionPattern::DecodeLoadObject(args_desc_load_end_, | |
258 object_pool_, | |
259 ®, | |
260 &args_desc_); | |
261 ASSERT(reg == R4); | |
262 } | |
263 return args_desc_.raw(); | |
264 } | |
265 | |
266 | |
267 uword CallPattern::TargetAddress() const { | 250 uword CallPattern::TargetAddress() const { |
268 return object_pool_.RawValueAt(target_address_pool_index_); | 251 return object_pool_.RawValueAt(target_address_pool_index_); |
269 } | 252 } |
270 | 253 |
271 | 254 |
272 void CallPattern::SetTargetAddress(uword target_address) const { | 255 void CallPattern::SetTargetAddress(uword target_address) const { |
273 object_pool_.SetRawValueAt(target_address_pool_index_, target_address); | 256 object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
274 // No need to flush the instruction cache, since the code is not modified. | 257 // No need to flush the instruction cache, since the code is not modified. |
275 } | 258 } |
276 | 259 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 bool ReturnPattern::IsValid() const { | 350 bool ReturnPattern::IsValid() const { |
368 Instr* bx_lr = Instr::At(pc_); | 351 Instr* bx_lr = Instr::At(pc_); |
369 const Register crn = ConcreteRegister(LR); | 352 const Register crn = ConcreteRegister(LR); |
370 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); | 353 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); |
371 return bx_lr->InstructionBits() == instruction; | 354 return bx_lr->InstructionBits() == instruction; |
372 } | 355 } |
373 | 356 |
374 } // namespace dart | 357 } // namespace dart |
375 | 358 |
376 #endif // defined TARGET_ARCH_ARM64 | 359 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |