Chromium Code Reviews| 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 |