Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 1225933002: Remove fixed contant pool entries by caching some global constants in Thread (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: added helper methods to Thread Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698