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 5445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5456 summary->set_temp(0, Location::RequiresRegister()); | 5456 summary->set_temp(0, Location::RequiresRegister()); |
5457 if (need_mask_temp) { | 5457 if (need_mask_temp) { |
5458 summary->set_temp(1, Location::RequiresRegister()); | 5458 summary->set_temp(1, Location::RequiresRegister()); |
5459 } | 5459 } |
5460 } | 5460 } |
5461 return summary; | 5461 return summary; |
5462 } | 5462 } |
5463 | 5463 |
5464 | 5464 |
5465 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5465 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5466 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5466 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
5467 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5467 ICData::kDeoptCheckClass, |
5468 licm_hoisted_ ? ICData::kHoisted : 0); | |
5468 if (IsNullCheck()) { | 5469 if (IsNullCheck()) { |
5469 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | |
5470 const Immediate& raw_null = | 5470 const Immediate& raw_null = |
5471 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 5471 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
5472 __ cmpl(locs()->in(0).reg(), raw_null); | 5472 __ cmpl(locs()->in(0).reg(), raw_null); |
5473 __ j(EQUAL, deopt); | 5473 __ j(EQUAL, deopt); |
5474 return; | 5474 return; |
5475 } | 5475 } |
5476 | 5476 |
5477 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || | 5477 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
5478 (unary_checks().NumberOfChecks() > 1)); | 5478 (unary_checks().NumberOfChecks() > 1)); |
5479 Register value = locs()->in(0).reg(); | 5479 Register value = locs()->in(0).reg(); |
5480 Register temp = locs()->temp(0).reg(); | 5480 Register temp = locs()->temp(0).reg(); |
5481 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | |
5482 Label is_ok; | 5481 Label is_ok; |
5483 intptr_t cix = 0; | 5482 intptr_t cix = 0; |
5484 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5483 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
5485 __ testl(value, Immediate(kSmiTagMask)); | 5484 __ testl(value, Immediate(kSmiTagMask)); |
5486 __ j(ZERO, &is_ok); | 5485 __ j(ZERO, &is_ok); |
5487 cix++; // Skip first check. | 5486 cix++; // Skip first check. |
5488 } else { | 5487 } else { |
5489 __ testl(value, Immediate(kSmiTagMask)); | 5488 __ testl(value, Immediate(kSmiTagMask)); |
5490 __ j(ZERO, deopt); | 5489 __ j(ZERO, deopt); |
5491 } | 5490 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5577 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5576 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
5578 } else { | 5577 } else { |
5579 locs->set_in(kLengthPos, Location::PrefersRegister()); | 5578 locs->set_in(kLengthPos, Location::PrefersRegister()); |
5580 } | 5579 } |
5581 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5580 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
5582 return locs; | 5581 return locs; |
5583 } | 5582 } |
5584 | 5583 |
5585 | 5584 |
5586 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5585 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5587 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 5586 Label* deopt = compiler->AddDeoptStub( |
5588 ICData::kDeoptCheckArrayBound); | 5587 deopt_id(), |
5588 ICData::kDeoptCheckArrayBound, | |
5589 generalized_ ? ICData::kGeneralized : 0); | |
5589 | 5590 |
5590 Location length_loc = locs()->in(kLengthPos); | 5591 Location length_loc = locs()->in(kLengthPos); |
5591 Location index_loc = locs()->in(kIndexPos); | 5592 Location index_loc = locs()->in(kIndexPos); |
5592 | 5593 |
5593 if (length_loc.IsConstant() && index_loc.IsConstant()) { | 5594 if (length_loc.IsConstant() && index_loc.IsConstant()) { |
5594 ASSERT((Smi::Cast(length_loc.constant()).Value() <= | 5595 ASSERT((Smi::Cast(length_loc.constant()).Value() <= |
5595 Smi::Cast(index_loc.constant()).Value()) || | 5596 Smi::Cast(index_loc.constant()).Value()) || |
5596 (Smi::Cast(index_loc.constant()).Value() < 0)); | 5597 (Smi::Cast(index_loc.constant()).Value() < 0)); |
5597 // Unconditionally deoptimize for constant bounds checks because they | 5598 // Unconditionally deoptimize for constant bounds checks because they |
5598 // only occur only when index is out-of-bounds. | 5599 // only occur only when index is out-of-bounds. |
5599 __ jmp(deopt); | 5600 __ jmp(deopt); |
5600 return; | 5601 return; |
5601 } | 5602 } |
5602 | 5603 |
5603 if (length_loc.IsConstant()) { | 5604 if (length_loc.IsConstant()) { |
5604 Register index = index_loc.reg(); | 5605 Register index = index_loc.reg(); |
5605 const Smi& length = Smi::Cast(length_loc.constant()); | 5606 const Smi& length = Smi::Cast(length_loc.constant()); |
5606 __ cmpl(index, Immediate(reinterpret_cast<int32_t>(length.raw()))); | 5607 if (length.Value() == Smi::kMaxValue) { |
5607 __ j(ABOVE_EQUAL, deopt); | 5608 __ testl(index, index); |
5609 __ j(NEGATIVE, deopt); | |
5610 } else { | |
5611 __ cmpl(index, Immediate(reinterpret_cast<int32_t>(length.raw()))); | |
5612 __ j(ABOVE_EQUAL, deopt); | |
5613 } | |
regis
2014/12/17 22:00:39
Slava,
I stumbled upon this code and do not quite
| |
5608 } else if (index_loc.IsConstant()) { | 5614 } else if (index_loc.IsConstant()) { |
5609 const Smi& index = Smi::Cast(index_loc.constant()); | 5615 const Smi& index = Smi::Cast(index_loc.constant()); |
5610 if (length_loc.IsStackSlot()) { | 5616 if (length_loc.IsStackSlot()) { |
5611 const Address& length = length_loc.ToStackSlotAddress(); | 5617 const Address& length = length_loc.ToStackSlotAddress(); |
5612 __ cmpl(length, Immediate(reinterpret_cast<int32_t>(index.raw()))); | 5618 __ cmpl(length, Immediate(reinterpret_cast<int32_t>(index.raw()))); |
5613 } else { | 5619 } else { |
5614 Register length = length_loc.reg(); | 5620 Register length = length_loc.reg(); |
5615 __ cmpl(length, Immediate(reinterpret_cast<int32_t>(index.raw()))); | 5621 __ cmpl(length, Immediate(reinterpret_cast<int32_t>(index.raw()))); |
5616 } | 5622 } |
5617 __ j(BELOW_EQUAL, deopt); | 5623 __ j(BELOW_EQUAL, deopt); |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6771 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6777 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6772 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6778 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
6773 #endif | 6779 #endif |
6774 } | 6780 } |
6775 | 6781 |
6776 } // namespace dart | 6782 } // namespace dart |
6777 | 6783 |
6778 #undef __ | 6784 #undef __ |
6779 | 6785 |
6780 #endif // defined TARGET_ARCH_IA32 | 6786 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |