| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4574 } | 4574 } |
| 4575 | 4575 |
| 4576 | 4576 |
| 4577 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { | 4577 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { |
| 4578 const intptr_t kNumInputs = 1; | 4578 const intptr_t kNumInputs = 1; |
| 4579 const intptr_t kNumTemps = 0; | 4579 const intptr_t kNumTemps = 0; |
| 4580 LocationSummary* summary = | 4580 LocationSummary* summary = |
| 4581 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4581 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4582 summary->set_in(0, Location::RequiresRegister()); | 4582 summary->set_in(0, Location::RequiresRegister()); |
| 4583 if (!IsNullCheck()) { | 4583 if (!IsNullCheck()) { |
| 4584 if (IsDenseSwitch()) { |
| 4585 summary->AddTemp(Location::RegisterLocation(ECX)); |
| 4586 } |
| 4584 summary->AddTemp(Location::RequiresRegister()); | 4587 summary->AddTemp(Location::RequiresRegister()); |
| 4585 } | 4588 } |
| 4586 return summary; | 4589 return summary; |
| 4587 } | 4590 } |
| 4588 | 4591 |
| 4589 | 4592 |
| 4590 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4593 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4591 const DeoptReasonId deopt_reason = | 4594 const DeoptReasonId deopt_reason = |
| 4592 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; | 4595 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; |
| 4593 if (IsNullCheck()) { | 4596 if (IsNullCheck()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4608 intptr_t cix = 0; | 4611 intptr_t cix = 0; |
| 4609 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 4612 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 4610 __ testl(value, Immediate(kSmiTagMask)); | 4613 __ testl(value, Immediate(kSmiTagMask)); |
| 4611 __ j(ZERO, &is_ok); | 4614 __ j(ZERO, &is_ok); |
| 4612 cix++; // Skip first check. | 4615 cix++; // Skip first check. |
| 4613 } else { | 4616 } else { |
| 4614 __ testl(value, Immediate(kSmiTagMask)); | 4617 __ testl(value, Immediate(kSmiTagMask)); |
| 4615 __ j(ZERO, deopt); | 4618 __ j(ZERO, deopt); |
| 4616 } | 4619 } |
| 4617 __ LoadClassId(temp, value); | 4620 __ LoadClassId(temp, value); |
| 4618 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 4621 |
| 4619 const bool use_near_jump = num_checks < 5; | 4622 if (IsDenseSwitch()) { |
| 4620 for (intptr_t i = cix; i < num_checks; i++) { | 4623 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| 4621 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | 4624 ASSERT(temp == ECX); |
| 4622 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); | 4625 Register mask_reg = locs()->temp(1).reg(); |
| 4623 if (i == (num_checks - 1)) { | 4626 __ subl(temp, Immediate(cids_[0])); |
| 4624 __ j(NOT_EQUAL, deopt); | 4627 __ cmpl(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); |
| 4625 } else { | 4628 __ j(ABOVE, deopt); |
| 4626 if (use_near_jump) { | 4629 __ movl(mask_reg, Immediate(1)); |
| 4627 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 4630 __ shll(mask_reg, temp); |
| 4631 intptr_t mask = 0; |
| 4632 for (intptr_t i = 0; i < cids_.length(); ++i) { |
| 4633 mask |= 1 << (cids_[i] - cids_[0]); |
| 4634 } |
| 4635 __ andl(mask_reg, Immediate(mask)); |
| 4636 __ j(ZERO, deopt); |
| 4637 } else { |
| 4638 const intptr_t num_checks = cids_.length(); |
| 4639 const bool use_near_jump = num_checks < 5; |
| 4640 for (intptr_t i = cix; i < num_checks; i++) { |
| 4641 ASSERT(cids_[i] != kSmiCid); |
| 4642 __ cmpl(temp, Immediate(cids_[i])); |
| 4643 if (i == (num_checks - 1)) { |
| 4644 __ j(NOT_EQUAL, deopt); |
| 4628 } else { | 4645 } else { |
| 4629 __ j(EQUAL, &is_ok); | 4646 if (use_near_jump) { |
| 4647 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 4648 } else { |
| 4649 __ j(EQUAL, &is_ok); |
| 4650 } |
| 4630 } | 4651 } |
| 4631 } | 4652 } |
| 4632 } | 4653 } |
| 4633 __ Bind(&is_ok); | 4654 __ Bind(&is_ok); |
| 4634 } | 4655 } |
| 4635 | 4656 |
| 4636 | 4657 |
| 4637 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { | 4658 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { |
| 4638 const intptr_t kNumInputs = 1; | 4659 const intptr_t kNumInputs = 1; |
| 4639 const intptr_t kNumTemps = 0; | 4660 const intptr_t kNumTemps = 0; |
| 4640 LocationSummary* summary = | 4661 LocationSummary* summary = |
| 4641 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4662 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4642 summary->set_in(0, Location::RequiresRegister()); | 4663 summary->set_in(0, Location::RequiresRegister()); |
| 4643 return summary; | 4664 return summary; |
| 4644 } | 4665 } |
| 4645 | 4666 |
| 4646 | 4667 |
| 4647 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4668 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4648 Register value = locs()->in(0).reg(); | 4669 Register value = locs()->in(0).reg(); |
| 4649 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 4670 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 4650 kDeoptCheckSmi); | 4671 kDeoptCheckSmi); |
| 4651 __ testl(value, Immediate(kSmiTagMask)); | 4672 __ testl(value, Immediate(kSmiTagMask)); |
| 4652 __ j(NOT_ZERO, deopt); | 4673 __ j(NOT_ZERO, deopt); |
| 4653 } | 4674 } |
| 4654 | 4675 |
| 4655 | 4676 |
| 4677 LocationSummary* CheckClassIdInstr::MakeLocationSummary(bool opt) const { |
| 4678 const intptr_t kNumInputs = 2; |
| 4679 const intptr_t kNumTemps = 0; |
| 4680 LocationSummary* summary = |
| 4681 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4682 summary->set_in(0, Location::RequiresRegister()); |
| 4683 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 4684 return summary; |
| 4685 } |
| 4686 |
| 4687 |
| 4688 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4689 Register left = locs()->in(0).reg(); |
| 4690 Location right = locs()->in(1); |
| 4691 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckClass); |
| 4692 if (right.IsRegister()) { |
| 4693 __ cmpl(left, right.reg()); |
| 4694 } else { |
| 4695 ASSERT(right.IsConstant()); |
| 4696 const Object& right_const = Smi::Cast(right.constant()); |
| 4697 __ cmpl(left, Immediate(reinterpret_cast<int32_t>(right_const.raw()))); |
| 4698 } |
| 4699 __ j(NOT_ZERO, deopt); |
| 4700 } |
| 4701 |
| 4702 |
| 4656 // Length: register or constant. | 4703 // Length: register or constant. |
| 4657 // Index: register, constant or stack slot. | 4704 // Index: register, constant or stack slot. |
| 4658 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { | 4705 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { |
| 4659 const intptr_t kNumInputs = 2; | 4706 const intptr_t kNumInputs = 2; |
| 4660 const intptr_t kNumTemps = 0; | 4707 const intptr_t kNumTemps = 0; |
| 4661 LocationSummary* locs = | 4708 LocationSummary* locs = |
| 4662 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4709 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4663 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 4710 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 4664 ConstantInstr* index_constant = index()->definition()->AsConstant(); | 4711 ConstantInstr* index_constant = index()->definition()->AsConstant(); |
| 4665 if (index_constant != NULL) { | 4712 if (index_constant != NULL) { |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5379 PcDescriptors::kOther, | 5426 PcDescriptors::kOther, |
| 5380 locs()); | 5427 locs()); |
| 5381 __ Drop(2); // Discard type arguments and receiver. | 5428 __ Drop(2); // Discard type arguments and receiver. |
| 5382 } | 5429 } |
| 5383 | 5430 |
| 5384 } // namespace dart | 5431 } // namespace dart |
| 5385 | 5432 |
| 5386 #undef __ | 5433 #undef __ |
| 5387 | 5434 |
| 5388 #endif // defined TARGET_ARCH_IA32 | 5435 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |