| 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" |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 movk3->SetMoveWideBits(MOVK, IP0, h3, 3, kDoubleWord); | 352 movk3->SetMoveWideBits(MOVK, IP0, h3, 3, kDoubleWord); |
| 353 blr->SetUnconditionalBranchRegBits(BLR, IP0); | 353 blr->SetUnconditionalBranchRegBits(BLR, IP0); |
| 354 | 354 |
| 355 ASSERT(kDeoptCallLengthInBytes == 5 * Instr::kInstrSize); | 355 ASSERT(kDeoptCallLengthInBytes == 5 * Instr::kInstrSize); |
| 356 CPU::FlushICache(pc, kDeoptCallLengthInBytes); | 356 CPU::FlushICache(pc, kDeoptCallLengthInBytes); |
| 357 } | 357 } |
| 358 | 358 |
| 359 | 359 |
| 360 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) | 360 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) |
| 361 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), | 361 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
| 362 cache_pool_index_(-1), | 362 data_pool_index_(-1), |
| 363 stub_pool_index_(-1) { | 363 target_pool_index_(-1) { |
| 364 ASSERT(code.ContainsInstructionAt(pc)); | 364 ASSERT(code.ContainsInstructionAt(pc)); |
| 365 // Last instruction: blr r1. | 365 // Last instruction: blr ip0. |
| 366 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0020); | 366 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200); |
| 367 | 367 |
| 368 Register reg; | 368 Register reg; |
| 369 uword stub_load_end = | 369 uword stub_load_end = |
| 370 InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize, | 370 InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize, |
| 371 ®, | 371 ®, |
| 372 &stub_pool_index_); | 372 &target_pool_index_); |
| 373 ASSERT(reg == CODE_REG); | 373 ASSERT(reg == CODE_REG); |
| 374 InstructionPattern::DecodeLoadWordFromPool(stub_load_end, | 374 InstructionPattern::DecodeLoadWordFromPool(stub_load_end, |
| 375 ®, | 375 ®, |
| 376 &cache_pool_index_); | 376 &data_pool_index_); |
| 377 ASSERT(reg == R5); | 377 ASSERT(reg == R5); |
| 378 } | 378 } |
| 379 | 379 |
| 380 | 380 |
| 381 RawObject* SwitchableCallPattern::cache() const { | 381 RawObject* SwitchableCallPattern::data() const { |
| 382 return reinterpret_cast<RawCode*>( | 382 return object_pool_.ObjectAt(data_pool_index_); |
| 383 object_pool_.ObjectAt(cache_pool_index_)); | |
| 384 } | 383 } |
| 385 | 384 |
| 386 | 385 |
| 387 void SwitchableCallPattern::SetCache(const MegamorphicCache& cache) const { | 386 RawCode* SwitchableCallPattern::target() const { |
| 388 ASSERT(Object::Handle(object_pool_.ObjectAt(cache_pool_index_)).IsICData()); | 387 return reinterpret_cast<RawCode*>( |
| 389 object_pool_.SetObjectAt(cache_pool_index_, cache); | 388 object_pool_.ObjectAt(target_pool_index_)); |
| 390 } | 389 } |
| 391 | 390 |
| 392 | 391 |
| 393 void SwitchableCallPattern::SetLookupStub(const Code& lookup_stub) const { | 392 void SwitchableCallPattern::SetData(const Object& data) const { |
| 394 ASSERT(Object::Handle(object_pool_.ObjectAt(stub_pool_index_)).IsCode()); | 393 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); |
| 395 object_pool_.SetObjectAt(stub_pool_index_, lookup_stub); | 394 object_pool_.SetObjectAt(data_pool_index_, data); |
| 396 } | 395 } |
| 397 | 396 |
| 398 | 397 |
| 398 void SwitchableCallPattern::SetTarget(const Code& target) const { |
| 399 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); |
| 400 object_pool_.SetObjectAt(target_pool_index_, target); |
| 401 } |
| 402 |
| 403 |
| 399 ReturnPattern::ReturnPattern(uword pc) | 404 ReturnPattern::ReturnPattern(uword pc) |
| 400 : pc_(pc) { | 405 : pc_(pc) { |
| 401 } | 406 } |
| 402 | 407 |
| 403 | 408 |
| 404 bool ReturnPattern::IsValid() const { | 409 bool ReturnPattern::IsValid() const { |
| 405 Instr* bx_lr = Instr::At(pc_); | 410 Instr* bx_lr = Instr::At(pc_); |
| 406 const Register crn = ConcreteRegister(LR); | 411 const Register crn = ConcreteRegister(LR); |
| 407 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); | 412 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); |
| 408 return bx_lr->InstructionBits() == instruction; | 413 return bx_lr->InstructionBits() == instruction; |
| 409 } | 414 } |
| 410 | 415 |
| 411 } // namespace dart | 416 } // namespace dart |
| 412 | 417 |
| 413 #endif // defined TARGET_ARCH_ARM64 | 418 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |