Chromium Code Reviews| 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 |