| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 5428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5439 const Register value = locs()->in(0).reg(); | 5439 const Register value = locs()->in(0).reg(); |
| 5440 const Register temp = locs()->temp(0).reg(); | 5440 const Register temp = locs()->temp(0).reg(); |
| 5441 Label is_ok; | 5441 Label is_ok; |
| 5442 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { | 5442 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) { |
| 5443 __ tsti(value, Immediate(kSmiTagMask)); | 5443 __ tsti(value, Immediate(kSmiTagMask)); |
| 5444 __ b(&is_ok, EQ); | 5444 __ b(&is_ok, EQ); |
| 5445 } else { | 5445 } else { |
| 5446 __ tsti(value, Immediate(kSmiTagMask)); | 5446 __ tsti(value, Immediate(kSmiTagMask)); |
| 5447 __ b(deopt, EQ); | 5447 __ b(deopt, EQ); |
| 5448 } | 5448 } |
| 5449 __ LoadClassId(temp, value); | 5449 Register biased_cid = temp; |
| 5450 __ LoadClassId(biased_cid, value); |
| 5450 | 5451 |
| 5451 if (IsDenseSwitch()) { | 5452 GrowableArray<CidRangeTarget> sorted_ic_data; |
| 5453 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| 5454 /* drop_smi = */ true); |
| 5455 |
| 5456 if (sorted_ic_data.length() > 4 && IsDenseSwitch()) { |
| 5452 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5457 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| 5453 __ AddImmediate(temp, temp, -cids_[0]); | 5458 __ AddImmediate(biased_cid, biased_cid, -cids_[0]); |
| 5454 __ CompareImmediate(temp, cids_[cids_.length() - 1] - cids_[0]); | 5459 __ CompareImmediate(biased_cid, cids_[cids_.length() - 1] - cids_[0]); |
| 5455 __ b(deopt, HI); | 5460 __ b(deopt, HI); |
| 5456 | 5461 |
| 5457 intptr_t mask = ComputeCidMask(); | 5462 intptr_t mask = ComputeCidMask(); |
| 5458 if (!IsDenseMask(mask)) { | 5463 if (!IsDenseMask(mask)) { |
| 5459 // Only need mask if there are missing numbers in the range. | 5464 // Only need mask if there are missing numbers in the range. |
| 5460 ASSERT(cids_.length() > 2); | 5465 ASSERT(cids_.length() > 2); |
| 5461 Register mask_reg = locs()->temp(1).reg(); | 5466 Register mask_reg = locs()->temp(1).reg(); |
| 5462 __ LoadImmediate(mask_reg, 1); | 5467 __ LoadImmediate(mask_reg, 1); |
| 5463 __ lslv(mask_reg, mask_reg, temp); | 5468 __ lslv(mask_reg, mask_reg, biased_cid); |
| 5464 __ TestImmediate(mask_reg, mask); | 5469 __ TestImmediate(mask_reg, mask); |
| 5465 __ b(deopt, EQ); | 5470 __ b(deopt, EQ); |
| 5466 } | 5471 } |
| 5467 | 5472 |
| 5468 } else { | 5473 } else { |
| 5469 GrowableArray<CidTarget> sorted_ic_data; | |
| 5470 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, | |
| 5471 /* drop_smi = */ true); | |
| 5472 const intptr_t num_checks = sorted_ic_data.length(); | 5474 const intptr_t num_checks = sorted_ic_data.length(); |
| 5475 int bias = 0; |
| 5473 for (intptr_t i = 0; i < num_checks; i++) { | 5476 for (intptr_t i = 0; i < num_checks; i++) { |
| 5474 const intptr_t cid = sorted_ic_data[i].cid; | 5477 const intptr_t cid_start = sorted_ic_data[i].cid_start; |
| 5475 ASSERT(cid != kSmiCid); | 5478 const intptr_t cid_end = sorted_ic_data[i].cid_end; |
| 5476 __ CompareImmediate(temp, cid); | 5479 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid); |
| 5480 Condition no_match, match; |
| 5481 if (cid_start == cid_end) { |
| 5482 __ CompareImmediate(biased_cid, cid_start - bias); |
| 5483 no_match = NE; |
| 5484 match = EQ; |
| 5485 } else { |
| 5486 // For class ID ranges use a subtract followed by an unsigned |
| 5487 // comparison to check both ends of the ranges with one comparison. |
| 5488 __ AddImmediate(biased_cid, biased_cid, bias - cid_start); |
| 5489 bias = cid_start; |
| 5490 __ CompareImmediate(biased_cid, cid_end - cid_start); |
| 5491 no_match = HI; // Unsigned higher. |
| 5492 match = LS; // Unsigned lower or same. |
| 5493 } |
| 5477 if (i == (num_checks - 1)) { | 5494 if (i == (num_checks - 1)) { |
| 5478 __ b(deopt, NE); | 5495 __ b(deopt, no_match); |
| 5479 } else { | 5496 } else { |
| 5480 __ b(&is_ok, EQ); | 5497 __ b(&is_ok, match); |
| 5481 } | 5498 } |
| 5482 } | 5499 } |
| 5483 } | 5500 } |
| 5484 __ Bind(&is_ok); | 5501 __ Bind(&is_ok); |
| 5485 } | 5502 } |
| 5486 | 5503 |
| 5487 | 5504 |
| 5488 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, | 5505 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, |
| 5489 bool opt) const { | 5506 bool opt) const { |
| 5490 const intptr_t kNumInputs = 1; | 5507 const intptr_t kNumInputs = 1; |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6019 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), | 6036 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), |
| 6020 kGrowRegExpStackRuntimeEntry, 1, locs()); | 6037 kGrowRegExpStackRuntimeEntry, 1, locs()); |
| 6021 __ Drop(1); | 6038 __ Drop(1); |
| 6022 __ Pop(result); | 6039 __ Pop(result); |
| 6023 } | 6040 } |
| 6024 | 6041 |
| 6025 | 6042 |
| 6026 } // namespace dart | 6043 } // namespace dart |
| 6027 | 6044 |
| 6028 #endif // defined TARGET_ARCH_ARM64 | 6045 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |