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" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 2133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 __ popq(kResultReg); | 2144 __ popq(kResultReg); |
2145 __ Bind(&done); | 2145 __ Bind(&done); |
2146 return; | 2146 return; |
2147 } | 2147 } |
2148 } | 2148 } |
2149 | 2149 |
2150 __ Bind(&slow_path); | 2150 __ Bind(&slow_path); |
2151 const Code& stub = Code::ZoneHandle(compiler->zone(), | 2151 const Code& stub = Code::ZoneHandle(compiler->zone(), |
2152 StubCode::AllocateArray_entry()->code()); | 2152 StubCode::AllocateArray_entry()->code()); |
2153 compiler->AddStubCallTarget(stub); | 2153 compiler->AddStubCallTarget(stub); |
2154 compiler->GenerateCallWithDeopt(token_pos(), deopt_id(), | 2154 compiler->GenerateCall(token_pos(), *StubCode::AllocateArray_entry(), |
2155 *StubCode::AllocateArray_entry(), | 2155 RawPcDescriptors::kOther, locs()); |
2156 RawPcDescriptors::kOther, locs()); | |
2157 __ Bind(&done); | 2156 __ Bind(&done); |
2158 ASSERT(locs()->out(0).reg() == kResultReg); | 2157 ASSERT(locs()->out(0).reg() == kResultReg); |
2159 } | 2158 } |
2160 | 2159 |
2161 | 2160 |
2162 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, | 2161 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, |
2163 bool opt) const { | 2162 bool opt) const { |
2164 const intptr_t kNumInputs = 1; | 2163 const intptr_t kNumInputs = 1; |
2165 const intptr_t kNumTemps = | 2164 const intptr_t kNumTemps = |
2166 (IsUnboxedLoad() && opt) ? 1 : ((IsPotentialUnboxedLoad()) ? 2 : 0); | 2165 (IsUnboxedLoad() && opt) ? 1 : ((IsPotentialUnboxedLoad()) ? 2 : 0); |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2822 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
2824 if (Assembler::EmittingComments()) { | 2823 if (Assembler::EmittingComments()) { |
2825 __ Comment("slow path smi operation"); | 2824 __ Comment("slow path smi operation"); |
2826 } | 2825 } |
2827 __ Bind(entry_label()); | 2826 __ Bind(entry_label()); |
2828 LocationSummary* locs = instruction_->locs(); | 2827 LocationSummary* locs = instruction_->locs(); |
2829 Register result = locs->out(0).reg(); | 2828 Register result = locs->out(0).reg(); |
2830 locs->live_registers()->Remove(Location::RegisterLocation(result)); | 2829 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
2831 | 2830 |
2832 compiler->SaveLiveRegisters(locs); | 2831 compiler->SaveLiveRegisters(locs); |
2833 if (instruction_->env() != NULL) { | |
2834 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); | |
2835 compiler->pending_deoptimization_env_ = env; | |
2836 } | |
2837 __ pushq(locs->in(0).reg()); | 2832 __ pushq(locs->in(0).reg()); |
2838 __ pushq(locs->in(1).reg()); | 2833 __ pushq(locs->in(1).reg()); |
2839 compiler->EmitMegamorphicInstanceCall( | 2834 compiler->EmitMegamorphicInstanceCall( |
2840 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), | 2835 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), |
2841 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), | 2836 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), |
2842 locs, try_index_, | 2837 locs, try_index_, |
2843 /* slow_path_argument_count = */ 2); | 2838 /* slow_path_argument_count = */ 2); |
2844 __ MoveRegister(result, RAX); | 2839 __ MoveRegister(result, RAX); |
2845 compiler->RestoreLiveRegisters(locs); | 2840 compiler->RestoreLiveRegisters(locs); |
2846 __ jmp(exit_label()); | 2841 __ jmp(exit_label()); |
2847 compiler->pending_deoptimization_env_ = NULL; | |
2848 } | 2842 } |
2849 | 2843 |
2850 private: | 2844 private: |
2851 CheckedSmiOpInstr* instruction_; | 2845 CheckedSmiOpInstr* instruction_; |
2852 intptr_t try_index_; | 2846 intptr_t try_index_; |
2853 }; | 2847 }; |
2854 | 2848 |
2855 | 2849 |
2856 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, | 2850 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, |
2857 bool opt) const { | 2851 bool opt) const { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2988 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 2982 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
2989 if (Assembler::EmittingComments()) { | 2983 if (Assembler::EmittingComments()) { |
2990 __ Comment("slow path smi comparison"); | 2984 __ Comment("slow path smi comparison"); |
2991 } | 2985 } |
2992 __ Bind(entry_label()); | 2986 __ Bind(entry_label()); |
2993 LocationSummary* locs = instruction_->locs(); | 2987 LocationSummary* locs = instruction_->locs(); |
2994 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); | 2988 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); |
2995 locs->live_registers()->Remove(Location::RegisterLocation(result)); | 2989 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
2996 | 2990 |
2997 compiler->SaveLiveRegisters(locs); | 2991 compiler->SaveLiveRegisters(locs); |
2998 if (instruction_->env() != NULL) { | |
2999 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); | |
3000 compiler->pending_deoptimization_env_ = env; | |
3001 } | |
3002 __ pushq(locs->in(0).reg()); | 2992 __ pushq(locs->in(0).reg()); |
3003 __ pushq(locs->in(1).reg()); | 2993 __ pushq(locs->in(1).reg()); |
3004 compiler->EmitMegamorphicInstanceCall( | 2994 compiler->EmitMegamorphicInstanceCall( |
3005 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), | 2995 *instruction_->call()->ic_data(), instruction_->call()->ArgumentCount(), |
3006 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), | 2996 instruction_->call()->deopt_id(), instruction_->call()->token_pos(), |
3007 locs, try_index_, | 2997 locs, try_index_, |
3008 /* slow_path_argument_count = */ 2); | 2998 /* slow_path_argument_count = */ 2); |
3009 __ MoveRegister(result, RAX); | 2999 __ MoveRegister(result, RAX); |
3010 compiler->RestoreLiveRegisters(locs); | 3000 compiler->RestoreLiveRegisters(locs); |
3011 compiler->pending_deoptimization_env_ = NULL; | |
3012 if (merged_) { | 3001 if (merged_) { |
3013 __ CompareObject(result, Bool::True()); | 3002 __ CompareObject(result, Bool::True()); |
3014 __ j(EQUAL, instruction_->is_negated() ? labels_.false_label | 3003 __ j(EQUAL, instruction_->is_negated() ? labels_.false_label |
3015 : labels_.true_label); | 3004 : labels_.true_label); |
3016 __ jmp(instruction_->is_negated() ? labels_.true_label | 3005 __ jmp(instruction_->is_negated() ? labels_.true_label |
3017 : labels_.false_label); | 3006 : labels_.false_label); |
3018 } else { | 3007 } else { |
3019 __ jmp(exit_label()); | 3008 __ jmp(exit_label()); |
3020 } | 3009 } |
3021 } | 3010 } |
(...skipping 2889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5911 public: | 5900 public: |
5912 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) | 5901 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) |
5913 : instruction_(instruction), try_index_(try_index) {} | 5902 : instruction_(instruction), try_index_(try_index) {} |
5914 | 5903 |
5915 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 5904 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
5916 if (Assembler::EmittingComments()) { | 5905 if (Assembler::EmittingComments()) { |
5917 __ Comment("slow path check bound operation"); | 5906 __ Comment("slow path check bound operation"); |
5918 } | 5907 } |
5919 __ Bind(entry_label()); | 5908 __ Bind(entry_label()); |
5920 LocationSummary* locs = instruction_->locs(); | 5909 LocationSummary* locs = instruction_->locs(); |
5921 compiler->SaveLiveRegisters(locs); | |
5922 __ pushq(locs->in(0).reg()); | 5910 __ pushq(locs->in(0).reg()); |
5923 __ pushq(locs->in(1).reg()); | 5911 __ pushq(locs->in(1).reg()); |
5924 __ CallRuntime(kRangeErrorRuntimeEntry, 2); | 5912 __ CallRuntime(kRangeErrorRuntimeEntry, 2); |
5925 compiler->AddDescriptor( | 5913 compiler->AddDescriptor( |
5926 RawPcDescriptors::kOther, compiler->assembler()->CodeSize(), | 5914 RawPcDescriptors::kOther, compiler->assembler()->CodeSize(), |
5927 instruction_->deopt_id(), instruction_->token_pos(), try_index_); | 5915 instruction_->deopt_id(), instruction_->token_pos(), try_index_); |
5928 compiler->RecordSafepoint(locs, 2); | 5916 compiler->RecordSafepoint(locs, 2); |
5929 Environment* env = compiler->SlowPathEnvironmentFor(instruction_); | |
5930 compiler->EmitCatchEntryState(env, try_index_); | |
5931 __ int3(); | 5917 __ int3(); |
5932 } | 5918 } |
5933 | 5919 |
5934 private: | 5920 private: |
5935 GenericCheckBoundInstr* instruction_; | 5921 GenericCheckBoundInstr* instruction_; |
5936 intptr_t try_index_; | 5922 intptr_t try_index_; |
5937 }; | 5923 }; |
5938 | 5924 |
5939 | 5925 |
5940 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5926 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5941 RangeErrorSlowPath* slow_path = | 5927 RangeErrorSlowPath* slow_path = |
5942 new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); | 5928 new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); |
5943 compiler->AddSlowPathCode(slow_path); | 5929 compiler->AddSlowPathCode(slow_path); |
| 5930 |
5944 Location length_loc = locs()->in(kLengthPos); | 5931 Location length_loc = locs()->in(kLengthPos); |
5945 Location index_loc = locs()->in(kIndexPos); | 5932 Location index_loc = locs()->in(kIndexPos); |
5946 Register length = length_loc.reg(); | 5933 Register length = length_loc.reg(); |
5947 Register index = index_loc.reg(); | 5934 Register index = index_loc.reg(); |
5948 const intptr_t index_cid = this->index()->Type()->ToCid(); | 5935 const intptr_t index_cid = this->index()->Type()->ToCid(); |
5949 if (index_cid != kSmiCid) { | 5936 if (index_cid != kSmiCid) { |
5950 __ BranchIfNotSmi(index, slow_path->entry_label()); | 5937 __ BranchIfNotSmi(index, slow_path->entry_label()); |
5951 } | 5938 } |
5952 __ cmpq(index, length); | 5939 __ cmpq(index, length); |
5953 __ j(ABOVE_EQUAL, slow_path->entry_label()); | 5940 __ j(ABOVE_EQUAL, slow_path->entry_label()); |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6674 ASSERT(locs()->in(0).reg() == RAX); | 6661 ASSERT(locs()->in(0).reg() == RAX); |
6675 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | 6662 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
6676 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 6663 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
6677 | 6664 |
6678 // RAX: Function. | 6665 // RAX: Function. |
6679 // R10: Arguments descriptor array. | 6666 // R10: Arguments descriptor array. |
6680 // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | 6667 // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). |
6681 __ xorq(RBX, RBX); | 6668 __ xorq(RBX, RBX); |
6682 __ call(RCX); | 6669 __ call(RCX); |
6683 compiler->RecordSafepoint(locs()); | 6670 compiler->RecordSafepoint(locs()); |
6684 compiler->EmitCatchEntryState(); | |
6685 // Marks either the continuation point in unoptimized code or the | 6671 // Marks either the continuation point in unoptimized code or the |
6686 // deoptimization point in optimized code, after call. | 6672 // deoptimization point in optimized code, after call. |
6687 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id()); | 6673 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id()); |
6688 if (compiler->is_optimizing()) { | 6674 if (compiler->is_optimizing()) { |
6689 compiler->AddDeoptIndexAtCall(deopt_id_after); | 6675 compiler->AddDeoptIndexAtCall(deopt_id_after); |
6690 } | 6676 } |
6691 // Add deoptimization continuation point after the call and before the | 6677 // Add deoptimization continuation point after the call and before the |
6692 // arguments are removed. | 6678 // arguments are removed. |
6693 // In optimized code this descriptor is needed for exception handling. | 6679 // In optimized code this descriptor is needed for exception handling. |
6694 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, | 6680 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6764 __ Drop(1); | 6750 __ Drop(1); |
6765 __ popq(result); | 6751 __ popq(result); |
6766 } | 6752 } |
6767 | 6753 |
6768 | 6754 |
6769 } // namespace dart | 6755 } // namespace dart |
6770 | 6756 |
6771 #undef __ | 6757 #undef __ |
6772 | 6758 |
6773 #endif // defined TARGET_ARCH_X64 | 6759 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |