Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 38118) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -5486,12 +5486,16 @@ |
| LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, |
| bool opt) const { |
| const intptr_t kNumInputs = 1; |
| - const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; |
| + const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); |
| + const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
| LocationSummary* summary = new(isolate) LocationSummary( |
| isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| summary->set_in(0, Location::RequiresRegister()); |
| if (!IsNullCheck()) { |
| summary->set_temp(0, Location::RequiresRegister()); |
| + if (need_mask_temp) { |
| + summary->set_temp(1, Location::RequiresRegister()); |
| + } |
| } |
| return summary; |
| } |
| @@ -5525,18 +5529,36 @@ |
| __ j(ZERO, deopt); |
| } |
| __ LoadClassId(temp, value); |
| - const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| - const bool use_near_jump = num_checks < 5; |
| - for (intptr_t i = cix; i < num_checks; i++) { |
| - ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| - __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| - if (i == (num_checks - 1)) { |
| - __ j(NOT_EQUAL, deopt); |
| - } else { |
| - if (use_near_jump) { |
| - __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| + |
| + if (IsDenseSwitch()) { |
| + ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| + __ subl(temp, Immediate(cids_[0])); |
| + __ cmpl(temp, 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, temp); |
| + __ j(NOT_CARRY, deopt); |
| + } |
| + } else { |
| + const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| + const bool use_near_jump = num_checks < 5; |
| + for (intptr_t i = cix; i < num_checks; i++) { |
| + ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
|
Florian Schneider
2014/07/10 15:10:13
Used unary_checks() instead of cids_ here.
|
| + __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| + if (i == (num_checks - 1)) { |
| + __ j(NOT_EQUAL, deopt); |
| } else { |
| - __ j(EQUAL, &is_ok); |
| + if (use_near_jump) { |
| + __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| + } else { |
| + __ j(EQUAL, &is_ok); |
| + } |
| } |
| } |
| } |
| @@ -5563,6 +5585,33 @@ |
| } |
| +LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, |
| + bool opt) const { |
| + const intptr_t kNumInputs = 2; |
| + const intptr_t kNumTemps = 0; |
| + LocationSummary* summary = new(isolate) LocationSummary( |
| + isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| + summary->set_in(0, Location::RequiresRegister()); |
| + summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| + return summary; |
| +} |
| + |
| + |
| +void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| + Register left = locs()->in(0).reg(); |
| + Location right = locs()->in(1); |
| + Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
| + if (right.IsRegister()) { |
| + __ cmpl(left, right.reg()); |
| + } else { |
| + ASSERT(right.IsConstant()); |
| + const Object& right_const = Smi::Cast(right.constant()); |
| + __ cmpl(left, Immediate(reinterpret_cast<int32_t>(right_const.raw()))); |
| + } |
| + __ j(NOT_ZERO, deopt); |
| +} |
| + |
| + |
| // Length: register or constant. |
| // Index: register, constant or stack slot. |
| LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |