Index: runtime/vm/intermediate_language_mips.cc |
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc |
index 342e267f6a438de6ea9edc5fa4bbca72e6aec53f..645273fe83fe62fd3838009dba530ef4d2982a79 100644 |
--- a/runtime/vm/intermediate_language_mips.cc |
+++ b/runtime/vm/intermediate_language_mips.cc |
@@ -4836,8 +4836,7 @@ void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
Label* deopt = compiler->AddDeoptStub(deopt_id(), |
ICData::kDeoptCheckSmi, |
licm_hoisted_ ? ICData::kHoisted : 0); |
- __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
- __ bne(CMPRES1, ZR, deopt); |
+ __ BranchIfNotSmi(value, deopt); |
} |
@@ -4859,6 +4858,64 @@ void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} |
+LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, |
+ bool opt) const { |
+ const intptr_t kNumInputs = 2; |
+ const intptr_t kNumTemps = 0; |
+ LocationSummary* locs = new(zone) LocationSummary( |
+ zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
+ locs->set_in(kLengthPos, Location::RequiresRegister()); |
+ locs->set_in(kIndexPos, Location::RequiresRegister()); |
+ return locs; |
+} |
+ |
+ |
+class RangeErrorSlowPath : public SlowPathCode { |
+ public: |
+ RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) |
+ : instruction_(instruction), try_index_(try_index) { } |
+ |
+ virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
+ if (Assembler::EmittingComments()) { |
+ __ Comment("slow path check bound operation"); |
+ } |
+ __ Bind(entry_label()); |
+ LocationSummary* locs = instruction_->locs(); |
+ __ Push(locs->in(0).reg()); |
+ __ Push(locs->in(1).reg()); |
+ __ CallRuntime(kRangeErrorRuntimeEntry, 2); |
+ compiler->pc_descriptors_list()->AddDescriptor( |
+ RawPcDescriptors::kOther, |
+ compiler->assembler()->CodeSize(), |
+ instruction_->deopt_id(), |
+ instruction_->token_pos(), |
+ try_index_); |
+ __ break_(0); |
+ } |
+ |
+ private: |
+ GenericCheckBoundInstr* instruction_; |
+ intptr_t try_index_; |
+}; |
+ |
+ |
+void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ RangeErrorSlowPath* slow_path = |
+ new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); |
+ compiler->AddSlowPathCode(slow_path); |
+ |
+ Location length_loc = locs()->in(kLengthPos); |
+ Location index_loc = locs()->in(kIndexPos); |
+ Register length = length_loc.reg(); |
+ Register index = index_loc.reg(); |
+ const intptr_t index_cid = this->index()->Type()->ToCid(); |
+ if (index_cid != kSmiCid) { |
+ __ BranchIfNotSmi(index, slow_path->entry_label()); |
+ } |
+ __ BranchUnsignedGreaterEqual(index, length, slow_path->entry_label()); |
+} |
+ |
+ |
LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, |
bool opt) const { |
const intptr_t kNumInputs = 2; |
@@ -4892,6 +4949,7 @@ void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
return; |
} |
+ const intptr_t index_cid = index()->Type()->ToCid(); |
if (index_loc.IsConstant()) { |
Register length = length_loc.reg(); |
const Smi& index = Smi::Cast(index_loc.constant()); |
@@ -4900,6 +4958,9 @@ void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} else if (length_loc.IsConstant()) { |
const Smi& length = Smi::Cast(length_loc.constant()); |
Register index = index_loc.reg(); |
+ if (index_cid != kSmiCid) { |
+ __ BranchIfNotSmi(index, deopt); |
+ } |
if (length.Value() == Smi::kMaxValue) { |
__ BranchSignedLess(index, Immediate(0), deopt); |
} else { |
@@ -4909,6 +4970,9 @@ void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} else { |
Register length = length_loc.reg(); |
Register index = index_loc.reg(); |
+ if (index_cid != kSmiCid) { |
+ __ BranchIfNotSmi(index, deopt); |
+ } |
__ BranchUnsignedGreaterEqual(index, length, deopt); |
} |
} |