Chromium Code Reviews| Index: runtime/vm/intermediate_language_arm.cc |
| diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc |
| index 3f9e1f38052212fa7d8e2f1a3ddc27e5900eda21..72a857cc02d8f6451d480f5e17b9bf18b9c3d45b 100644 |
| --- a/runtime/vm/intermediate_language_arm.cc |
| +++ b/runtime/vm/intermediate_language_arm.cc |
| @@ -6300,12 +6300,17 @@ void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ tst(value, Operand(kSmiTagMask)); |
| __ b(deopt, EQ); |
| } |
| - __ LoadClassId(temp, value); |
| + Register biased_cid = temp; |
| + __ LoadClassId(biased_cid, value); |
| - if (IsDenseSwitch()) { |
| + GrowableArray<CidRangeTarget> sorted_ic_data; |
| + FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| + /* drop_smi = */ true); |
| + |
| + if (sorted_ic_data.length() > 4 && IsDenseSwitch()) { |
|
Vyacheslav Egorov (Google)
2017/03/10 10:31:30
What is this magical 4? Is this the same 4 as FLAG
erikcorry
2017/03/10 13:30:01
Accidental change, reverted.
|
| ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| - __ AddImmediate(temp, -cids_[0]); |
| - __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0]); |
| + __ AddImmediate(biased_cid, -cids_[0]); |
| + __ CompareImmediate(biased_cid, cids_[cids_.length() - 1] - cids_[0]); |
| __ b(deopt, HI); |
| intptr_t mask = ComputeCidMask(); |
| @@ -6314,23 +6319,35 @@ void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| ASSERT(cids_.length() > 2); |
| Register mask_reg = locs()->temp(1).reg(); |
| __ LoadImmediate(mask_reg, 1); |
| - __ Lsl(mask_reg, mask_reg, temp); |
| + __ Lsl(mask_reg, mask_reg, biased_cid); |
| __ TestImmediate(mask_reg, mask); |
| __ b(deopt, EQ); |
| } |
| } else { |
| - GrowableArray<CidTarget> sorted_ic_data; |
| - FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| - /* drop_smi = */ true); |
| const intptr_t num_checks = sorted_ic_data.length(); |
| + int bias = 0; |
| for (intptr_t i = 0; i < num_checks; i++) { |
| - const intptr_t cid = sorted_ic_data[i].cid; |
| - ASSERT(cid != kSmiCid); |
| - __ CompareImmediate(temp, cid); |
| + const intptr_t cid_start = sorted_ic_data[i].cid_start; |
| + const intptr_t cid_end = sorted_ic_data[i].cid_end; |
| + ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); |
| + Condition no_match, match; |
| + if (cid_start == cid_end) { |
| + __ CompareImmediate(biased_cid, cid_start - bias); |
| + no_match = NE; |
| + match = EQ; |
| + } else { |
| + // For class ID ranges use a subtract followed by an unsigned |
| + // comparison to check both ends of the ranges with one comparison. |
| + __ AddImmediate(biased_cid, biased_cid, bias - cid_start); |
| + bias = cid_start; |
| + __ CompareImmediate(biased_cid, cid_end - cid_start); |
| + no_match = HI; // Unsigned higher. |
| + match = LS; // Unsigned lower or same. |
| + } |
| if (i == (num_checks - 1)) { |
| - __ b(deopt, NE); |
| + __ b(deopt, no_match); |
| } else { |
| - __ b(&is_ok, EQ); |
| + __ b(&is_ok, match); |
| } |
| } |
| } |