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 |