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 5789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5800 | 5800 |
5801 | 5801 |
5802 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5802 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5803 comparison()->EmitBranchCode(compiler, this); | 5803 comparison()->EmitBranchCode(compiler, this); |
5804 } | 5804 } |
5805 | 5805 |
5806 | 5806 |
5807 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, | 5807 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, |
5808 bool opt) const { | 5808 bool opt) const { |
5809 const intptr_t kNumInputs = 1; | 5809 const intptr_t kNumInputs = 1; |
5810 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 5810 const bool need_mask_temp = IsBitTest(); |
5811 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | 5811 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
5812 LocationSummary* summary = new (zone) | 5812 LocationSummary* summary = new (zone) |
5813 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5813 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5814 summary->set_in(0, Location::RequiresRegister()); | 5814 summary->set_in(0, Location::RequiresRegister()); |
5815 if (!IsNullCheck()) { | 5815 if (!IsNullCheck()) { |
5816 summary->set_temp(0, Location::RequiresRegister()); | 5816 summary->set_temp(0, Location::RequiresRegister()); |
5817 if (need_mask_temp) { | 5817 if (need_mask_temp) { |
5818 summary->set_temp(1, Location::RequiresRegister()); | 5818 summary->set_temp(1, Location::RequiresRegister()); |
5819 } | 5819 } |
5820 } | 5820 } |
5821 return summary; | 5821 return summary; |
5822 } | 5822 } |
5823 | 5823 |
5824 | 5824 |
5825 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5825 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) { |
5826 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, | 5826 __ CompareObject(locs()->in(0).reg(), Object::null_object()); |
5827 licm_hoisted_ ? ICData::kHoisted : 0); | 5827 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL; |
5828 if (IsNullCheck()) { | 5828 __ j(cond, deopt); |
5829 __ CompareObject(locs()->in(0).reg(), Object::null_object()); | 5829 return; |
Vyacheslav Egorov (Google)
2017/05/09 21:07:28
ditto
erikcorry
2017/05/10 08:47:43
Done.
| |
5830 Condition cond = DeoptIfNull() ? EQUAL : NOT_EQUAL; | |
5831 __ j(cond, deopt); | |
5832 return; | |
5833 } | |
5834 | |
5835 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | |
5836 (unary_checks().NumberOfChecks() > 1)); | |
5837 Register value = locs()->in(0).reg(); | |
5838 Register temp = locs()->temp(0).reg(); | |
5839 Label is_ok; | |
5840 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | |
5841 __ testq(value, Immediate(kSmiTagMask)); | |
5842 __ j(ZERO, &is_ok); | |
5843 } else { | |
5844 __ testq(value, Immediate(kSmiTagMask)); | |
5845 __ j(ZERO, deopt); | |
5846 } | |
5847 __ LoadClassId(temp, value); | |
5848 | |
5849 GrowableArray<CidRangeTarget> sorted_ic_data; | |
5850 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
5851 /* drop_smi = */ true); | |
5852 | |
5853 if (IsDenseSwitch()) { | |
5854 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | |
5855 __ subq(temp, Immediate(cids_[0])); | |
5856 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); | |
5857 __ j(ABOVE, deopt); | |
5858 | |
5859 intptr_t mask = ComputeCidMask(); | |
5860 if (!IsDenseMask(mask)) { | |
5861 // Only need mask if there are missing numbers in the range. | |
5862 ASSERT(cids_.length() > 2); | |
5863 Register mask_reg = locs()->temp(1).reg(); | |
5864 __ movq(mask_reg, Immediate(mask)); | |
5865 __ btq(mask_reg, temp); | |
5866 __ j(NOT_CARRY, deopt); | |
5867 } | |
5868 } else { | |
5869 const intptr_t num_checks = sorted_ic_data.length(); | |
5870 const bool use_near_jump = num_checks < 5; | |
5871 int bias = 0; | |
5872 for (intptr_t i = 0; i < num_checks; i++) { | |
5873 const intptr_t cid_start = sorted_ic_data[i].cid_start; | |
5874 const intptr_t cid_end = sorted_ic_data[i].cid_end; | |
5875 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); | |
5876 Condition no_match, match; | |
5877 if (cid_start == cid_end) { | |
5878 __ cmpl(temp, Immediate(cid_start - bias)); | |
5879 no_match = NOT_EQUAL; | |
5880 match = EQUAL; | |
5881 } else { | |
5882 // For class ID ranges use a subtract followed by an unsigned | |
5883 // comparison to check both ends of the ranges with one comparison. | |
5884 __ addl(temp, Immediate(bias - cid_start)); | |
5885 bias = cid_start; | |
5886 __ cmpl(temp, Immediate(cid_end - cid_start)); | |
5887 no_match = ABOVE; | |
5888 match = BELOW_EQUAL; | |
5889 } | |
5890 | |
5891 if (i == num_checks - 1) { | |
5892 __ j(no_match, deopt); | |
5893 } else { | |
5894 if (use_near_jump) { | |
5895 __ j(match, &is_ok, Assembler::kNearJump); | |
5896 } else { | |
5897 __ j(match, &is_ok); | |
5898 } | |
5899 } | |
5900 } | |
5901 } | |
5902 __ Bind(&is_ok); | |
5903 } | 5830 } |
5904 | 5831 |
5905 | 5832 |
5833 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, | |
5834 intptr_t min, | |
5835 intptr_t max, | |
5836 intptr_t mask, | |
5837 Label* deopt) { | |
5838 Register biased_cid = locs()->temp(0).reg(); | |
5839 __ subq(biased_cid, Immediate(min)); | |
5840 __ cmpq(biased_cid, Immediate(max - min)); | |
5841 __ j(ABOVE, deopt); | |
5842 | |
5843 Register mask_reg = locs()->temp(1).reg(); | |
5844 __ movq(mask_reg, Immediate(mask)); | |
5845 __ btq(mask_reg, biased_cid); | |
5846 __ j(NOT_CARRY, deopt); | |
5847 } | |
5848 | |
5849 | |
5850 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, | |
5851 int bias, | |
5852 intptr_t cid_start, | |
5853 intptr_t cid_end, | |
5854 bool is_last, | |
5855 Label* is_ok, | |
5856 Label* deopt, | |
5857 bool use_near_jump) { | |
5858 Register biased_cid = locs()->temp(0).reg(); | |
5859 Condition no_match, match; | |
5860 if (cid_start == cid_end) { | |
5861 __ cmpl(biased_cid, Immediate(cid_start - bias)); | |
5862 no_match = NOT_EQUAL; | |
5863 match = EQUAL; | |
5864 } else { | |
5865 // For class ID ranges use a subtract followed by an unsigned | |
5866 // comparison to check both ends of the ranges with one comparison. | |
5867 __ addl(biased_cid, Immediate(bias - cid_start)); | |
5868 bias = cid_start; | |
5869 __ cmpl(biased_cid, Immediate(cid_end - cid_start)); | |
5870 no_match = ABOVE; | |
5871 match = BELOW_EQUAL; | |
5872 } | |
5873 | |
5874 if (is_last) { | |
5875 __ j(no_match, deopt); | |
5876 } else { | |
5877 if (use_near_jump) { | |
5878 __ j(match, is_ok, Assembler::kNearJump); | |
5879 } else { | |
5880 __ j(match, is_ok); | |
5881 } | |
5882 } | |
5883 return bias; | |
5884 } | |
5885 | |
5886 | |
5906 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, | 5887 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, |
5907 bool opt) const { | 5888 bool opt) const { |
5908 const intptr_t kNumInputs = 1; | 5889 const intptr_t kNumInputs = 1; |
5909 const intptr_t kNumTemps = 0; | 5890 const intptr_t kNumTemps = 0; |
5910 LocationSummary* summary = new (zone) | 5891 LocationSummary* summary = new (zone) |
5911 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5892 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5912 summary->set_in(0, Location::RequiresRegister()); | 5893 summary->set_in(0, Location::RequiresRegister()); |
5913 return summary; | 5894 return summary; |
5914 } | 5895 } |
5915 | 5896 |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6810 __ Drop(1); | 6791 __ Drop(1); |
6811 __ popq(result); | 6792 __ popq(result); |
6812 } | 6793 } |
6813 | 6794 |
6814 | 6795 |
6815 } // namespace dart | 6796 } // namespace dart |
6816 | 6797 |
6817 #undef __ | 6798 #undef __ |
6818 | 6799 |
6819 #endif // defined TARGET_ARCH_X64 | 6800 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |