| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| 11 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
| 12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
| 13 #include "vm/memory_region.h" | 13 #include "vm/memory_region.h" |
| 14 #include "vm/runtime_entry.h" | 14 #include "vm/runtime_entry.h" |
| 15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
| 16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 17 | 17 |
| 18 namespace dart { | 18 namespace dart { |
| 19 | 19 |
| 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 21 DECLARE_FLAG(bool, inline_alloc); | 21 DECLARE_FLAG(bool, inline_alloc); |
| 22 | 22 |
| 23 | 23 |
| 24 Assembler::Assembler(bool use_far_branches) | 24 Assembler::Assembler(bool use_far_branches) |
| 25 : buffer_(), | 25 : buffer_(), |
| 26 prologue_offset_(-1), | 26 prologue_offset_(-1), |
| 27 comments_(), | 27 comments_(), |
| 28 allow_constant_pool_(true) { | 28 constant_pool_allowed_(true) { |
| 29 // Far branching mode is only needed and implemented for MIPS and ARM. | 29 // Far branching mode is only needed and implemented for MIPS and ARM. |
| 30 ASSERT(!use_far_branches); | 30 ASSERT(!use_far_branches); |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
| 35 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 35 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| 36 } | 36 } |
| 37 | 37 |
| 38 | 38 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 76 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 77 EmitRegisterREX(TMP, REX_W); | 77 EmitRegisterREX(TMP, REX_W); |
| 78 EmitUint8(0xB8 | (TMP & 7)); | 78 EmitUint8(0xB8 | (TMP & 7)); |
| 79 EmitInt64(label->address()); | 79 EmitInt64(label->address()); |
| 80 } | 80 } |
| 81 call(TMP); | 81 call(TMP); |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 void Assembler::CallPatchable(const ExternalLabel* label) { | 85 void Assembler::CallPatchable(const ExternalLabel* label) { |
| 86 ASSERT(allow_constant_pool()); | 86 ASSERT(constant_pool_allowed()); |
| 87 intptr_t call_start = buffer_.GetPosition(); | 87 intptr_t call_start = buffer_.GetPosition(); |
| 88 const int32_t offset = ObjectPool::element_offset( | 88 const int32_t offset = ObjectPool::element_offset( |
| 89 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 89 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); |
| 90 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); | 90 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
| 91 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 91 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 void Assembler::Call(const ExternalLabel* label, Register pp) { | 95 void Assembler::Call(const ExternalLabel* label, Register pp) { |
| 96 const int32_t offset = ObjectPool::element_offset( | 96 const int32_t offset = ObjectPool::element_offset( |
| (...skipping 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2592 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2592 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2593 EmitRegisterREX(TMP, REX_W); | 2593 EmitRegisterREX(TMP, REX_W); |
| 2594 EmitUint8(0xB8 | (TMP & 7)); | 2594 EmitUint8(0xB8 | (TMP & 7)); |
| 2595 EmitInt64(label->address()); | 2595 EmitInt64(label->address()); |
| 2596 } | 2596 } |
| 2597 jmp(TMP); | 2597 jmp(TMP); |
| 2598 } | 2598 } |
| 2599 | 2599 |
| 2600 | 2600 |
| 2601 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2601 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { |
| 2602 ASSERT(allow_constant_pool()); | 2602 ASSERT(constant_pool_allowed()); |
| 2603 intptr_t call_start = buffer_.GetPosition(); | 2603 intptr_t call_start = buffer_.GetPosition(); |
| 2604 const int32_t offset = ObjectPool::element_offset( | 2604 const int32_t offset = ObjectPool::element_offset( |
| 2605 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 2605 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); |
| 2606 // Patchable jumps always use a 32-bit immediate encoding. | 2606 // Patchable jumps always use a 32-bit immediate encoding. |
| 2607 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2607 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 2608 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); | 2608 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
| 2609 } | 2609 } |
| 2610 | 2610 |
| 2611 | 2611 |
| 2612 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2612 void Assembler::Jmp(const ExternalLabel* label, Register pp) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2763 popq(tmp); | 2763 popq(tmp); |
| 2764 } | 2764 } |
| 2765 return; | 2765 return; |
| 2766 } | 2766 } |
| 2767 addq(RSP, Immediate(stack_elements * kWordSize)); | 2767 addq(RSP, Immediate(stack_elements * kWordSize)); |
| 2768 } | 2768 } |
| 2769 | 2769 |
| 2770 | 2770 |
| 2771 bool Assembler::CanLoadFromObjectPool(const Object& object) const { | 2771 bool Assembler::CanLoadFromObjectPool(const Object& object) const { |
| 2772 ASSERT(!Thread::CanLoadFromThread(object)); | 2772 ASSERT(!Thread::CanLoadFromThread(object)); |
| 2773 if (!allow_constant_pool()) { | 2773 if (!constant_pool_allowed()) { |
| 2774 return false; | 2774 return false; |
| 2775 } | 2775 } |
| 2776 | 2776 |
| 2777 // TODO(zra, kmillikin): Also load other large immediates from the object | 2777 // TODO(zra, kmillikin): Also load other large immediates from the object |
| 2778 // pool | 2778 // pool |
| 2779 if (object.IsSmi()) { | 2779 if (object.IsSmi()) { |
| 2780 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 2780 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 2781 // the raw value in the object pool. | 2781 // the raw value in the object pool. |
| 2782 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 2782 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 2783 } | 2783 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2869 } | 2869 } |
| 2870 } | 2870 } |
| 2871 | 2871 |
| 2872 | 2872 |
| 2873 intptr_t Assembler::FindImmediate(int64_t imm) { | 2873 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 2874 return object_pool_wrapper_.FindImmediate(imm); | 2874 return object_pool_wrapper_.FindImmediate(imm); |
| 2875 } | 2875 } |
| 2876 | 2876 |
| 2877 | 2877 |
| 2878 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { | 2878 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { |
| 2879 if (!allow_constant_pool()) { | 2879 if (!constant_pool_allowed()) { |
| 2880 return false; | 2880 return false; |
| 2881 } | 2881 } |
| 2882 return !imm.is_int32() && (pp != kNoRegister); | 2882 return !imm.is_int32() && (pp != kNoRegister); |
| 2883 } | 2883 } |
| 2884 | 2884 |
| 2885 | 2885 |
| 2886 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) { | 2886 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) { |
| 2887 if (CanLoadImmediateFromPool(imm, pp)) { | 2887 if (CanLoadImmediateFromPool(imm, pp)) { |
| 2888 // It's a 64-bit constant and we're not in the VM isolate, so load from | 2888 // It's a 64-bit constant and we're not in the VM isolate, so load from |
| 2889 // object pool. | 2889 // object pool. |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3927 | 3927 |
| 3928 | 3928 |
| 3929 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3929 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3930 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3930 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3931 return xmm_reg_names[reg]; | 3931 return xmm_reg_names[reg]; |
| 3932 } | 3932 } |
| 3933 | 3933 |
| 3934 } // namespace dart | 3934 } // namespace dart |
| 3935 | 3935 |
| 3936 #endif // defined TARGET_ARCH_X64 | 3936 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |