| 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" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 EmitRegisterREX(TMP, REX_W); | 76 EmitRegisterREX(TMP, REX_W); |
| 77 EmitUint8(0xB8 | (TMP & 7)); | 77 EmitUint8(0xB8 | (TMP & 7)); |
| 78 EmitInt64(label->address()); | 78 EmitInt64(label->address()); |
| 79 } | 79 } |
| 80 call(TMP); | 80 call(TMP); |
| 81 } | 81 } |
| 82 | 82 |
| 83 | 83 |
| 84 void Assembler::CallPatchable(const StubEntry& stub_entry) { | 84 void Assembler::CallPatchable(const StubEntry& stub_entry) { |
| 85 ASSERT(constant_pool_allowed()); | 85 ASSERT(constant_pool_allowed()); |
| 86 const Code& target = Code::Handle(stub_entry.code()); | 86 const Code& target = Code::ZoneHandle(stub_entry.code()); |
| 87 intptr_t call_start = buffer_.GetPosition(); | 87 intptr_t call_start = buffer_.GetPosition(); |
| 88 const int32_t offset = ObjectPool::element_offset( | 88 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable); |
| 89 object_pool_wrapper_.FindObject(target, kPatchable)); | 89 const int32_t offset = ObjectPool::element_offset(idx); |
| 90 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); | 90 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); |
| 91 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); | 91 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 92 call(TMP); | 92 call(TMP); |
| 93 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 93 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 void Assembler::CallWithEquivalence(const StubEntry& stub_entry, | 97 void Assembler::CallWithEquivalence(const StubEntry& stub_entry, |
| 98 const Object& equivalence) { | 98 const Object& equivalence) { |
| 99 ASSERT(constant_pool_allowed()); | 99 ASSERT(constant_pool_allowed()); |
| 100 const Code& target = Code::Handle(stub_entry.code()); | 100 const Code& target = Code::ZoneHandle(stub_entry.code()); |
| 101 const int32_t offset = ObjectPool::element_offset( | 101 const intptr_t idx = object_pool_wrapper_.FindObject(target, equivalence); |
| 102 object_pool_wrapper_.FindObject(target, equivalence)); | 102 const int32_t offset = ObjectPool::element_offset(idx); |
| 103 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); | 103 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); |
| 104 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); | 104 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 105 call(TMP); | 105 call(TMP); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 void Assembler::Call(const StubEntry& stub_entry) { | 109 void Assembler::Call(const StubEntry& stub_entry) { |
| 110 ASSERT(constant_pool_allowed()); | 110 ASSERT(constant_pool_allowed()); |
| 111 const Code& target = Code::Handle(stub_entry.code()); | 111 const Code& target = Code::ZoneHandle(stub_entry.code()); |
| 112 const int32_t offset = ObjectPool::element_offset( | 112 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable); |
| 113 object_pool_wrapper_.FindObject(target, kNotPatchable)); | 113 const int32_t offset = ObjectPool::element_offset(idx); |
| 114 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); | 114 LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); |
| 115 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); | 115 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 116 call(TMP); | 116 call(TMP); |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 void Assembler::CallToRuntime() { | 120 void Assembler::CallToRuntime() { |
| 121 movq(TMP, Address(THR, Thread::call_to_runtime_entry_point_offset())); | 121 movq(TMP, Address(THR, Thread::call_to_runtime_entry_point_offset())); |
| 122 movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset())); | 122 movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset())); |
| 123 call(TMP); | 123 call(TMP); |
| (...skipping 2453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2577 EmitRegisterREX(TMP, REX_W); | 2577 EmitRegisterREX(TMP, REX_W); |
| 2578 EmitUint8(0xB8 | (TMP & 7)); | 2578 EmitUint8(0xB8 | (TMP & 7)); |
| 2579 EmitInt64(label->address()); | 2579 EmitInt64(label->address()); |
| 2580 } | 2580 } |
| 2581 jmp(TMP); | 2581 jmp(TMP); |
| 2582 } | 2582 } |
| 2583 | 2583 |
| 2584 | 2584 |
| 2585 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { | 2585 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { |
| 2586 ASSERT((pp != PP) || constant_pool_allowed()); | 2586 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2587 const Code& target = Code::Handle(stub_entry.code()); | 2587 const Code& target = Code::ZoneHandle(stub_entry.code()); |
| 2588 const int32_t offset = ObjectPool::element_offset( | 2588 const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable); |
| 2589 object_pool_wrapper_.FindObject(target, kPatchable)); | 2589 const int32_t offset = ObjectPool::element_offset(idx); |
| 2590 movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2590 movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 2591 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2591 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 2592 jmp(TMP); | 2592 jmp(TMP); |
| 2593 } | 2593 } |
| 2594 | 2594 |
| 2595 | 2595 |
| 2596 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) { | 2596 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) { |
| 2597 ASSERT((pp != PP) || constant_pool_allowed()); | 2597 ASSERT((pp != PP) || constant_pool_allowed()); |
| 2598 const Code& target = Code::Handle(stub_entry.code()); | 2598 const Code& target = Code::ZoneHandle(stub_entry.code()); |
| 2599 const int32_t offset = ObjectPool::element_offset( | 2599 const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable); |
| 2600 object_pool_wrapper_.FindObject(target, kNotPatchable)); | 2600 const int32_t offset = ObjectPool::element_offset(idx); |
| 2601 movq(CODE_REG, FieldAddress(pp, offset)); | 2601 movq(CODE_REG, FieldAddress(pp, offset)); |
| 2602 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); | 2602 movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
| 2603 jmp(TMP); | 2603 jmp(TMP); |
| 2604 } | 2604 } |
| 2605 | 2605 |
| 2606 | 2606 |
| 2607 void Assembler::lock() { | 2607 void Assembler::lock() { |
| 2608 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2608 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2609 EmitUint8(0xF0); | 2609 EmitUint8(0xF0); |
| 2610 } | 2610 } |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2790 | 2790 |
| 2791 | 2791 |
| 2792 void Assembler::LoadObjectHelper(Register dst, | 2792 void Assembler::LoadObjectHelper(Register dst, |
| 2793 const Object& object, | 2793 const Object& object, |
| 2794 bool is_unique) { | 2794 bool is_unique) { |
| 2795 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 2795 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
| 2796 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 2796 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
| 2797 if (Thread::CanLoadFromThread(object)) { | 2797 if (Thread::CanLoadFromThread(object)) { |
| 2798 movq(dst, Address(THR, Thread::OffsetFromThread(object))); | 2798 movq(dst, Address(THR, Thread::OffsetFromThread(object))); |
| 2799 } else if (CanLoadFromObjectPool(object)) { | 2799 } else if (CanLoadFromObjectPool(object)) { |
| 2800 const int32_t offset = ObjectPool::element_offset( | 2800 const intptr_t idx = |
| 2801 is_unique ? object_pool_wrapper_.AddObject(object) | 2801 is_unique ? object_pool_wrapper_.AddObject(object) |
| 2802 : object_pool_wrapper_.FindObject(object)); | 2802 : object_pool_wrapper_.FindObject(object); |
| 2803 const int32_t offset = ObjectPool::element_offset(idx); |
| 2803 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); | 2804 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); |
| 2804 } else { | 2805 } else { |
| 2805 ASSERT(object.IsSmi() || object.InVMHeap()); | 2806 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 2806 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); | 2807 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2807 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2808 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2808 } | 2809 } |
| 2809 } | 2810 } |
| 2810 | 2811 |
| 2811 | 2812 |
| 2812 void Assembler::LoadFunctionFromCalleePool(Register dst, | 2813 void Assembler::LoadFunctionFromCalleePool(Register dst, |
| 2813 const Function& function, | 2814 const Function& function, |
| 2814 Register new_pp) { | 2815 Register new_pp) { |
| 2815 ASSERT(!constant_pool_allowed()); | 2816 ASSERT(!constant_pool_allowed()); |
| 2816 ASSERT(new_pp != PP); | 2817 ASSERT(new_pp != PP); |
| 2817 const int32_t offset = | 2818 const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable); |
| 2818 ObjectPool::element_offset(object_pool_wrapper_.FindObject(function)); | 2819 const int32_t offset = ObjectPool::element_offset(idx); |
| 2819 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag)); | 2820 movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag)); |
| 2820 } | 2821 } |
| 2821 | 2822 |
| 2822 | 2823 |
| 2823 void Assembler::LoadObject(Register dst, const Object& object) { | 2824 void Assembler::LoadObject(Register dst, const Object& object) { |
| 2824 LoadObjectHelper(dst, object, false); | 2825 LoadObjectHelper(dst, object, false); |
| 2825 } | 2826 } |
| 2826 | 2827 |
| 2827 | 2828 |
| 2828 void Assembler::LoadUniqueObject(Register dst, const Object& object) { | 2829 void Assembler::LoadUniqueObject(Register dst, const Object& object) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2860 } | 2861 } |
| 2861 } | 2862 } |
| 2862 | 2863 |
| 2863 | 2864 |
| 2864 void Assembler::CompareObject(Register reg, const Object& object) { | 2865 void Assembler::CompareObject(Register reg, const Object& object) { |
| 2865 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); | 2866 ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal()); |
| 2866 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); | 2867 ASSERT(!object.IsField() || Field::Cast(object).IsOriginal()); |
| 2867 if (Thread::CanLoadFromThread(object)) { | 2868 if (Thread::CanLoadFromThread(object)) { |
| 2868 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); | 2869 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); |
| 2869 } else if (CanLoadFromObjectPool(object)) { | 2870 } else if (CanLoadFromObjectPool(object)) { |
| 2870 const int32_t offset = | 2871 const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable); |
| 2871 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 2872 const int32_t offset = ObjectPool::element_offset(idx); |
| 2872 cmpq(reg, Address(PP, offset-kHeapObjectTag)); | 2873 cmpq(reg, Address(PP, offset-kHeapObjectTag)); |
| 2873 } else { | 2874 } else { |
| 2874 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); | 2875 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2875 CompareImmediate( | 2876 CompareImmediate( |
| 2876 reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2877 reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2877 } | 2878 } |
| 2878 } | 2879 } |
| 2879 | 2880 |
| 2880 | 2881 |
| 2881 intptr_t Assembler::FindImmediate(int64_t imm) { | 2882 intptr_t Assembler::FindImmediate(int64_t imm) { |
| (...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 | 3949 |
| 3949 | 3950 |
| 3950 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3951 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3951 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3952 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3952 return xmm_reg_names[reg]; | 3953 return xmm_reg_names[reg]; |
| 3953 } | 3954 } |
| 3954 | 3955 |
| 3955 } // namespace dart | 3956 } // namespace dart |
| 3956 | 3957 |
| 3957 #endif // defined TARGET_ARCH_X64 | 3958 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |