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 |