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