OLD | NEW |
1 | 1 |
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
7 #if defined(TARGET_ARCH_ARM) | 7 #if defined(TARGET_ARCH_ARM) |
8 | 8 |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 | 10 |
(...skipping 6287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6298 | 6298 |
6299 | 6299 |
6300 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6300 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6301 comparison()->EmitBranchCode(compiler, this); | 6301 comparison()->EmitBranchCode(compiler, this); |
6302 } | 6302 } |
6303 | 6303 |
6304 | 6304 |
6305 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, | 6305 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, |
6306 bool opt) const { | 6306 bool opt) const { |
6307 const intptr_t kNumInputs = 1; | 6307 const intptr_t kNumInputs = 1; |
6308 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 6308 const bool need_mask_temp = IsBitTest(); |
6309 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | 6309 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
6310 LocationSummary* summary = new (zone) | 6310 LocationSummary* summary = new (zone) |
6311 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6311 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6312 summary->set_in(0, Location::RequiresRegister()); | 6312 summary->set_in(0, Location::RequiresRegister()); |
6313 if (!IsNullCheck()) { | 6313 if (!IsNullCheck()) { |
6314 summary->set_temp(0, Location::RequiresRegister()); | 6314 summary->set_temp(0, Location::RequiresRegister()); |
6315 if (need_mask_temp) { | 6315 if (need_mask_temp) { |
6316 summary->set_temp(1, Location::RequiresRegister()); | 6316 summary->set_temp(1, Location::RequiresRegister()); |
6317 } | 6317 } |
6318 } | 6318 } |
6319 return summary; | 6319 return summary; |
6320 } | 6320 } |
6321 | 6321 |
6322 | 6322 |
6323 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6323 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) { |
6324 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, | 6324 __ CompareObject(locs()->in(0).reg(), Object::null_object()); |
6325 licm_hoisted_ ? ICData::kHoisted : 0); | 6325 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull()); |
6326 if (IsNullCheck()) { | 6326 Condition cond = IsDeoptIfNull() ? EQ : NE; |
6327 __ CompareObject(locs()->in(0).reg(), Object::null_object()); | 6327 __ b(deopt, cond); |
6328 ASSERT(DeoptIfNull() || DeoptIfNotNull()); | 6328 return; |
6329 Condition cond = DeoptIfNull() ? EQ : NE; | |
6330 __ b(deopt, cond); | |
6331 return; | |
6332 } | |
6333 | |
6334 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | |
6335 (unary_checks().NumberOfChecks() > 1)); | |
6336 const Register value = locs()->in(0).reg(); | |
6337 const Register temp = locs()->temp(0).reg(); | |
6338 Label is_ok; | |
6339 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | |
6340 __ tst(value, Operand(kSmiTagMask)); | |
6341 __ b(&is_ok, EQ); | |
6342 } else { | |
6343 __ tst(value, Operand(kSmiTagMask)); | |
6344 __ b(deopt, EQ); | |
6345 } | |
6346 Register biased_cid = temp; | |
6347 __ LoadClassId(biased_cid, value); | |
6348 | |
6349 GrowableArray<CidRangeTarget> sorted_ic_data; | |
6350 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
6351 /* drop_smi = */ true); | |
6352 | |
6353 if (IsDenseSwitch()) { | |
6354 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | |
6355 __ AddImmediate(biased_cid, -cids_[0]); | |
6356 __ CompareImmediate(biased_cid, cids_[cids_.length() - 1] - cids_[0]); | |
6357 __ b(deopt, HI); | |
6358 | |
6359 intptr_t mask = ComputeCidMask(); | |
6360 if (!IsDenseMask(mask)) { | |
6361 // Only need mask if there are missing numbers in the range. | |
6362 ASSERT(cids_.length() > 2); | |
6363 Register mask_reg = locs()->temp(1).reg(); | |
6364 __ LoadImmediate(mask_reg, 1); | |
6365 __ Lsl(mask_reg, mask_reg, biased_cid); | |
6366 __ TestImmediate(mask_reg, mask); | |
6367 __ b(deopt, EQ); | |
6368 } | |
6369 } else { | |
6370 const intptr_t num_checks = sorted_ic_data.length(); | |
6371 int bias = 0; | |
6372 for (intptr_t i = 0; i < num_checks; i++) { | |
6373 const intptr_t cid_start = sorted_ic_data[i].cid_start; | |
6374 const intptr_t cid_end = sorted_ic_data[i].cid_end; | |
6375 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); | |
6376 Condition no_match, match; | |
6377 if (cid_start == cid_end) { | |
6378 __ CompareImmediate(biased_cid, cid_start - bias); | |
6379 no_match = NE; | |
6380 match = EQ; | |
6381 } else { | |
6382 // For class ID ranges use a subtract followed by an unsigned | |
6383 // comparison to check both ends of the ranges with one comparison. | |
6384 __ AddImmediate(biased_cid, biased_cid, bias - cid_start); | |
6385 bias = cid_start; | |
6386 __ CompareImmediate(biased_cid, cid_end - cid_start); | |
6387 no_match = HI; // Unsigned higher. | |
6388 match = LS; // Unsigned lower or same. | |
6389 } | |
6390 if (i == (num_checks - 1)) { | |
6391 __ b(deopt, no_match); | |
6392 } else { | |
6393 __ b(&is_ok, match); | |
6394 } | |
6395 } | |
6396 } | |
6397 __ Bind(&is_ok); | |
6398 } | 6329 } |
6399 | 6330 |
6400 | 6331 |
| 6332 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler, |
| 6333 intptr_t min, |
| 6334 intptr_t max, |
| 6335 intptr_t mask, |
| 6336 Label* deopt) { |
| 6337 Register biased_cid = locs()->temp(0).reg(); |
| 6338 __ AddImmediate(biased_cid, -min); |
| 6339 __ CompareImmediate(biased_cid, max - min); |
| 6340 __ b(deopt, HI); |
| 6341 |
| 6342 Register bit_reg = locs()->temp(1).reg(); |
| 6343 __ LoadImmediate(bit_reg, 1); |
| 6344 __ Lsl(bit_reg, bit_reg, biased_cid); |
| 6345 __ TestImmediate(bit_reg, mask); |
| 6346 __ b(deopt, EQ); |
| 6347 } |
| 6348 |
| 6349 |
| 6350 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler, |
| 6351 int bias, |
| 6352 intptr_t cid_start, |
| 6353 intptr_t cid_end, |
| 6354 bool is_last, |
| 6355 Label* is_ok, |
| 6356 Label* deopt, |
| 6357 bool use_near_jump) { |
| 6358 Register biased_cid = locs()->temp(0).reg(); |
| 6359 Condition no_match, match; |
| 6360 if (cid_start == cid_end) { |
| 6361 __ CompareImmediate(biased_cid, cid_start - bias); |
| 6362 no_match = NE; |
| 6363 match = EQ; |
| 6364 } else { |
| 6365 // For class ID ranges use a subtract followed by an unsigned |
| 6366 // comparison to check both ends of the ranges with one comparison. |
| 6367 __ AddImmediate(biased_cid, biased_cid, bias - cid_start); |
| 6368 bias = cid_start; |
| 6369 __ CompareImmediate(biased_cid, cid_end - cid_start); |
| 6370 no_match = HI; // Unsigned higher. |
| 6371 match = LS; // Unsigned lower or same. |
| 6372 } |
| 6373 if (is_last) { |
| 6374 __ b(deopt, no_match); |
| 6375 } else { |
| 6376 __ b(is_ok, match); |
| 6377 } |
| 6378 return bias; |
| 6379 } |
| 6380 |
| 6381 |
6401 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, | 6382 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, |
6402 bool opt) const { | 6383 bool opt) const { |
6403 const intptr_t kNumInputs = 1; | 6384 const intptr_t kNumInputs = 1; |
6404 const intptr_t kNumTemps = 0; | 6385 const intptr_t kNumTemps = 0; |
6405 LocationSummary* summary = new (zone) | 6386 LocationSummary* summary = new (zone) |
6406 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6387 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6407 summary->set_in(0, Location::RequiresRegister()); | 6388 summary->set_in(0, Location::RequiresRegister()); |
6408 return summary; | 6389 return summary; |
6409 } | 6390 } |
6410 | 6391 |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7289 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 7270 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
7290 kGrowRegExpStackRuntimeEntry, 1, locs()); | 7271 kGrowRegExpStackRuntimeEntry, 1, locs()); |
7291 __ Drop(1); | 7272 __ Drop(1); |
7292 __ Pop(result); | 7273 __ Pop(result); |
7293 } | 7274 } |
7294 | 7275 |
7295 | 7276 |
7296 } // namespace dart | 7277 } // namespace dart |
7297 | 7278 |
7298 #endif // defined TARGET_ARCH_ARM | 7279 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |