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