Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 2737303003: Allow dispatch to use a range of Class-ids in tests (Closed)
Patch Set: Feedback from Slava Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698