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 |