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