| 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 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 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 object_pool_(GrowableObjectArray::Handle()), | |
| 27 patchable_pool_entries_(), | |
| 28 prologue_offset_(-1), | 26 prologue_offset_(-1), |
| 29 comments_(), | 27 comments_(), |
| 30 allow_constant_pool_(true) { | 28 allow_constant_pool_(true) { |
| 31 // 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. |
| 32 ASSERT(!use_far_branches); | 30 ASSERT(!use_far_branches); |
| 33 Isolate* isolate = Isolate::Current(); | 31 Isolate* isolate = Isolate::Current(); |
| 34 if (isolate != Dart::vm_isolate()) { | 32 if (isolate != Dart::vm_isolate()) { |
| 35 object_pool_ = GrowableObjectArray::New(Heap::kOld); | |
| 36 | |
| 37 // These objects and labels need to be accessible through every pool-pointer | 33 // These objects and labels need to be accessible through every pool-pointer |
| 38 // at the same index. | 34 // at the same index. |
| 39 object_pool_.Add(Object::null_object(), Heap::kOld); | 35 intptr_t index = |
| 40 patchable_pool_entries_.Add(kNotPatchable); | 36 object_pool_.AddObject(Object::null_object(), kNotPatchable); |
| 41 object_pool_index_table_.Insert(ObjIndexPair(&Object::null_object(), 0)); | 37 ASSERT(index == 0); |
| 42 | 38 |
| 43 object_pool_.Add(Bool::True(), Heap::kOld); | 39 index = object_pool_.AddObject(Bool::True(), kNotPatchable); |
| 44 patchable_pool_entries_.Add(kNotPatchable); | 40 ASSERT(index == 1); |
| 45 object_pool_index_table_.Insert(ObjIndexPair(&Bool::True(), 1)); | |
| 46 | 41 |
| 47 object_pool_.Add(Bool::False(), Heap::kOld); | 42 index = object_pool_.AddObject(Bool::False(), kNotPatchable); |
| 48 patchable_pool_entries_.Add(kNotPatchable); | 43 ASSERT(index == 2); |
| 49 object_pool_index_table_.Insert(ObjIndexPair(&Bool::False(), 2)); | |
| 50 | 44 |
| 51 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); | 45 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); |
| 52 | |
| 53 StubCode* stub_code = isolate->stub_code(); | 46 StubCode* stub_code = isolate->stub_code(); |
| 54 if (stub_code->UpdateStoreBuffer_entry() != NULL) { | 47 if (stub_code->UpdateStoreBuffer_entry() != NULL) { |
| 55 FindExternalLabel(&stub_code->UpdateStoreBufferLabel(), kNotPatchable); | 48 object_pool_.AddExternalLabel(&stub_code->UpdateStoreBufferLabel(), |
| 49 kNotPatchable); |
| 56 } else { | 50 } else { |
| 57 object_pool_.Add(vacant, Heap::kOld); | 51 object_pool_.AddObject(vacant, kNotPatchable); |
| 58 patchable_pool_entries_.Add(kNotPatchable); | |
| 59 } | 52 } |
| 60 | 53 |
| 61 if (stub_code->CallToRuntime_entry() != NULL) { | 54 if (stub_code->CallToRuntime_entry() != NULL) { |
| 62 FindExternalLabel(&stub_code->CallToRuntimeLabel(), kNotPatchable); | 55 object_pool_.AddExternalLabel(&stub_code->CallToRuntimeLabel(), |
| 56 kNotPatchable); |
| 63 } else { | 57 } else { |
| 64 object_pool_.Add(vacant, Heap::kOld); | 58 object_pool_.AddObject(vacant, kNotPatchable); |
| 65 patchable_pool_entries_.Add(kNotPatchable); | |
| 66 } | 59 } |
| 67 | 60 |
| 68 // Create fixed object pool entries for debugger stubs. | 61 // Create fixed object pool entries for debugger stubs. |
| 69 if (stub_code->ICCallBreakpoint_entry() != NULL) { | 62 if (stub_code->ICCallBreakpoint_entry() != NULL) { |
| 70 intptr_t index = | 63 index = object_pool_.AddExternalLabel( |
| 71 FindExternalLabel(&stub_code->ICCallBreakpointLabel(), | 64 &stub_code->ICCallBreakpointLabel(), kNotPatchable); |
| 72 kNotPatchable); | |
| 73 ASSERT(index == kICCallBreakpointCPIndex); | 65 ASSERT(index == kICCallBreakpointCPIndex); |
| 74 } else { | 66 } else { |
| 75 object_pool_.Add(vacant, Heap::kOld); | 67 object_pool_.AddObject(vacant, kNotPatchable); |
| 76 patchable_pool_entries_.Add(kNotPatchable); | |
| 77 } | 68 } |
| 78 if (stub_code->ClosureCallBreakpoint_entry() != NULL) { | 69 if (stub_code->ClosureCallBreakpoint_entry() != NULL) { |
| 79 intptr_t index = | 70 index = object_pool_.AddExternalLabel( |
| 80 FindExternalLabel(&stub_code->ClosureCallBreakpointLabel(), | 71 &stub_code->ClosureCallBreakpointLabel(), kNotPatchable); |
| 81 kNotPatchable); | |
| 82 ASSERT(index == kClosureCallBreakpointCPIndex); | 72 ASSERT(index == kClosureCallBreakpointCPIndex); |
| 83 } else { | 73 } else { |
| 84 object_pool_.Add(vacant, Heap::kOld); | 74 object_pool_.AddObject(vacant, kNotPatchable); |
| 85 patchable_pool_entries_.Add(kNotPatchable); | |
| 86 } | 75 } |
| 87 if (stub_code->RuntimeCallBreakpoint_entry() != NULL) { | 76 if (stub_code->RuntimeCallBreakpoint_entry() != NULL) { |
| 88 intptr_t index = | 77 index = object_pool_.AddExternalLabel( |
| 89 FindExternalLabel(&stub_code->RuntimeCallBreakpointLabel(), | 78 &stub_code->RuntimeCallBreakpointLabel(), kNotPatchable); |
| 90 kNotPatchable); | |
| 91 ASSERT(index == kRuntimeCallBreakpointCPIndex); | 79 ASSERT(index == kRuntimeCallBreakpointCPIndex); |
| 92 } else { | 80 } else { |
| 93 object_pool_.Add(vacant, Heap::kOld); | 81 object_pool_.AddObject(vacant, kNotPatchable); |
| 94 patchable_pool_entries_.Add(kNotPatchable); | |
| 95 } | 82 } |
| 96 } | 83 } |
| 97 } | 84 } |
| 98 | 85 |
| 99 | 86 |
| 100 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 87 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
| 101 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 88 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| 102 } | 89 } |
| 103 | 90 |
| 104 | 91 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 125 EmitUint8(0xE8); | 112 EmitUint8(0xE8); |
| 126 EmitLabel(label, kSize); | 113 EmitLabel(label, kSize); |
| 127 } | 114 } |
| 128 | 115 |
| 129 | 116 |
| 130 void Assembler::LoadExternalLabel(Register dst, | 117 void Assembler::LoadExternalLabel(Register dst, |
| 131 const ExternalLabel* label, | 118 const ExternalLabel* label, |
| 132 Patchability patchable, | 119 Patchability patchable, |
| 133 Register pp) { | 120 Register pp) { |
| 134 const int32_t offset = | 121 const int32_t offset = |
| 135 Array::element_offset(FindExternalLabel(label, patchable)); | 122 Array::element_offset(object_pool_.FindExternalLabel(label, patchable)); |
| 136 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); | 123 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); |
| 137 } | 124 } |
| 138 | 125 |
| 139 | 126 |
| 140 void Assembler::call(const ExternalLabel* label) { | 127 void Assembler::call(const ExternalLabel* label) { |
| 141 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. | 128 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. |
| 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 129 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 143 EmitRegisterREX(TMP, REX_W); | 130 EmitRegisterREX(TMP, REX_W); |
| 144 EmitUint8(0xB8 | (TMP & 7)); | 131 EmitUint8(0xB8 | (TMP & 7)); |
| 145 EmitInt64(label->address()); | 132 EmitInt64(label->address()); |
| 146 } | 133 } |
| 147 call(TMP); | 134 call(TMP); |
| 148 } | 135 } |
| 149 | 136 |
| 150 | 137 |
| 151 void Assembler::CallPatchable(const ExternalLabel* label) { | 138 void Assembler::CallPatchable(const ExternalLabel* label) { |
| 152 ASSERT(allow_constant_pool()); | 139 ASSERT(allow_constant_pool()); |
| 153 intptr_t call_start = buffer_.GetPosition(); | 140 intptr_t call_start = buffer_.GetPosition(); |
| 154 const int32_t offset = | 141 const int32_t offset = |
| 155 Array::element_offset(FindExternalLabel(label, kPatchable)); | 142 Array::element_offset(object_pool_.FindExternalLabel(label, kPatchable)); |
| 156 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); | 143 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
| 157 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 144 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 158 } | 145 } |
| 159 | 146 |
| 160 | 147 |
| 161 void Assembler::Call(const ExternalLabel* label, Register pp) { | 148 void Assembler::Call(const ExternalLabel* label, Register pp) { |
| 162 if (Isolate::Current() == Dart::vm_isolate()) { | 149 if (Isolate::Current() == Dart::vm_isolate()) { |
| 163 call(label); | 150 call(label); |
| 164 } else { | 151 } else { |
| 165 const int32_t offset = | 152 const int32_t offset = Array::element_offset( |
| 166 Array::element_offset(FindExternalLabel(label, kNotPatchable)); | 153 object_pool_.FindExternalLabel(label, kNotPatchable)); |
| 167 call(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 154 call(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 168 } | 155 } |
| 169 } | 156 } |
| 170 | 157 |
| 171 | 158 |
| 172 void Assembler::pushq(Register reg) { | 159 void Assembler::pushq(Register reg) { |
| 173 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 160 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 174 EmitRegisterREX(reg, REX_NONE); | 161 EmitRegisterREX(reg, REX_NONE); |
| 175 EmitUint8(0x50 | (reg & 7)); | 162 EmitUint8(0x50 | (reg & 7)); |
| 176 } | 163 } |
| (...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2613 EmitInt64(label->address()); | 2600 EmitInt64(label->address()); |
| 2614 } | 2601 } |
| 2615 jmp(TMP); | 2602 jmp(TMP); |
| 2616 } | 2603 } |
| 2617 | 2604 |
| 2618 | 2605 |
| 2619 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2606 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { |
| 2620 ASSERT(allow_constant_pool()); | 2607 ASSERT(allow_constant_pool()); |
| 2621 intptr_t call_start = buffer_.GetPosition(); | 2608 intptr_t call_start = buffer_.GetPosition(); |
| 2622 const int32_t offset = | 2609 const int32_t offset = |
| 2623 Array::element_offset(FindExternalLabel(label, kPatchable)); | 2610 Array::element_offset(object_pool_.FindExternalLabel(label, kPatchable)); |
| 2624 // Patchable jumps always use a 32-bit immediate encoding. | 2611 // Patchable jumps always use a 32-bit immediate encoding. |
| 2625 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2612 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
| 2626 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); | 2613 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
| 2627 } | 2614 } |
| 2628 | 2615 |
| 2629 | 2616 |
| 2630 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2617 void Assembler::Jmp(const ExternalLabel* label, Register pp) { |
| 2631 const int32_t offset = | 2618 const int32_t offset = Array::element_offset( |
| 2632 Array::element_offset(FindExternalLabel(label, kNotPatchable)); | 2619 object_pool_.FindExternalLabel(label, kNotPatchable)); |
| 2633 jmp(Address(pp, offset - kHeapObjectTag)); | 2620 jmp(Address(pp, offset - kHeapObjectTag)); |
| 2634 } | 2621 } |
| 2635 | 2622 |
| 2636 | 2623 |
| 2637 void Assembler::lock() { | 2624 void Assembler::lock() { |
| 2638 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2625 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2639 EmitUint8(0xF0); | 2626 EmitUint8(0xF0); |
| 2640 } | 2627 } |
| 2641 | 2628 |
| 2642 | 2629 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2779 if (stack_elements <= 4) { | 2766 if (stack_elements <= 4) { |
| 2780 for (intptr_t i = 0; i < stack_elements; i++) { | 2767 for (intptr_t i = 0; i < stack_elements; i++) { |
| 2781 popq(tmp); | 2768 popq(tmp); |
| 2782 } | 2769 } |
| 2783 return; | 2770 return; |
| 2784 } | 2771 } |
| 2785 addq(RSP, Immediate(stack_elements * kWordSize)); | 2772 addq(RSP, Immediate(stack_elements * kWordSize)); |
| 2786 } | 2773 } |
| 2787 | 2774 |
| 2788 | 2775 |
| 2789 intptr_t Assembler::FindObject(const Object& obj, Patchability patchable) { | |
| 2790 // The object pool cannot be used in the vm isolate. | |
| 2791 ASSERT(Isolate::Current() != Dart::vm_isolate()); | |
| 2792 ASSERT(!object_pool_.IsNull()); | |
| 2793 | |
| 2794 // If the object is not patchable, check if we've already got it in the | |
| 2795 // object pool. | |
| 2796 if (patchable == kNotPatchable) { | |
| 2797 intptr_t idx = object_pool_index_table_.Lookup(&obj); | |
| 2798 if (idx != ObjIndexPair::kNoIndex) { | |
| 2799 ASSERT(patchable_pool_entries_[idx] == kNotPatchable); | |
| 2800 return idx; | |
| 2801 } | |
| 2802 } | |
| 2803 | |
| 2804 object_pool_.Add(obj, Heap::kOld); | |
| 2805 patchable_pool_entries_.Add(patchable); | |
| 2806 if (patchable == kNotPatchable) { | |
| 2807 // The object isn't patchable. Record the index for fast lookup. | |
| 2808 object_pool_index_table_.Insert( | |
| 2809 ObjIndexPair(&obj, object_pool_.Length() - 1)); | |
| 2810 } | |
| 2811 return object_pool_.Length() - 1; | |
| 2812 } | |
| 2813 | |
| 2814 | |
| 2815 intptr_t Assembler::FindExternalLabel(const ExternalLabel* label, | |
| 2816 Patchability patchable) { | |
| 2817 // The object pool cannot be used in the vm isolate. | |
| 2818 ASSERT(Isolate::Current() != Dart::vm_isolate()); | |
| 2819 ASSERT(!object_pool_.IsNull()); | |
| 2820 const uword address = label->address(); | |
| 2821 ASSERT(Utils::IsAligned(address, 4)); | |
| 2822 // The address is stored in the object array as a RawSmi. | |
| 2823 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address)); | |
| 2824 if (patchable == kNotPatchable) { | |
| 2825 // If the call site is not patchable, we can try to re-use an existing | |
| 2826 // entry. | |
| 2827 return FindObject(smi, kNotPatchable); | |
| 2828 } | |
| 2829 // If the call is patchable, do not reuse an existing entry since each | |
| 2830 // reference may be patched independently. | |
| 2831 object_pool_.Add(smi, Heap::kOld); | |
| 2832 patchable_pool_entries_.Add(patchable); | |
| 2833 return object_pool_.Length() - 1; | |
| 2834 } | |
| 2835 | |
| 2836 | |
| 2837 // A set of VM objects that are present in every constant pool. | 2776 // A set of VM objects that are present in every constant pool. |
| 2838 static bool IsAlwaysInConstantPool(const Object& object) { | 2777 static bool IsAlwaysInConstantPool(const Object& object) { |
| 2839 // TODO(zra): Evaluate putting all VM heap objects into the pool. | 2778 // TODO(zra): Evaluate putting all VM heap objects into the pool. |
| 2840 return (object.raw() == Object::null()) | 2779 return (object.raw() == Object::null()) |
| 2841 || (object.raw() == Bool::True().raw()) | 2780 || (object.raw() == Bool::True().raw()) |
| 2842 || (object.raw() == Bool::False().raw()); | 2781 || (object.raw() == Bool::False().raw()); |
| 2843 } | 2782 } |
| 2844 | 2783 |
| 2845 | 2784 |
| 2846 bool Assembler::CanLoadFromObjectPool(const Object& object) { | 2785 bool Assembler::CanLoadFromObjectPool(const Object& object) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2870 | 2809 |
| 2871 | 2810 |
| 2872 void Assembler::LoadIsolate(Register dst) { | 2811 void Assembler::LoadIsolate(Register dst) { |
| 2873 movq(dst, Immediate(reinterpret_cast<uword>(Isolate::Current()))); | 2812 movq(dst, Immediate(reinterpret_cast<uword>(Isolate::Current()))); |
| 2874 } | 2813 } |
| 2875 | 2814 |
| 2876 | 2815 |
| 2877 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { | 2816 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { |
| 2878 if (CanLoadFromObjectPool(object)) { | 2817 if (CanLoadFromObjectPool(object)) { |
| 2879 const int32_t offset = | 2818 const int32_t offset = |
| 2880 Array::element_offset(FindObject(object, kNotPatchable)); | 2819 Array::element_offset(object_pool_.FindObject(object, kNotPatchable)); |
| 2881 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); | 2820 LoadWordFromPoolOffset(dst, pp, offset - kHeapObjectTag); |
| 2882 } else { | 2821 } else { |
| 2883 ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 2822 ASSERT((Isolate::Current() == Dart::vm_isolate()) || |
| 2884 object.IsSmi() || | 2823 object.IsSmi() || |
| 2885 object.InVMHeap()); | 2824 object.InVMHeap()); |
| 2886 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2825 LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2887 } | 2826 } |
| 2888 } | 2827 } |
| 2889 | 2828 |
| 2890 | 2829 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2905 pushq(TMP); | 2844 pushq(TMP); |
| 2906 } else { | 2845 } else { |
| 2907 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2846 PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2908 } | 2847 } |
| 2909 } | 2848 } |
| 2910 | 2849 |
| 2911 | 2850 |
| 2912 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { | 2851 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { |
| 2913 if (CanLoadFromObjectPool(object)) { | 2852 if (CanLoadFromObjectPool(object)) { |
| 2914 const int32_t offset = | 2853 const int32_t offset = |
| 2915 Array::element_offset(FindObject(object, kNotPatchable)); | 2854 Array::element_offset(object_pool_.FindObject(object, kNotPatchable)); |
| 2916 cmpq(reg, Address(pp, offset-kHeapObjectTag)); | 2855 cmpq(reg, Address(pp, offset-kHeapObjectTag)); |
| 2917 } else { | 2856 } else { |
| 2918 CompareImmediate( | 2857 CompareImmediate( |
| 2919 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); | 2858 reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp); |
| 2920 } | 2859 } |
| 2921 } | 2860 } |
| 2922 | 2861 |
| 2923 | 2862 |
| 2924 intptr_t Assembler::FindImmediate(int64_t imm) { | 2863 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 2925 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 2864 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| 2926 ASSERT(!object_pool_.IsNull()); | |
| 2927 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); | 2865 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); |
| 2928 return FindObject(smi, kNotPatchable); | 2866 return object_pool_.FindObject(smi, kNotPatchable); |
| 2929 } | 2867 } |
| 2930 | 2868 |
| 2931 | 2869 |
| 2932 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { | 2870 bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) { |
| 2933 if (!allow_constant_pool()) { | 2871 if (!allow_constant_pool()) { |
| 2934 return false; | 2872 return false; |
| 2935 } | 2873 } |
| 2936 return !imm.is_int32() && | 2874 return !imm.is_int32() && |
| 2937 (pp != kNoRegister) && | 2875 (pp != kNoRegister) && |
| 2938 (Isolate::Current() != Dart::vm_isolate()); | 2876 (Isolate::Current() != Dart::vm_isolate()); |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3957 | 3895 |
| 3958 | 3896 |
| 3959 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3897 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3960 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3898 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3961 return xmm_reg_names[reg]; | 3899 return xmm_reg_names[reg]; |
| 3962 } | 3900 } |
| 3963 | 3901 |
| 3964 } // namespace dart | 3902 } // namespace dart |
| 3965 | 3903 |
| 3966 #endif // defined TARGET_ARCH_X64 | 3904 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |