| 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 Label is_ok; | 5800 Label is_ok; |
| 5801 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | 5801 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { |
| 5802 __ testq(value, Immediate(kSmiTagMask)); | 5802 __ testq(value, Immediate(kSmiTagMask)); |
| 5803 __ j(ZERO, &is_ok); | 5803 __ j(ZERO, &is_ok); |
| 5804 } else { | 5804 } else { |
| 5805 __ testq(value, Immediate(kSmiTagMask)); | 5805 __ testq(value, Immediate(kSmiTagMask)); |
| 5806 __ j(ZERO, deopt); | 5806 __ j(ZERO, deopt); |
| 5807 } | 5807 } |
| 5808 __ LoadClassId(temp, value); | 5808 __ LoadClassId(temp, value); |
| 5809 | 5809 |
| 5810 if (IsDenseSwitch()) { | 5810 GrowableArray<CidRangeTarget> sorted_ic_data; |
| 5811 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| 5812 /* drop_smi = */ true); |
| 5813 |
| 5814 if (sorted_ic_data.length() > 4 && IsDenseSwitch()) { |
| 5811 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5815 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| 5812 __ subq(temp, Immediate(cids_[0])); | 5816 __ subq(temp, Immediate(cids_[0])); |
| 5813 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); | 5817 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); |
| 5814 __ j(ABOVE, deopt); | 5818 __ j(ABOVE, deopt); |
| 5815 | 5819 |
| 5816 intptr_t mask = ComputeCidMask(); | 5820 intptr_t mask = ComputeCidMask(); |
| 5817 if (!IsDenseMask(mask)) { | 5821 if (!IsDenseMask(mask)) { |
| 5818 // Only need mask if there are missing numbers in the range. | 5822 // Only need mask if there are missing numbers in the range. |
| 5819 ASSERT(cids_.length() > 2); | 5823 ASSERT(cids_.length() > 2); |
| 5820 Register mask_reg = locs()->temp(1).reg(); | 5824 Register mask_reg = locs()->temp(1).reg(); |
| 5821 __ movq(mask_reg, Immediate(mask)); | 5825 __ movq(mask_reg, Immediate(mask)); |
| 5822 __ btq(mask_reg, temp); | 5826 __ btq(mask_reg, temp); |
| 5823 __ j(NOT_CARRY, deopt); | 5827 __ j(NOT_CARRY, deopt); |
| 5824 } | 5828 } |
| 5825 } else { | 5829 } else { |
| 5826 GrowableArray<CidTarget> sorted_ic_data; | |
| 5827 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
| 5828 /* drop_smi = */ true); | |
| 5829 const intptr_t num_checks = sorted_ic_data.length(); | 5830 const intptr_t num_checks = sorted_ic_data.length(); |
| 5830 const bool use_near_jump = num_checks < 5; | 5831 const bool use_near_jump = num_checks < 5; |
| 5832 int bias = 0; |
| 5831 for (intptr_t i = 0; i < num_checks; i++) { | 5833 for (intptr_t i = 0; i < num_checks; i++) { |
| 5832 const intptr_t cid = sorted_ic_data[i].cid; | 5834 const intptr_t cid_start = sorted_ic_data[i].cid_start; |
| 5833 __ cmpl(temp, Immediate(cid)); | 5835 const intptr_t cid_end = sorted_ic_data[i].cid_end; |
| 5834 if (i == (num_checks - 1)) { | 5836 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); |
| 5835 __ j(NOT_EQUAL, deopt); | 5837 Condition no_match, match; |
| 5838 if (cid_start == cid_end) { |
| 5839 __ cmpl(temp, Immediate(cid_start - bias)); |
| 5840 no_match = NOT_EQUAL; |
| 5841 match = EQUAL; |
| 5842 } else { |
| 5843 // For class ID ranges use a subtract followed by an unsigned |
| 5844 // comparison to check both ends of the ranges with one comparison. |
| 5845 __ addl(temp, Immediate(bias - cid_start)); |
| 5846 bias = cid_start; |
| 5847 __ cmpl(temp, Immediate(cid_end - cid_start)); |
| 5848 no_match = ABOVE; |
| 5849 match = BELOW_EQUAL; |
| 5850 } |
| 5851 |
| 5852 if (i == num_checks - 1) { |
| 5853 __ j(no_match, deopt); |
| 5836 } else { | 5854 } else { |
| 5837 if (use_near_jump) { | 5855 if (use_near_jump) { |
| 5838 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 5856 __ j(match, &is_ok, Assembler::kNearJump); |
| 5839 } else { | 5857 } else { |
| 5840 __ j(EQUAL, &is_ok); | 5858 __ j(match, &is_ok); |
| 5841 } | 5859 } |
| 5842 } | 5860 } |
| 5843 } | 5861 } |
| 5844 } | 5862 } |
| 5845 __ Bind(&is_ok); | 5863 __ Bind(&is_ok); |
| 5846 } | 5864 } |
| 5847 | 5865 |
| 5848 | 5866 |
| 5849 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, | 5867 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, |
| 5850 bool opt) const { | 5868 bool opt) const { |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6750 __ Drop(1); | 6768 __ Drop(1); |
| 6751 __ popq(result); | 6769 __ popq(result); |
| 6752 } | 6770 } |
| 6753 | 6771 |
| 6754 | 6772 |
| 6755 } // namespace dart | 6773 } // namespace dart |
| 6756 | 6774 |
| 6757 #undef __ | 6775 #undef __ |
| 6758 | 6776 |
| 6759 #endif // defined TARGET_ARCH_X64 | 6777 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |