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