OLD | NEW |
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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 6117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6128 | 6128 |
6129 | 6129 |
6130 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6130 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6131 Register value = locs()->in(0).reg(); | 6131 Register value = locs()->in(0).reg(); |
6132 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | 6132 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
6133 __ CompareImmediate(value, Smi::RawValue(cid_)); | 6133 __ CompareImmediate(value, Smi::RawValue(cid_)); |
6134 __ b(deopt, NE); | 6134 __ b(deopt, NE); |
6135 } | 6135 } |
6136 | 6136 |
6137 | 6137 |
| 6138 LocationSummary* GenericCheckBoundInstr::MakeLocationSummary(Zone* zone, |
| 6139 bool opt) const { |
| 6140 const intptr_t kNumInputs = 2; |
| 6141 const intptr_t kNumTemps = 0; |
| 6142 LocationSummary* locs = new(zone) LocationSummary( |
| 6143 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 6144 locs->set_in(kLengthPos, Location::RequiresRegister()); |
| 6145 locs->set_in(kIndexPos, Location::RequiresRegister()); |
| 6146 return locs; |
| 6147 } |
| 6148 |
| 6149 |
| 6150 class RangeErrorSlowPath : public SlowPathCode { |
| 6151 public: |
| 6152 RangeErrorSlowPath(GenericCheckBoundInstr* instruction, intptr_t try_index) |
| 6153 : instruction_(instruction), try_index_(try_index) { } |
| 6154 |
| 6155 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6156 if (Assembler::EmittingComments()) { |
| 6157 __ Comment("slow path check bound operation"); |
| 6158 } |
| 6159 __ Bind(entry_label()); |
| 6160 LocationSummary* locs = instruction_->locs(); |
| 6161 __ Push(locs->in(0).reg()); |
| 6162 __ Push(locs->in(1).reg()); |
| 6163 compiler->GenerateRuntimeCall(instruction_->token_pos(), |
| 6164 instruction_->deopt_id(), |
| 6165 kRangeErrorRuntimeEntry, |
| 6166 2, |
| 6167 instruction_->locs()); |
| 6168 compiler->RecordSafepoint(locs, /* slow_path_argument_count = */ 2); |
| 6169 compiler->pc_descriptors_list()->AddDescriptor( |
| 6170 RawPcDescriptors::kOther, |
| 6171 compiler->assembler()->CodeSize(), |
| 6172 instruction_->deopt_id(), |
| 6173 instruction_->token_pos(), |
| 6174 try_index_); |
| 6175 __ bkpt(0); |
| 6176 } |
| 6177 |
| 6178 private: |
| 6179 GenericCheckBoundInstr* instruction_; |
| 6180 intptr_t try_index_; |
| 6181 }; |
| 6182 |
| 6183 |
| 6184 void GenericCheckBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 6185 RangeErrorSlowPath* slow_path = |
| 6186 new RangeErrorSlowPath(this, compiler->CurrentTryIndex()); |
| 6187 compiler->AddSlowPathCode(slow_path); |
| 6188 |
| 6189 Location length_loc = locs()->in(kLengthPos); |
| 6190 Location index_loc = locs()->in(kIndexPos); |
| 6191 Register length = length_loc.reg(); |
| 6192 Register index = index_loc.reg(); |
| 6193 const intptr_t index_cid = this->index()->Type()->ToCid(); |
| 6194 if (index_cid != kSmiCid) { |
| 6195 __ tst(index, Operand(kSmiTagMask)); |
| 6196 __ b(slow_path->entry_label(), NE); |
| 6197 } |
| 6198 __ cmp(index, Operand(length)); |
| 6199 __ b(slow_path->entry_label(), CS); |
| 6200 } |
| 6201 |
| 6202 |
6138 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, | 6203 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone, |
6139 bool opt) const { | 6204 bool opt) const { |
6140 const intptr_t kNumInputs = 2; | 6205 const intptr_t kNumInputs = 2; |
6141 const intptr_t kNumTemps = 0; | 6206 const intptr_t kNumTemps = 0; |
6142 LocationSummary* locs = new(zone) LocationSummary( | 6207 LocationSummary* locs = new(zone) LocationSummary( |
6143 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6208 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6144 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 6209 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
6145 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 6210 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
6146 return locs; | 6211 return locs; |
6147 } | 6212 } |
(...skipping 13 matching lines...) Expand all Loading... |
6161 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 6226 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
6162 ASSERT((Smi::Cast(length_loc.constant()).Value() <= | 6227 ASSERT((Smi::Cast(length_loc.constant()).Value() <= |
6163 Smi::Cast(index_loc.constant()).Value()) || | 6228 Smi::Cast(index_loc.constant()).Value()) || |
6164 (Smi::Cast(index_loc.constant()).Value() < 0)); | 6229 (Smi::Cast(index_loc.constant()).Value() < 0)); |
6165 // Unconditionally deoptimize for constant bounds checks because they | 6230 // Unconditionally deoptimize for constant bounds checks because they |
6166 // only occur only when index is out-of-bounds. | 6231 // only occur only when index is out-of-bounds. |
6167 __ b(deopt); | 6232 __ b(deopt); |
6168 return; | 6233 return; |
6169 } | 6234 } |
6170 | 6235 |
| 6236 const intptr_t index_cid = index()->Type()->ToCid(); |
6171 if (index_loc.IsConstant()) { | 6237 if (index_loc.IsConstant()) { |
6172 const Register length = length_loc.reg(); | 6238 const Register length = length_loc.reg(); |
6173 const Smi& index = Smi::Cast(index_loc.constant()); | 6239 const Smi& index = Smi::Cast(index_loc.constant()); |
6174 __ CompareImmediate(length, reinterpret_cast<int32_t>(index.raw())); | 6240 __ CompareImmediate(length, reinterpret_cast<int32_t>(index.raw())); |
6175 __ b(deopt, LS); | 6241 __ b(deopt, LS); |
6176 } else if (length_loc.IsConstant()) { | 6242 } else if (length_loc.IsConstant()) { |
6177 const Smi& length = Smi::Cast(length_loc.constant()); | 6243 const Smi& length = Smi::Cast(length_loc.constant()); |
6178 const Register index = index_loc.reg(); | 6244 const Register index = index_loc.reg(); |
| 6245 if (index_cid != kSmiCid) { |
| 6246 __ tst(index, Operand(kSmiTagMask)); |
| 6247 __ b(deopt, NE); |
| 6248 } |
6179 if (length.Value() == Smi::kMaxValue) { | 6249 if (length.Value() == Smi::kMaxValue) { |
6180 __ tst(index, Operand(index)); | 6250 __ tst(index, Operand(index)); |
6181 __ b(deopt, MI); | 6251 __ b(deopt, MI); |
6182 } else { | 6252 } else { |
6183 __ CompareImmediate(index, reinterpret_cast<int32_t>(length.raw())); | 6253 __ CompareImmediate(index, reinterpret_cast<int32_t>(length.raw())); |
6184 __ b(deopt, CS); | 6254 __ b(deopt, CS); |
6185 } | 6255 } |
6186 } else { | 6256 } else { |
6187 const Register length = length_loc.reg(); | 6257 const Register length = length_loc.reg(); |
6188 const Register index = index_loc.reg(); | 6258 const Register index = index_loc.reg(); |
| 6259 if (index_cid != kSmiCid) { |
| 6260 __ tst(index, Operand(kSmiTagMask)); |
| 6261 __ b(deopt, NE); |
| 6262 } |
6189 __ cmp(index, Operand(length)); | 6263 __ cmp(index, Operand(length)); |
6190 __ b(deopt, CS); | 6264 __ b(deopt, CS); |
6191 } | 6265 } |
6192 } | 6266 } |
6193 | 6267 |
6194 | 6268 |
6195 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, | 6269 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Zone* zone, |
6196 bool opt) const { | 6270 bool opt) const { |
6197 const intptr_t kNumInputs = 2; | 6271 const intptr_t kNumInputs = 2; |
6198 const intptr_t kNumTemps = 0; | 6272 const intptr_t kNumTemps = 0; |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6947 1, | 7021 1, |
6948 locs()); | 7022 locs()); |
6949 __ Drop(1); | 7023 __ Drop(1); |
6950 __ Pop(result); | 7024 __ Pop(result); |
6951 } | 7025 } |
6952 | 7026 |
6953 | 7027 |
6954 } // namespace dart | 7028 } // namespace dart |
6955 | 7029 |
6956 #endif // defined TARGET_ARCH_ARM | 7030 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |