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