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 5782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5793 Register value = locs()->in(0).reg(); | 5793 Register value = locs()->in(0).reg(); |
5794 Register temp = locs()->temp(0).reg(); | 5794 Register temp = locs()->temp(0).reg(); |
5795 Label is_ok; | 5795 Label is_ok; |
5796 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | 5796 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { |
5797 __ testl(value, Immediate(kSmiTagMask)); | 5797 __ testl(value, Immediate(kSmiTagMask)); |
5798 __ j(ZERO, &is_ok); | 5798 __ j(ZERO, &is_ok); |
5799 } else { | 5799 } else { |
5800 __ testl(value, Immediate(kSmiTagMask)); | 5800 __ testl(value, Immediate(kSmiTagMask)); |
5801 __ j(ZERO, deopt); | 5801 __ j(ZERO, deopt); |
5802 } | 5802 } |
5803 __ LoadClassId(temp, value); | 5803 Register biased_cid = temp; |
| 5804 __ LoadClassId(biased_cid, value); |
| 5805 |
| 5806 GrowableArray<CidRangeTarget> sorted_ic_data; |
| 5807 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| 5808 /* drop_smi = */ true); |
5804 | 5809 |
5805 if (IsDenseSwitch()) { | 5810 if (IsDenseSwitch()) { |
5806 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5811 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
5807 __ subl(temp, Immediate(cids_[0])); | 5812 __ subl(biased_cid, Immediate(cids_[0])); |
5808 __ cmpl(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); | 5813 __ cmpl(biased_cid, Immediate(cids_[cids_.length() - 1] - cids_[0])); |
5809 __ j(ABOVE, deopt); | 5814 __ j(ABOVE, deopt); |
5810 | 5815 |
5811 intptr_t mask = ComputeCidMask(); | 5816 intptr_t mask = ComputeCidMask(); |
5812 if (!IsDenseMask(mask)) { | 5817 if (!IsDenseMask(mask)) { |
5813 // Only need mask if there are missing numbers in the range. | 5818 // Only need mask if there are missing numbers in the range. |
5814 ASSERT(cids_.length() > 2); | 5819 ASSERT(cids_.length() > 2); |
5815 Register mask_reg = locs()->temp(1).reg(); | 5820 Register mask_reg = locs()->temp(1).reg(); |
5816 __ movl(mask_reg, Immediate(mask)); | 5821 __ movl(mask_reg, Immediate(mask)); |
5817 __ bt(mask_reg, temp); | 5822 __ bt(mask_reg, biased_cid); |
5818 __ j(NOT_CARRY, deopt); | 5823 __ j(NOT_CARRY, deopt); |
5819 } | 5824 } |
5820 } else { | 5825 } else { |
5821 GrowableArray<CidTarget> sorted_ic_data; | |
5822 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
5823 /* drop_smi = */ true); | |
5824 const intptr_t num_checks = sorted_ic_data.length(); | 5826 const intptr_t num_checks = sorted_ic_data.length(); |
5825 const bool use_near_jump = num_checks < 5; | 5827 const bool use_near_jump = num_checks < 5; |
| 5828 int bias = 0; |
5826 for (intptr_t i = 0; i < num_checks; i++) { | 5829 for (intptr_t i = 0; i < num_checks; i++) { |
5827 const intptr_t cid = sorted_ic_data[i].cid; | 5830 const intptr_t cid_start = sorted_ic_data[i].cid_start; |
5828 ASSERT(cid != kSmiCid); | 5831 const intptr_t cid_end = sorted_ic_data[i].cid_end; |
5829 __ cmpl(temp, Immediate(cid)); | 5832 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); |
5830 if (i == (num_checks - 1)) { | 5833 Condition no_match, match; |
5831 __ j(NOT_EQUAL, deopt); | 5834 if (cid_start == cid_end) { |
| 5835 __ cmpl(biased_cid, Immediate(cid_start - bias)); |
| 5836 no_match = NOT_EQUAL; |
| 5837 match = EQUAL; |
| 5838 } else { |
| 5839 // For class ID ranges use a subtract followed by an unsigned |
| 5840 // comparison to check both ends of the ranges with one comparison. |
| 5841 __ addl(biased_cid, Immediate(bias - cid_start)); |
| 5842 bias = cid_start; |
| 5843 __ cmpl(biased_cid, Immediate(cid_end - cid_start)); |
| 5844 no_match = ABOVE; |
| 5845 match = BELOW_EQUAL; |
| 5846 } |
| 5847 |
| 5848 if (i == num_checks - 1) { |
| 5849 __ j(no_match, deopt); |
5832 } else { | 5850 } else { |
5833 if (use_near_jump) { | 5851 if (use_near_jump) { |
5834 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 5852 __ j(match, &is_ok, Assembler::kNearJump); |
5835 } else { | 5853 } else { |
5836 __ j(EQUAL, &is_ok); | 5854 __ j(match, &is_ok); |
5837 } | 5855 } |
5838 } | 5856 } |
5839 } | 5857 } |
5840 } | 5858 } |
5841 __ Bind(&is_ok); | 5859 __ Bind(&is_ok); |
5842 } | 5860 } |
5843 | 5861 |
5844 | 5862 |
5845 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, | 5863 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, |
5846 bool opt) const { | 5864 bool opt) const { |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6872 __ Drop(1); | 6890 __ Drop(1); |
6873 __ popl(result); | 6891 __ popl(result); |
6874 } | 6892 } |
6875 | 6893 |
6876 | 6894 |
6877 } // namespace dart | 6895 } // namespace dart |
6878 | 6896 |
6879 #undef __ | 6897 #undef __ |
6880 | 6898 |
6881 #endif // defined TARGET_ARCH_IA32 | 6899 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |