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