| 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 5468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5479 | 5479 |
| 5480 | 5480 |
| 5481 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5481 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5482 comparison()->EmitBranchCode(compiler, this); | 5482 comparison()->EmitBranchCode(compiler, this); |
| 5483 } | 5483 } |
| 5484 | 5484 |
| 5485 | 5485 |
| 5486 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, | 5486 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, |
| 5487 bool opt) const { | 5487 bool opt) const { |
| 5488 const intptr_t kNumInputs = 1; | 5488 const intptr_t kNumInputs = 1; |
| 5489 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 5489 const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; |
| 5490 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | |
| 5491 LocationSummary* summary = new(isolate) LocationSummary( | 5490 LocationSummary* summary = new(isolate) LocationSummary( |
| 5492 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5491 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5493 summary->set_in(0, Location::RequiresRegister()); | 5492 summary->set_in(0, Location::RequiresRegister()); |
| 5494 if (!IsNullCheck()) { | 5493 if (!IsNullCheck()) { |
| 5495 summary->set_temp(0, Location::RequiresRegister()); | 5494 summary->set_temp(0, Location::RequiresRegister()); |
| 5496 if (need_mask_temp) { | |
| 5497 summary->set_temp(1, Location::RequiresRegister()); | |
| 5498 } | |
| 5499 } | 5495 } |
| 5500 return summary; | 5496 return summary; |
| 5501 } | 5497 } |
| 5502 | 5498 |
| 5503 | 5499 |
| 5504 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5500 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5505 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5501 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5506 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5502 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5507 if (IsNullCheck()) { | 5503 if (IsNullCheck()) { |
| 5508 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5504 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5522 intptr_t cix = 0; | 5518 intptr_t cix = 0; |
| 5523 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5519 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 5524 __ testl(value, Immediate(kSmiTagMask)); | 5520 __ testl(value, Immediate(kSmiTagMask)); |
| 5525 __ j(ZERO, &is_ok); | 5521 __ j(ZERO, &is_ok); |
| 5526 cix++; // Skip first check. | 5522 cix++; // Skip first check. |
| 5527 } else { | 5523 } else { |
| 5528 __ testl(value, Immediate(kSmiTagMask)); | 5524 __ testl(value, Immediate(kSmiTagMask)); |
| 5529 __ j(ZERO, deopt); | 5525 __ j(ZERO, deopt); |
| 5530 } | 5526 } |
| 5531 __ LoadClassId(temp, value); | 5527 __ LoadClassId(temp, value); |
| 5532 | 5528 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 5533 if (IsDenseSwitch()) { | 5529 const bool use_near_jump = num_checks < 5; |
| 5534 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5530 for (intptr_t i = cix; i < num_checks; i++) { |
| 5535 __ subl(temp, Immediate(cids_[0])); | 5531 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| 5536 __ cmpl(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); | 5532 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| 5537 __ j(ABOVE, deopt); | 5533 if (i == (num_checks - 1)) { |
| 5538 | 5534 __ j(NOT_EQUAL, deopt); |
| 5539 intptr_t mask = ComputeCidMask(); | 5535 } else { |
| 5540 if (!IsDenseMask(mask)) { | 5536 if (use_near_jump) { |
| 5541 // Only need mask if there are missing numbers in the range. | 5537 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 5542 ASSERT(cids_.length() > 2); | |
| 5543 Register mask_reg = locs()->temp(1).reg(); | |
| 5544 __ movl(mask_reg, Immediate(mask)); | |
| 5545 __ bt(mask_reg, temp); | |
| 5546 __ j(NOT_CARRY, deopt); | |
| 5547 } | |
| 5548 } else { | |
| 5549 const intptr_t num_checks = cids_.length(); | |
| 5550 const bool use_near_jump = num_checks < 5; | |
| 5551 for (intptr_t i = cix; i < num_checks; i++) { | |
| 5552 ASSERT(cids_[i] != kSmiCid); | |
| 5553 __ cmpl(temp, Immediate(cids_[i])); | |
| 5554 if (i == (num_checks - 1)) { | |
| 5555 __ j(NOT_EQUAL, deopt); | |
| 5556 } else { | 5538 } else { |
| 5557 if (use_near_jump) { | 5539 __ j(EQUAL, &is_ok); |
| 5558 __ j(EQUAL, &is_ok, Assembler::kNearJump); | |
| 5559 } else { | |
| 5560 __ j(EQUAL, &is_ok); | |
| 5561 } | |
| 5562 } | 5540 } |
| 5563 } | 5541 } |
| 5564 } | 5542 } |
| 5565 __ Bind(&is_ok); | 5543 __ Bind(&is_ok); |
| 5566 } | 5544 } |
| 5567 | 5545 |
| 5568 | 5546 |
| 5569 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 5547 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5570 bool opt) const { | 5548 bool opt) const { |
| 5571 const intptr_t kNumInputs = 1; | 5549 const intptr_t kNumInputs = 1; |
| 5572 const intptr_t kNumTemps = 0; | 5550 const intptr_t kNumTemps = 0; |
| 5573 LocationSummary* summary = new(isolate) LocationSummary( | 5551 LocationSummary* summary = new(isolate) LocationSummary( |
| 5574 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5552 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5575 summary->set_in(0, Location::RequiresRegister()); | 5553 summary->set_in(0, Location::RequiresRegister()); |
| 5576 return summary; | 5554 return summary; |
| 5577 } | 5555 } |
| 5578 | 5556 |
| 5579 | 5557 |
| 5580 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5558 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5581 Register value = locs()->in(0).reg(); | 5559 Register value = locs()->in(0).reg(); |
| 5582 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5560 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5583 __ testl(value, Immediate(kSmiTagMask)); | 5561 __ testl(value, Immediate(kSmiTagMask)); |
| 5584 __ j(NOT_ZERO, deopt); | 5562 __ j(NOT_ZERO, deopt); |
| 5585 } | 5563 } |
| 5586 | 5564 |
| 5587 | 5565 |
| 5588 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, | |
| 5589 bool opt) const { | |
| 5590 const intptr_t kNumInputs = 2; | |
| 5591 const intptr_t kNumTemps = 0; | |
| 5592 LocationSummary* summary = new(isolate) LocationSummary( | |
| 5593 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 5594 summary->set_in(0, Location::RequiresRegister()); | |
| 5595 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | |
| 5596 return summary; | |
| 5597 } | |
| 5598 | |
| 5599 | |
| 5600 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5601 Register left = locs()->in(0).reg(); | |
| 5602 Location right = locs()->in(1); | |
| 5603 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | |
| 5604 if (right.IsRegister()) { | |
| 5605 __ cmpl(left, right.reg()); | |
| 5606 } else { | |
| 5607 ASSERT(right.IsConstant()); | |
| 5608 const Object& right_const = Smi::Cast(right.constant()); | |
| 5609 __ cmpl(left, Immediate(reinterpret_cast<int32_t>(right_const.raw()))); | |
| 5610 } | |
| 5611 __ j(NOT_ZERO, deopt); | |
| 5612 } | |
| 5613 | |
| 5614 | |
| 5615 // Length: register or constant. | 5566 // Length: register or constant. |
| 5616 // Index: register, constant or stack slot. | 5567 // Index: register, constant or stack slot. |
| 5617 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5568 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 5618 bool opt) const { | 5569 bool opt) const { |
| 5619 const intptr_t kNumInputs = 2; | 5570 const intptr_t kNumInputs = 2; |
| 5620 const intptr_t kNumTemps = 0; | 5571 const intptr_t kNumTemps = 0; |
| 5621 LocationSummary* locs = new(isolate) LocationSummary( | 5572 LocationSummary* locs = new(isolate) LocationSummary( |
| 5622 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5573 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5623 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5574 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5624 ConstantInstr* index_constant = index()->definition()->AsConstant(); | 5575 ConstantInstr* index_constant = index()->definition()->AsConstant(); |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6412 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6363 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6413 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6364 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6414 #endif | 6365 #endif |
| 6415 } | 6366 } |
| 6416 | 6367 |
| 6417 } // namespace dart | 6368 } // namespace dart |
| 6418 | 6369 |
| 6419 #undef __ | 6370 #undef __ |
| 6420 | 6371 |
| 6421 #endif // defined TARGET_ARCH_IA32 | 6372 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |