Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(553)

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 2149023002: VM: Array bounds checks that don't deoptimize for precompiled code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698