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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 5805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5816 | 5816 |
5817 | 5817 |
5818 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5818 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5819 comparison()->EmitBranchCode(compiler, this); | 5819 comparison()->EmitBranchCode(compiler, this); |
5820 } | 5820 } |
5821 | 5821 |
5822 | 5822 |
5823 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, | 5823 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, |
5824 bool opt) const { | 5824 bool opt) const { |
5825 const intptr_t kNumInputs = 1; | 5825 const intptr_t kNumInputs = 1; |
5826 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 5826 const bool need_mask_temp = IsBitTest(); |
5827 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | 5827 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
5828 LocationSummary* summary = new (zone) | 5828 LocationSummary* summary = new (zone) |
5829 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5829 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5830 summary->set_in(0, Location::RequiresRegister()); | 5830 summary->set_in(0, Location::RequiresRegister()); |
5831 if (!IsNullCheck()) { | 5831 if (!IsNullCheck()) { |
5832 summary->set_temp(0, Location::RequiresRegister()); | 5832 summary->set_temp(0, Location::RequiresRegister()); |
5833 if (need_mask_temp) { | 5833 if (need_mask_temp) { |
5834 summary->set_temp(1, Location::RequiresRegister()); | 5834 summary->set_temp(1, Location::RequiresRegister()); |
5835 } | 5835 } |
5836 } | 5836 } |
5837 return summary; | 5837 return summary; |
5838 } | 5838 } |
5839 | 5839 |
5840 | 5840 |
5841 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5841 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) { |
5842 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, | 5842 const Immediate& raw_null = |
5843 licm_hoisted_ ? ICData::kHoisted : 0); | 5843 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
5844 if (IsNullCheck()) { | 5844 __ cmpl(locs()->in(0).reg(), raw_null); |
5845 const Immediate& raw_null = | 5845 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull()); |
5846 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 5846 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL; |
5847 __ cmpl(locs()->in(0).reg(), raw_null); | 5847 __ j(cond, deopt); |
5848 ASSERT(DeoptIfNull() || DeoptIfNotNull()); | 5848 return; |
Vyacheslav Egorov (Google)
2017/05/09 21:07:28
delete return;
erikcorry
2017/05/10 08:47:43
Done.
| |
5849 Condition cond = DeoptIfNull() ? EQUAL : NOT_EQUAL; | |
5850 __ j(cond, deopt); | |
5851 return; | |
5852 } | |
5853 | |
5854 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | |
5855 (unary_checks().NumberOfChecks() > 1)); | |
5856 Register value = locs()->in(0).reg(); | |
5857 Register temp = locs()->temp(0).reg(); | |
5858 Label is_ok; | |
5859 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | |
5860 __ testl(value, Immediate(kSmiTagMask)); | |
5861 __ j(ZERO, &is_ok); | |
5862 } else { | |
5863 __ testl(value, Immediate(kSmiTagMask)); | |
5864 __ j(ZERO, deopt); | |
5865 } | |
5866 Register biased_cid = temp; | |
5867 __ LoadClassId(biased_cid, value); | |
5868 | |
5869 GrowableArray<CidRangeTarget> sorted_ic_data; | |
5870 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
5871 /* drop_smi = */ true); | |
5872 | |
5873 if (IsDenseSwitch()) { | |
5874 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | |
5875 __ subl(biased_cid, Immediate(cids_[0])); | |
5876 __ cmpl(biased_cid, Immediate(cids_[cids_.length() - 1] - cids_[0])); | |
5877 __ j(ABOVE, deopt); | |
5878 | |
5879 intptr_t mask = ComputeCidMask(); | |
5880 if (!IsDenseMask(mask)) { | |
5881 // Only need mask if there are missing numbers in the range. | |
5882 ASSERT(cids_.length() > 2); | |
5883 Register mask_reg = locs()->temp(1).reg(); | |
5884 __ movl(mask_reg, Immediate(mask)); | |
5885 __ bt(mask_reg, biased_cid); | |
5886 __ j(NOT_CARRY, deopt); | |
5887 } | |
5888 } else { | |
5889 const intptr_t num_checks = sorted_ic_data.length(); | |
5890 const bool use_near_jump = num_checks < 5; | |
5891 int bias = 0; | |
5892 for (intptr_t i = 0; i < num_checks; i++) { | |
5893 const intptr_t cid_start = sorted_ic_data[i].cid_start; | |
5894 const intptr_t cid_end = sorted_ic_data[i].cid_end; | |
5895 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); | |
5896 Condition no_match, match; | |
5897 if (cid_start == cid_end) { | |
5898 __ cmpl(biased_cid, Immediate(cid_start - bias)); | |
5899 no_match = NOT_EQUAL; | |
5900 match = EQUAL; | |
5901 } else { | |
5902 // For class ID ranges use a subtract followed by an unsigned | |
5903 // comparison to check both ends of the ranges with one comparison. | |
5904 __ addl(biased_cid, Immediate(bias - cid_start)); | |
5905 bias = cid_start; | |
5906 __ cmpl(biased_cid, Immediate(cid_end - cid_start)); | |
5907 no_match = ABOVE; | |
5908 match = BELOW_EQUAL; | |
5909 } | |
5910 | |
5911 if (i == num_checks - 1) { | |
5912 __ j(no_match, deopt); | |
5913 } else { | |
5914 if (use_near_jump) { | |
5915 __ j(match, &is_ok, Assembler::kNearJump); | |
5916 } else { | |
5917 __ j(match, &is_ok); | |
5918 } | |
5919 } | |
5920 } | |
5921 } | |
5922 __ Bind(&is_ok); | |
5923 } | 5849 } |
5924 | 5850 |
5925 | 5851 |
5852 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, | |
5853 intptr_t min, | |
5854 intptr_t max, | |
5855 intptr_t mask, | |
5856 Label* deopt) { | |
5857 Register biased_cid = locs()->temp(0).reg(); | |
5858 __ subl(biased_cid, Immediate(min)); | |
5859 __ cmpl(biased_cid, Immediate(max - min)); | |
5860 __ j(ABOVE, deopt); | |
5861 | |
5862 Register mask_reg = locs()->temp(1).reg(); | |
5863 __ movl(mask_reg, Immediate(mask)); | |
5864 __ bt(mask_reg, biased_cid); | |
5865 __ j(NOT_CARRY, deopt); | |
5866 } | |
5867 | |
5868 | |
5869 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, | |
5870 int bias, | |
5871 intptr_t cid_start, | |
5872 intptr_t cid_end, | |
5873 bool is_last, | |
5874 Label* is_ok, | |
5875 Label* deopt, | |
5876 bool use_near_jump) { | |
5877 Register biased_cid = locs()->temp(0).reg(); | |
5878 Condition no_match, match; | |
5879 if (cid_start == cid_end) { | |
5880 __ cmpl(biased_cid, Immediate(cid_start - bias)); | |
5881 no_match = NOT_EQUAL; | |
5882 match = EQUAL; | |
5883 } else { | |
5884 // For class ID ranges use a subtract followed by an unsigned | |
5885 // comparison to check both ends of the ranges with one comparison. | |
5886 __ addl(biased_cid, Immediate(bias - cid_start)); | |
5887 bias = cid_start; | |
5888 __ cmpl(biased_cid, Immediate(cid_end - cid_start)); | |
5889 no_match = ABOVE; | |
5890 match = BELOW_EQUAL; | |
5891 } | |
5892 | |
5893 if (is_last) { | |
5894 __ j(no_match, deopt); | |
5895 } else { | |
5896 if (use_near_jump) { | |
5897 __ j(match, is_ok, Assembler::kNearJump); | |
5898 } else { | |
5899 __ j(match, is_ok); | |
5900 } | |
5901 } | |
5902 return bias; | |
5903 } | |
5904 | |
5905 | |
5926 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, | 5906 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, |
5927 bool opt) const { | 5907 bool opt) const { |
5928 const intptr_t kNumInputs = 1; | 5908 const intptr_t kNumInputs = 1; |
5929 const intptr_t kNumTemps = 0; | 5909 const intptr_t kNumTemps = 0; |
5930 LocationSummary* summary = new (zone) | 5910 LocationSummary* summary = new (zone) |
5931 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5911 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
5932 summary->set_in(0, Location::RequiresRegister()); | 5912 summary->set_in(0, Location::RequiresRegister()); |
5933 return summary; | 5913 return summary; |
5934 } | 5914 } |
5935 | 5915 |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6953 __ Drop(1); | 6933 __ Drop(1); |
6954 __ popl(result); | 6934 __ popl(result); |
6955 } | 6935 } |
6956 | 6936 |
6957 | 6937 |
6958 } // namespace dart | 6938 } // namespace dart |
6959 | 6939 |
6960 #undef __ | 6940 #undef __ |
6961 | 6941 |
6962 #endif // defined TARGET_ARCH_IA32 | 6942 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |