Chromium Code Reviews| 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 10 matching lines...) Expand all Loading... | |
| 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 allow_constant_pool_(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 Isolate* isolate = Isolate::Current(); | |
| 32 if (isolate != Dart::vm_isolate()) { | |
| 33 // These objects and labels need to be accessible through every pool-pointer | |
| 34 // at the same index. | |
| 35 intptr_t index = object_pool_wrapper_.AddObject(Object::null_object()); | |
| 36 ASSERT(index == 0); | |
| 37 | |
| 38 index = object_pool_wrapper_.AddObject(Bool::True()); | |
| 39 ASSERT(index == 1); | |
| 40 | |
| 41 index = object_pool_wrapper_.AddObject(Bool::False()); | |
| 42 ASSERT(index == 2); | |
| 43 | |
| 44 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); | |
| 45 StubCode* stub_code = isolate->stub_code(); | |
| 46 if (stub_code->UpdateStoreBuffer_entry() != NULL) { | |
| 47 object_pool_wrapper_.AddExternalLabel( | |
| 48 &stub_code->UpdateStoreBufferLabel(), kNotPatchable); | |
| 49 } else { | |
| 50 object_pool_wrapper_.AddObject(vacant); | |
| 51 } | |
| 52 } | |
| 53 } | 31 } |
| 54 | 32 |
| 55 | 33 |
| 56 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 34 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
| 57 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 35 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| 58 } | 36 } |
| 59 | 37 |
| 60 | 38 |
| 61 void Assembler::call(Register reg) { | 39 void Assembler::call(Register reg) { |
| 62 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 40 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| (...skipping 2724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2787 if (stack_elements <= 4) { | 2765 if (stack_elements <= 4) { |
| 2788 for (intptr_t i = 0; i < stack_elements; i++) { | 2766 for (intptr_t i = 0; i < stack_elements; i++) { |
| 2789 popq(tmp); | 2767 popq(tmp); |
| 2790 } | 2768 } |
| 2791 return; | 2769 return; |
| 2792 } | 2770 } |
| 2793 addq(RSP, Immediate(stack_elements * kWordSize)); | 2771 addq(RSP, Immediate(stack_elements * kWordSize)); |
| 2794 } | 2772 } |
| 2795 | 2773 |
| 2796 | 2774 |
| 2797 // A set of VM objects that are present in every constant pool. | |
| 2798 static bool IsAlwaysInConstantPool(const Object& object) { | |
| 2799 // TODO(zra): Evaluate putting all VM heap objects into the pool. | |
| 2800 return (object.raw() == Object::null()) | |
| 2801 || (object.raw() == Bool::True().raw()) | |
| 2802 || (object.raw() == Bool::False().raw()); | |
| 2803 } | |
| 2804 | |
| 2805 | |
| 2806 bool Assembler::CanLoadFromObjectPool(const Object& object) { | 2775 bool Assembler::CanLoadFromObjectPool(const Object& object) { |
|
srdjan
2015/07/07 16:58:27
const
Florian Schneider
2015/07/08 09:28:09
Done.
| |
| 2776 ASSERT(!Thread::CanLoadFromThread(object)); | |
| 2807 if (!allow_constant_pool()) { | 2777 if (!allow_constant_pool()) { |
| 2808 return IsAlwaysInConstantPool(object); | 2778 return false; |
| 2809 } | 2779 } |
| 2810 | 2780 |
| 2811 // TODO(zra, kmillikin): Also load other large immediates from the object | 2781 // TODO(zra, kmillikin): Also load other large immediates from the object |
| 2812 // pool | 2782 // pool |
| 2813 if (object.IsSmi()) { | 2783 if (object.IsSmi()) { |
| 2814 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 2784 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 2815 // the raw value in the object pool. | 2785 // the raw value in the object pool. |
| 2816 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 2786 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 2817 } | 2787 } |
| 2818 ASSERT(object.IsNotTemporaryScopedHandle()); | 2788 ASSERT(object.IsNotTemporaryScopedHandle()); |
| 2819 ASSERT(object.IsOld()); | 2789 ASSERT(object.IsOld()); |
| 2820 return (Isolate::Current() != Dart::vm_isolate()); | 2790 return (Isolate::Current() != Dart::vm_isolate()); |
| 2821 } | 2791 } |
| 2822 | 2792 |
| 2823 | 2793 |
| 2824 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp, | 2794 void Assembler::LoadWordFromPoolOffset(Register dst, Register pp, |
| 2825 int32_t offset) { | 2795 int32_t offset) { |
| 2826 // This sequence must be of fixed size. AddressBaseImm32 | 2796 // This sequence must be of fixed size. AddressBaseImm32 |
| 2827 // forces the address operand to use a fixed-size imm32 encoding. | 2797 // forces the address operand to use a fixed-size imm32 encoding. |
| 2828 movq(dst, Address::AddressBaseImm32(pp, offset)); | 2798 movq(dst, Address::AddressBaseImm32(pp, offset)); |
| 2829 } | 2799 } |
| 2830 | 2800 |
| 2831 | 2801 |
| 2832 void Assembler::LoadIsolate(Register dst) { | 2802 void Assembler::LoadIsolate(Register dst) { |
| 2833 movq(dst, Address(THR, Thread::isolate_offset())); | 2803 movq(dst, Address(THR, Thread::isolate_offset())); |
| 2834 } | 2804 } |
| 2835 | 2805 |
| 2836 | 2806 |
| 2837 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { | 2807 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { |
| 2838 if (CanLoadFromObjectPool(object)) { | 2808 if (Thread::CanLoadFromThread(object)) { |
| 2809 movq(dst, Address(THR, Thread::OffsetFromThread(object))); | |
| 2810 } else if (CanLoadFromObjectPool(object)) { | |
| 2839 const int32_t offset = | 2811 const int32_t offset = |
| 2840 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 2812 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); |
| 2841 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); | 2813 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); |
| 2842 } else { | 2814 } else { |
| 2843 ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 2815 ASSERT((Isolate::Current() == Dart::vm_isolate()) || |
| 2844 object.IsSmi() || | 2816 object.IsSmi() || |
| 2845 object.InVMHeap()); | 2817 object.InVMHeap()); |
| 2846 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2818 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2847 } | 2819 } |
| 2848 } | 2820 } |
| 2849 | 2821 |
| 2850 | 2822 |
| 2851 void Assembler::StoreObject(const Address& dst, const Object& object, | 2823 void Assembler::StoreObject(const Address& dst, const Object& object, |
| 2852 Register pp) { | 2824 Register pp) { |
| 2853 if (CanLoadFromObjectPool(object)) { | 2825 if (Thread::CanLoadFromThread(object)) { |
| 2826 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); | |
| 2827 movq(dst, TMP); | |
| 2828 } else if (CanLoadFromObjectPool(object)) { | |
| 2854 LoadObject(TMP, object, pp); | 2829 LoadObject(TMP, object, pp); |
| 2855 movq(dst, TMP); | 2830 movq(dst, TMP); |
| 2856 } else { | 2831 } else { |
| 2857 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2832 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2858 } | 2833 } |
| 2859 } | 2834 } |
| 2860 | 2835 |
| 2861 | 2836 |
| 2862 void Assembler::PushObject(const Object& object, Register pp) { | 2837 void Assembler::PushObject(const Object& object, Register pp) { |
| 2863 if (CanLoadFromObjectPool(object)) { | 2838 if (Thread::CanLoadFromThread(object)) { |
| 2839 pushq(Address(THR, Thread::OffsetFromThread(object))); | |
| 2840 } else if (CanLoadFromObjectPool(object)) { | |
| 2864 LoadObject(TMP, object, pp); | 2841 LoadObject(TMP, object, pp); |
| 2865 pushq(TMP); | 2842 pushq(TMP); |
| 2866 } else { | 2843 } else { |
| 2867 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2844 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2868 } | 2845 } |
| 2869 } | 2846 } |
| 2870 | 2847 |
| 2871 | 2848 |
| 2872 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { | 2849 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { |
| 2873 if (CanLoadFromObjectPool(object)) { | 2850 if (Thread::CanLoadFromThread(object)) { |
| 2851 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); | |
| 2852 } else if (CanLoadFromObjectPool(object)) { | |
| 2874 const int32_t offset = | 2853 const int32_t offset = |
| 2875 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 2854 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); |
| 2876 cmpq(reg, Address(pp, offset-kHeapObjectTag)); | 2855 cmpq(reg, Address(pp, offset-kHeapObjectTag)); |
| 2877 } else { | 2856 } else { |
| 2878 CompareImmediate( | 2857 CompareImmediate( |
| 2879 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2858 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2880 } | 2859 } |
| 2881 } | 2860 } |
| 2882 | 2861 |
| 2883 | 2862 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3067 if (can_value_be_smi) { | 3046 if (can_value_be_smi) { |
| 3068 StoreIntoObjectFilter(object, value, &done); | 3047 StoreIntoObjectFilter(object, value, &done); |
| 3069 } else { | 3048 } else { |
| 3070 StoreIntoObjectFilterNoSmi(object, value, &done); | 3049 StoreIntoObjectFilterNoSmi(object, value, &done); |
| 3071 } | 3050 } |
| 3072 // A store buffer update is required. | 3051 // A store buffer update is required. |
| 3073 if (value != RDX) pushq(RDX); | 3052 if (value != RDX) pushq(RDX); |
| 3074 if (object != RDX) { | 3053 if (object != RDX) { |
| 3075 movq(RDX, object); | 3054 movq(RDX, object); |
| 3076 } | 3055 } |
| 3077 StubCode* stub_code = Isolate::Current()->stub_code(); | 3056 movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset())); |
| 3078 Call(&stub_code->UpdateStoreBufferLabel(), PP); | 3057 call(TMP); |
| 3079 if (value != RDX) popq(RDX); | 3058 if (value != RDX) popq(RDX); |
| 3080 Bind(&done); | 3059 Bind(&done); |
| 3081 } | 3060 } |
| 3082 | 3061 |
| 3083 | 3062 |
| 3084 void Assembler::StoreIntoObjectNoBarrier(Register object, | 3063 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 3085 const Address& dest, | 3064 const Address& dest, |
| 3086 Register value, | 3065 Register value, |
| 3087 FieldContent old_content) { | 3066 FieldContent old_content) { |
| 3088 VerifiedWrite(dest, value, old_content); | 3067 VerifiedWrite(dest, value, old_content); |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3924 | 3903 |
| 3925 | 3904 |
| 3926 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3905 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3927 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3906 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3928 return xmm_reg_names[reg]; | 3907 return xmm_reg_names[reg]; |
| 3929 } | 3908 } |
| 3930 | 3909 |
| 3931 } // namespace dart | 3910 } // namespace dart |
| 3932 | 3911 |
| 3933 #endif // defined TARGET_ARCH_X64 | 3912 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |