| 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 DECLARE_FLAG(bool, allow_absolute_addresses); |
| 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 21 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 21 DECLARE_FLAG(bool, inline_alloc); | 22 DECLARE_FLAG(bool, inline_alloc); |
| 22 | 23 |
| 23 | 24 |
| 24 Assembler::Assembler(bool use_far_branches) | 25 Assembler::Assembler(bool use_far_branches) |
| 25 : buffer_(), | 26 : buffer_(), |
| 26 prologue_offset_(-1), | 27 prologue_offset_(-1), |
| 27 comments_(), | 28 comments_(), |
| 28 constant_pool_allowed_(false) { | 29 constant_pool_allowed_(false) { |
| 29 // Far branching mode is only needed and implemented for MIPS and ARM. | 30 // Far branching mode is only needed and implemented for MIPS and ARM. |
| (...skipping 2790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2820 bool is_unique) { | 2821 bool is_unique) { |
| 2821 if (Thread::CanLoadFromThread(object)) { | 2822 if (Thread::CanLoadFromThread(object)) { |
| 2822 movq(dst, Address(THR, Thread::OffsetFromThread(object))); | 2823 movq(dst, Address(THR, Thread::OffsetFromThread(object))); |
| 2823 } else if (CanLoadFromObjectPool(object)) { | 2824 } else if (CanLoadFromObjectPool(object)) { |
| 2824 const int32_t offset = ObjectPool::element_offset( | 2825 const int32_t offset = ObjectPool::element_offset( |
| 2825 is_unique ? object_pool_wrapper_.AddObject(object) | 2826 is_unique ? object_pool_wrapper_.AddObject(object) |
| 2826 : object_pool_wrapper_.FindObject(object)); | 2827 : object_pool_wrapper_.FindObject(object)); |
| 2827 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); | 2828 LoadWordFromPoolOffset(dst, offset - kHeapObjectTag); |
| 2828 } else { | 2829 } else { |
| 2829 ASSERT(object.IsSmi() || object.InVMHeap()); | 2830 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 2831 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2830 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2832 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2831 } | 2833 } |
| 2832 } | 2834 } |
| 2833 | 2835 |
| 2834 | 2836 |
| 2835 void Assembler::LoadFunctionFromCalleePool(Register dst, | 2837 void Assembler::LoadFunctionFromCalleePool(Register dst, |
| 2836 const Function& function, | 2838 const Function& function, |
| 2837 Register new_pp) { | 2839 Register new_pp) { |
| 2838 ASSERT(!constant_pool_allowed()); | 2840 ASSERT(!constant_pool_allowed()); |
| 2839 ASSERT(new_pp != PP); | 2841 ASSERT(new_pp != PP); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2854 | 2856 |
| 2855 | 2857 |
| 2856 void Assembler::StoreObject(const Address& dst, const Object& object) { | 2858 void Assembler::StoreObject(const Address& dst, const Object& object) { |
| 2857 if (Thread::CanLoadFromThread(object)) { | 2859 if (Thread::CanLoadFromThread(object)) { |
| 2858 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); | 2860 movq(TMP, Address(THR, Thread::OffsetFromThread(object))); |
| 2859 movq(dst, TMP); | 2861 movq(dst, TMP); |
| 2860 } else if (CanLoadFromObjectPool(object)) { | 2862 } else if (CanLoadFromObjectPool(object)) { |
| 2861 LoadObject(TMP, object); | 2863 LoadObject(TMP, object); |
| 2862 movq(dst, TMP); | 2864 movq(dst, TMP); |
| 2863 } else { | 2865 } else { |
| 2866 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2864 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2867 MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2865 } | 2868 } |
| 2866 } | 2869 } |
| 2867 | 2870 |
| 2868 | 2871 |
| 2869 void Assembler::PushObject(const Object& object) { | 2872 void Assembler::PushObject(const Object& object) { |
| 2870 if (Thread::CanLoadFromThread(object)) { | 2873 if (Thread::CanLoadFromThread(object)) { |
| 2871 pushq(Address(THR, Thread::OffsetFromThread(object))); | 2874 pushq(Address(THR, Thread::OffsetFromThread(object))); |
| 2872 } else if (CanLoadFromObjectPool(object)) { | 2875 } else if (CanLoadFromObjectPool(object)) { |
| 2873 LoadObject(TMP, object); | 2876 LoadObject(TMP, object); |
| 2874 pushq(TMP); | 2877 pushq(TMP); |
| 2875 } else { | 2878 } else { |
| 2879 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2876 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2880 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2877 } | 2881 } |
| 2878 } | 2882 } |
| 2879 | 2883 |
| 2880 | 2884 |
| 2881 void Assembler::CompareObject(Register reg, const Object& object) { | 2885 void Assembler::CompareObject(Register reg, const Object& object) { |
| 2882 if (Thread::CanLoadFromThread(object)) { | 2886 if (Thread::CanLoadFromThread(object)) { |
| 2883 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); | 2887 cmpq(reg, Address(THR, Thread::OffsetFromThread(object))); |
| 2884 } else if (CanLoadFromObjectPool(object)) { | 2888 } else if (CanLoadFromObjectPool(object)) { |
| 2885 const int32_t offset = | 2889 const int32_t offset = |
| 2886 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); | 2890 ObjectPool::element_offset(object_pool_wrapper_.FindObject(object)); |
| 2887 cmpq(reg, Address(PP, offset-kHeapObjectTag)); | 2891 cmpq(reg, Address(PP, offset-kHeapObjectTag)); |
| 2888 } else { | 2892 } else { |
| 2893 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 2889 CompareImmediate( | 2894 CompareImmediate( |
| 2890 reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); | 2895 reg, Immediate(reinterpret_cast<int64_t>(object.raw()))); |
| 2891 } | 2896 } |
| 2892 } | 2897 } |
| 2893 | 2898 |
| 2894 | 2899 |
| 2895 intptr_t Assembler::FindImmediate(int64_t imm) { | 2900 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 2896 return object_pool_wrapper_.FindImmediate(imm); | 2901 return object_pool_wrapper_.FindImmediate(imm); |
| 2897 } | 2902 } |
| 2898 | 2903 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3028 Label ok; | 3033 Label ok; |
| 3029 testb(dest, Immediate(kHeapObjectTag)); | 3034 testb(dest, Immediate(kHeapObjectTag)); |
| 3030 j(ZERO, &ok, Assembler::kNearJump); | 3035 j(ZERO, &ok, Assembler::kNearJump); |
| 3031 // Non-smi case: Check for the special zap word or null. | 3036 // Non-smi case: Check for the special zap word or null. |
| 3032 #if defined(DEBUG) | 3037 #if defined(DEBUG) |
| 3033 cmpq(dest, Immediate(Heap::kZap64Bits)); | 3038 cmpq(dest, Immediate(Heap::kZap64Bits)); |
| 3034 j(EQUAL, &ok, Assembler::kNearJump); | 3039 j(EQUAL, &ok, Assembler::kNearJump); |
| 3035 #else | 3040 #else |
| 3036 #error Only supported in DEBUG mode | 3041 #error Only supported in DEBUG mode |
| 3037 #endif | 3042 #endif |
| 3038 cmpq(dest, Immediate(reinterpret_cast<uint64_t>(Object::null()))); | 3043 LoadObject(TMP, Object::null_object()); |
| 3044 cmpq(dest, TMP); |
| 3039 j(EQUAL, &ok, Assembler::kNearJump); | 3045 j(EQUAL, &ok, Assembler::kNearJump); |
| 3040 static const bool kFixedLengthEncoding = true; | 3046 static const bool kFixedLengthEncoding = true; |
| 3041 Stop("Expected zapped, Smi or null", kFixedLengthEncoding); | 3047 Stop("Expected zapped, Smi or null", kFixedLengthEncoding); |
| 3042 Bind(&ok); | 3048 Bind(&ok); |
| 3043 } | 3049 } |
| 3044 | 3050 |
| 3045 | 3051 |
| 3046 void Assembler::VerifySmi(const Address& dest, const char* stop_msg) { | 3052 void Assembler::VerifySmi(const Address& dest, const char* stop_msg) { |
| 3047 Label done; | 3053 Label done; |
| 3048 testb(dest, Immediate(kHeapObjectTag)); | 3054 testb(dest, Immediate(kHeapObjectTag)); |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3446 | 3452 |
| 3447 | 3453 |
| 3448 void Assembler::MaybeTraceAllocation(intptr_t cid, | 3454 void Assembler::MaybeTraceAllocation(intptr_t cid, |
| 3449 Label* trace, | 3455 Label* trace, |
| 3450 bool near_jump, | 3456 bool near_jump, |
| 3451 bool inline_isolate) { | 3457 bool inline_isolate) { |
| 3452 ASSERT(cid > 0); | 3458 ASSERT(cid > 0); |
| 3453 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 3459 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
| 3454 Register temp_reg = TMP; | 3460 Register temp_reg = TMP; |
| 3455 if (inline_isolate) { | 3461 if (inline_isolate) { |
| 3462 ASSERT(FLAG_allow_absolute_addresses); |
| 3456 ClassTable* class_table = Isolate::Current()->class_table(); | 3463 ClassTable* class_table = Isolate::Current()->class_table(); |
| 3457 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 3464 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
| 3458 if (cid < kNumPredefinedCids) { | 3465 if (cid < kNumPredefinedCids) { |
| 3459 movq(temp_reg, Immediate(reinterpret_cast<uword>(*table_ptr))); | 3466 movq(temp_reg, Immediate(reinterpret_cast<uword>(*table_ptr))); |
| 3460 } else { | 3467 } else { |
| 3461 movq(temp_reg, Immediate(reinterpret_cast<uword>(table_ptr))); | 3468 movq(temp_reg, Immediate(reinterpret_cast<uword>(table_ptr))); |
| 3462 movq(temp_reg, Address(temp_reg, 0)); | 3469 movq(temp_reg, Address(temp_reg, 0)); |
| 3463 } | 3470 } |
| 3464 } else { | 3471 } else { |
| 3465 LoadIsolate(temp_reg); | 3472 LoadIsolate(temp_reg); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3476 | 3483 |
| 3477 | 3484 |
| 3478 void Assembler::UpdateAllocationStats(intptr_t cid, | 3485 void Assembler::UpdateAllocationStats(intptr_t cid, |
| 3479 Heap::Space space, | 3486 Heap::Space space, |
| 3480 bool inline_isolate) { | 3487 bool inline_isolate) { |
| 3481 ASSERT(cid > 0); | 3488 ASSERT(cid > 0); |
| 3482 intptr_t counter_offset = | 3489 intptr_t counter_offset = |
| 3483 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); | 3490 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); |
| 3484 Register temp_reg = TMP; | 3491 Register temp_reg = TMP; |
| 3485 if (inline_isolate) { | 3492 if (inline_isolate) { |
| 3493 ASSERT(FLAG_allow_absolute_addresses); |
| 3486 ClassTable* class_table = Isolate::Current()->class_table(); | 3494 ClassTable* class_table = Isolate::Current()->class_table(); |
| 3487 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 3495 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
| 3488 if (cid < kNumPredefinedCids) { | 3496 if (cid < kNumPredefinedCids) { |
| 3489 movq(temp_reg, Immediate(reinterpret_cast<uword>(*table_ptr))); | 3497 movq(temp_reg, Immediate(reinterpret_cast<uword>(*table_ptr))); |
| 3490 } else { | 3498 } else { |
| 3491 movq(temp_reg, Immediate(reinterpret_cast<uword>(table_ptr))); | 3499 movq(temp_reg, Immediate(reinterpret_cast<uword>(table_ptr))); |
| 3492 movq(temp_reg, Address(temp_reg, 0)); | 3500 movq(temp_reg, Address(temp_reg, 0)); |
| 3493 } | 3501 } |
| 3494 } else { | 3502 } else { |
| 3495 LoadIsolate(temp_reg); | 3503 LoadIsolate(temp_reg); |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3936 | 3944 |
| 3937 | 3945 |
| 3938 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3946 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3939 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3947 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3940 return xmm_reg_names[reg]; | 3948 return xmm_reg_names[reg]; |
| 3941 } | 3949 } |
| 3942 | 3950 |
| 3943 } // namespace dart | 3951 } // namespace dart |
| 3944 | 3952 |
| 3945 #endif // defined TARGET_ARCH_X64 | 3953 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |