Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
| index 6ace530e23167c3bffb78dada5c04eec8ed2c5b4..b17e7f5210ed6830ef23d6ddfba8959ee14b0ee2 100644 |
| --- a/runtime/vm/intermediate_language_ia32.cc |
| +++ b/runtime/vm/intermediate_language_ia32.cc |
| @@ -5823,7 +5823,7 @@ void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, |
| bool opt) const { |
| const intptr_t kNumInputs = 1; |
| - const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); |
| + const bool need_mask_temp = IsBitTest(); |
| const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
| LocationSummary* summary = new (zone) |
| LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| @@ -5838,88 +5838,68 @@ LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, |
| } |
| -void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| - Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, |
| - licm_hoisted_ ? ICData::kHoisted : 0); |
| - if (IsNullCheck()) { |
| - const Immediate& raw_null = |
| - Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| - __ cmpl(locs()->in(0).reg(), raw_null); |
| - ASSERT(DeoptIfNull() || DeoptIfNotNull()); |
| - Condition cond = DeoptIfNull() ? EQUAL : NOT_EQUAL; |
| - __ j(cond, deopt); |
| - return; |
| - } |
| +void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) { |
| + const Immediate& raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + __ cmpl(locs()->in(0).reg(), raw_null); |
| + ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull()); |
| + Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL; |
| + __ j(cond, deopt); |
| + return; |
|
Vyacheslav Egorov (Google)
2017/05/09 21:07:28
delete return;
erikcorry
2017/05/10 08:47:43
Done.
|
| +} |
| - ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
| - (unary_checks().NumberOfChecks() > 1)); |
| - Register value = locs()->in(0).reg(); |
| - Register temp = locs()->temp(0).reg(); |
| - Label is_ok; |
| - if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { |
| - __ testl(value, Immediate(kSmiTagMask)); |
| - __ j(ZERO, &is_ok); |
| - } else { |
| - __ testl(value, Immediate(kSmiTagMask)); |
| - __ j(ZERO, deopt); |
| - } |
| - Register biased_cid = temp; |
| - __ LoadClassId(biased_cid, value); |
| - |
| - GrowableArray<CidRangeTarget> sorted_ic_data; |
| - FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| - /* drop_smi = */ true); |
| - |
| - if (IsDenseSwitch()) { |
| - ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| - __ subl(biased_cid, Immediate(cids_[0])); |
| - __ cmpl(biased_cid, Immediate(cids_[cids_.length() - 1] - cids_[0])); |
| - __ j(ABOVE, deopt); |
| - |
| - intptr_t mask = ComputeCidMask(); |
| - if (!IsDenseMask(mask)) { |
| - // Only need mask if there are missing numbers in the range. |
| - ASSERT(cids_.length() > 2); |
| - Register mask_reg = locs()->temp(1).reg(); |
| - __ movl(mask_reg, Immediate(mask)); |
| - __ bt(mask_reg, biased_cid); |
| - __ j(NOT_CARRY, deopt); |
| - } |
| + |
| +void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, |
| + intptr_t min, |
| + intptr_t max, |
| + intptr_t mask, |
| + Label* deopt) { |
| + Register biased_cid = locs()->temp(0).reg(); |
| + __ subl(biased_cid, Immediate(min)); |
| + __ cmpl(biased_cid, Immediate(max - min)); |
| + __ j(ABOVE, deopt); |
| + |
| + Register mask_reg = locs()->temp(1).reg(); |
| + __ movl(mask_reg, Immediate(mask)); |
| + __ bt(mask_reg, biased_cid); |
| + __ j(NOT_CARRY, deopt); |
| +} |
| + |
| + |
| +int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, |
| + int bias, |
| + intptr_t cid_start, |
| + intptr_t cid_end, |
| + bool is_last, |
| + Label* is_ok, |
| + Label* deopt, |
| + bool use_near_jump) { |
| + Register biased_cid = locs()->temp(0).reg(); |
| + Condition no_match, match; |
| + if (cid_start == cid_end) { |
| + __ cmpl(biased_cid, Immediate(cid_start - bias)); |
| + no_match = NOT_EQUAL; |
| + match = EQUAL; |
| } else { |
| - const intptr_t num_checks = sorted_ic_data.length(); |
| - const bool use_near_jump = num_checks < 5; |
| - int bias = 0; |
| - for (intptr_t i = 0; i < num_checks; i++) { |
| - 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) { |
| - __ cmpl(biased_cid, Immediate(cid_start - bias)); |
| - no_match = NOT_EQUAL; |
| - match = EQUAL; |
| - } else { |
| - // For class ID ranges use a subtract followed by an unsigned |
| - // comparison to check both ends of the ranges with one comparison. |
| - __ addl(biased_cid, Immediate(bias - cid_start)); |
| - bias = cid_start; |
| - __ cmpl(biased_cid, Immediate(cid_end - cid_start)); |
| - no_match = ABOVE; |
| - match = BELOW_EQUAL; |
| - } |
| + // For class ID ranges use a subtract followed by an unsigned |
| + // comparison to check both ends of the ranges with one comparison. |
| + __ addl(biased_cid, Immediate(bias - cid_start)); |
| + bias = cid_start; |
| + __ cmpl(biased_cid, Immediate(cid_end - cid_start)); |
| + no_match = ABOVE; |
| + match = BELOW_EQUAL; |
| + } |
| - if (i == num_checks - 1) { |
| - __ j(no_match, deopt); |
| - } else { |
| - if (use_near_jump) { |
| - __ j(match, &is_ok, Assembler::kNearJump); |
| - } else { |
| - __ j(match, &is_ok); |
| - } |
| - } |
| + if (is_last) { |
| + __ j(no_match, deopt); |
| + } else { |
| + if (use_near_jump) { |
| + __ j(match, is_ok, Assembler::kNearJump); |
| + } else { |
| + __ j(match, is_ok); |
| } |
| } |
| - __ Bind(&is_ok); |
| + return bias; |
| } |