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); |
| 5451 |
| 5452 GrowableArray<CidRangeTarget> sorted_ic_data; |
| 5453 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data, |
| 5454 /* drop_smi = */ true); |
5450 | 5455 |
5451 if (IsDenseSwitch()) { | 5456 if (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 |