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