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" | 5 #include "vm/globals.h" |
| 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/locations.h" | 11 #include "vm/locations.h" |
| 12 #include "vm/memory_region.h" | 12 #include "vm/memory_region.h" |
| 13 #include "vm/runtime_entry.h" | 13 #include "vm/runtime_entry.h" |
| 14 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
| 15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
| 16 | 16 |
| 17 namespace dart { | 17 namespace dart { |
| 18 | 18 |
| 19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 19 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 20 DECLARE_FLAG(bool, inline_alloc); | 20 DECLARE_FLAG(bool, inline_alloc); |
| 21 | 21 |
| 22 | 22 |
| 23 Assembler::Assembler(bool use_far_branches) | 23 Assembler::Assembler(bool use_far_branches) |
| 24 : buffer_(), | 24 : buffer_(), |
| 25 object_pool_(GrowableObjectArray::Handle()), | 25 object_pool_(GrowableObjectArray::Handle()), |
| 26 patchable_pool_entries_(), | 26 patchable_pool_entries_(), |
| 27 prologue_offset_(-1), | 27 prologue_offset_(-1), |
| 28 comments_() { | 28 comments_(), |
| 29 allow_constant_pool_(true) { | |
| 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. |
| 30 ASSERT(!use_far_branches); | 31 ASSERT(!use_far_branches); |
| 31 Isolate* isolate = Isolate::Current(); | 32 Isolate* isolate = Isolate::Current(); |
| 32 if (isolate != Dart::vm_isolate()) { | 33 if (isolate != Dart::vm_isolate()) { |
| 33 object_pool_ = GrowableObjectArray::New(Heap::kOld); | 34 object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| 34 | 35 |
| 35 // These objects and labels need to be accessible through every pool-pointer | 36 // These objects and labels need to be accessible through every pool-pointer |
| 36 // at the same index. | 37 // at the same index. |
| 37 object_pool_.Add(Object::null_object(), Heap::kOld); | 38 object_pool_.Add(Object::null_object(), Heap::kOld); |
| 38 patchable_pool_entries_.Add(kNotPatchable); | 39 patchable_pool_entries_.Add(kNotPatchable); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 142 EmitRegisterREX(TMP, REX_W); | 143 EmitRegisterREX(TMP, REX_W); |
| 143 EmitUint8(0xB8 | (TMP & 7)); | 144 EmitUint8(0xB8 | (TMP & 7)); |
| 144 EmitInt64(label->address()); | 145 EmitInt64(label->address()); |
| 145 } | 146 } |
| 146 call(TMP); | 147 call(TMP); |
| 147 } | 148 } |
| 148 | 149 |
| 149 | 150 |
| 150 void Assembler::CallPatchable(const ExternalLabel* label) { | 151 void Assembler::CallPatchable(const ExternalLabel* label) { |
| 151 intptr_t call_start = buffer_.GetPosition(); | 152 intptr_t call_start = buffer_.GetPosition(); |
|
zra
2014/09/05 20:26:49
ASSERT that the constant pool is enabled, o/w this
Florian Schneider
2014/09/08 11:12:39
Done.
| |
| 152 LoadExternalLabel(TMP, label, kPatchable, PP); | 153 LoadExternalLabel(TMP, label, kPatchable, PP); |
| 153 call(TMP); | 154 call(TMP); |
| 154 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 155 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 155 } | 156 } |
| 156 | 157 |
| 157 | 158 |
| 158 void Assembler::Call(const ExternalLabel* label, Register pp) { | 159 void Assembler::Call(const ExternalLabel* label, Register pp) { |
| 159 if (Isolate::Current() == Dart::vm_isolate()) { | 160 if (Isolate::Current() == Dart::vm_isolate()) { |
| 160 call(label); | 161 call(label); |
| 161 } else { | 162 } else { |
| (...skipping 2199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2361 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2362 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2362 EmitRegisterREX(TMP, REX_W); | 2363 EmitRegisterREX(TMP, REX_W); |
| 2363 EmitUint8(0xB8 | (TMP & 7)); | 2364 EmitUint8(0xB8 | (TMP & 7)); |
| 2364 EmitInt64(label->address()); | 2365 EmitInt64(label->address()); |
| 2365 } | 2366 } |
| 2366 jmp(TMP); | 2367 jmp(TMP); |
| 2367 } | 2368 } |
| 2368 | 2369 |
| 2369 | 2370 |
| 2370 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2371 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { |
| 2371 intptr_t call_start = buffer_.GetPosition(); | 2372 intptr_t call_start = buffer_.GetPosition(); |
|
zra
2014/09/05 20:26:49
Assert that the constant pool is enabled, o/w this
Florian Schneider
2014/09/08 11:12:39
Done.
| |
| 2372 LoadExternalLabel(TMP, label, kPatchable, pp); | 2373 LoadExternalLabel(TMP, label, kPatchable, pp); |
| 2373 jmp(TMP); | 2374 jmp(TMP); |
| 2374 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 2375 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 2375 } | 2376 } |
| 2376 | 2377 |
| 2377 | 2378 |
| 2378 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2379 void Assembler::Jmp(const ExternalLabel* label, Register pp) { |
| 2379 LoadExternalLabel(TMP, label, kNotPatchable, pp); | 2380 LoadExternalLabel(TMP, label, kNotPatchable, pp); |
| 2380 jmp(TMP); | 2381 jmp(TMP); |
| 2381 } | 2382 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2582 } | 2583 } |
| 2583 // If the call is patchable, do not reuse an existing entry since each | 2584 // If the call is patchable, do not reuse an existing entry since each |
| 2584 // reference may be patched independently. | 2585 // reference may be patched independently. |
| 2585 object_pool_.Add(smi, Heap::kOld); | 2586 object_pool_.Add(smi, Heap::kOld); |
| 2586 patchable_pool_entries_.Add(patchable); | 2587 patchable_pool_entries_.Add(patchable); |
| 2587 return object_pool_.Length() - 1; | 2588 return object_pool_.Length() - 1; |
| 2588 } | 2589 } |
| 2589 | 2590 |
| 2590 | 2591 |
| 2591 bool Assembler::CanLoadFromObjectPool(const Object& object) { | 2592 bool Assembler::CanLoadFromObjectPool(const Object& object) { |
| 2593 if (!allow_constant_pool()) return false; | |
|
zra
2014/09/05 20:26:49
Please use curly braces.
Also, Null, True, and Fa
Florian Schneider
2014/09/08 11:12:39
What about the case of an intrinsified function di
Florian Schneider
2014/09/08 11:13:56
Never mind. For the set of VM objects it still wor
| |
| 2594 | |
| 2592 // TODO(zra, kmillikin): Also load other large immediates from the object | 2595 // TODO(zra, kmillikin): Also load other large immediates from the object |
| 2593 // pool | 2596 // pool |
| 2594 if (object.IsSmi()) { | 2597 if (object.IsSmi()) { |
| 2595 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 2598 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 2596 // the raw value in the object pool. | 2599 // the raw value in the object pool. |
| 2597 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 2600 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 2598 } | 2601 } |
| 2599 ASSERT(object.IsNotTemporaryScopedHandle()); | 2602 ASSERT(object.IsNotTemporaryScopedHandle()); |
| 2600 ASSERT(object.IsOld()); | 2603 ASSERT(object.IsOld()); |
| 2601 return (Isolate::Current() != Dart::vm_isolate()) && | 2604 return (Isolate::Current() != Dart::vm_isolate()) && |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2665 | 2668 |
| 2666 intptr_t Assembler::FindImmediate(int64_t imm) { | 2669 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 2667 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 2670 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| 2668 ASSERT(!object_pool_.IsNull()); | 2671 ASSERT(!object_pool_.IsNull()); |
| 2669 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); | 2672 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); |
| 2670 return FindObject(smi, kNotPatchable); | 2673 return FindObject(smi, kNotPatchable); |
| 2671 } | 2674 } |
| 2672 | 2675 |
| 2673 | 2676 |
| 2674 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { | 2677 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { |
| 2678 if (!allow_constant_pool()) return false; | |
|
zra
2014/09/05 20:26:50
Please use curly braces.
Florian Schneider
2014/09/08 11:12:39
Done.
| |
| 2675 return !imm.is_int32() && | 2679 return !imm.is_int32() && |
| 2676 (pp != kNoRegister) && | 2680 (pp != kNoRegister) && |
| 2677 (Isolate::Current() != Dart::vm_isolate()); | 2681 (Isolate::Current() != Dart::vm_isolate()); |
| 2678 } | 2682 } |
| 2679 | 2683 |
| 2680 | 2684 |
| 2681 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) { | 2685 void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) { |
| 2682 if (CanLoadImmediateFromPool(imm, pp)) { | 2686 if (CanLoadImmediateFromPool(imm, pp)) { |
| 2683 // It's a 64-bit constant and we're not in the VM isolate, so load from | 2687 // It's a 64-bit constant and we're not in the VM isolate, so load from |
| 2684 // object pool. | 2688 // object pool. |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3523 | 3527 |
| 3524 | 3528 |
| 3525 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3529 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3526 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3530 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3527 return xmm_reg_names[reg]; | 3531 return xmm_reg_names[reg]; |
| 3528 } | 3532 } |
| 3529 | 3533 |
| 3530 } // namespace dart | 3534 } // namespace dart |
| 3531 | 3535 |
| 3532 #endif // defined TARGET_ARCH_X64 | 3536 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |