| 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 |