Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 181183004: VM: Improve receiver class check in polymorphic inlining. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: improved polymorphic ClassCheck ia32 Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 4563 matching lines...) Expand 10 before | Expand all | Expand 10 after
4574 } 4574 }
4575 4575
4576 4576
4577 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { 4577 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
4578 const intptr_t kNumInputs = 1; 4578 const intptr_t kNumInputs = 1;
4579 const intptr_t kNumTemps = 0; 4579 const intptr_t kNumTemps = 0;
4580 LocationSummary* summary = 4580 LocationSummary* summary =
4581 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4581 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4582 summary->set_in(0, Location::RequiresRegister()); 4582 summary->set_in(0, Location::RequiresRegister());
4583 if (!IsNullCheck()) { 4583 if (!IsNullCheck()) {
4584 if (IsDenseSwitch()) {
4585 summary->AddTemp(Location::RegisterLocation(ECX));
4586 }
4584 summary->AddTemp(Location::RequiresRegister()); 4587 summary->AddTemp(Location::RequiresRegister());
4585 } 4588 }
4586 return summary; 4589 return summary;
4587 } 4590 }
4588 4591
4589 4592
4590 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4593 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4591 const DeoptReasonId deopt_reason = 4594 const DeoptReasonId deopt_reason =
4592 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass; 4595 licm_hoisted_ ? kDeoptHoistedCheckClass : kDeoptCheckClass;
4593 if (IsNullCheck()) { 4596 if (IsNullCheck()) {
(...skipping 14 matching lines...) Expand all
4608 intptr_t cix = 0; 4611 intptr_t cix = 0;
4609 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { 4612 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) {
4610 __ testl(value, Immediate(kSmiTagMask)); 4613 __ testl(value, Immediate(kSmiTagMask));
4611 __ j(ZERO, &is_ok); 4614 __ j(ZERO, &is_ok);
4612 cix++; // Skip first check. 4615 cix++; // Skip first check.
4613 } else { 4616 } else {
4614 __ testl(value, Immediate(kSmiTagMask)); 4617 __ testl(value, Immediate(kSmiTagMask));
4615 __ j(ZERO, deopt); 4618 __ j(ZERO, deopt);
4616 } 4619 }
4617 __ LoadClassId(temp, value); 4620 __ LoadClassId(temp, value);
4618 const intptr_t num_checks = unary_checks().NumberOfChecks(); 4621
4619 const bool use_near_jump = num_checks < 5; 4622 if (IsDenseSwitch()) {
4620 for (intptr_t i = cix; i < num_checks; i++) { 4623 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
4621 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); 4624 ASSERT(temp == ECX);
4622 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); 4625 Register mask_reg = locs()->temp(1).reg();
4623 if (i == (num_checks - 1)) { 4626 __ subl(temp, Immediate(cids_[0]));
4624 __ j(NOT_EQUAL, deopt); 4627 __ cmpl(temp, Immediate(cids_[cids_.length() - 1] - cids_[0]));
4625 } else { 4628 __ j(ABOVE, deopt);
4626 if (use_near_jump) { 4629 __ movl(mask_reg, Immediate(1));
4627 __ j(EQUAL, &is_ok, Assembler::kNearJump); 4630 __ shll(mask_reg, temp);
4631 intptr_t mask = 0;
4632 for (intptr_t i = 0; i < cids_.length(); ++i) {
4633 mask |= 1 << (cids_[i] - cids_[0]);
4634 }
4635 __ andl(mask_reg, Immediate(mask));
4636 __ j(ZERO, deopt);
4637 } else {
4638 const intptr_t num_checks = cids_.length();
4639 const bool use_near_jump = num_checks < 5;
4640 for (intptr_t i = cix; i < num_checks; i++) {
4641 ASSERT(cids_[i] != kSmiCid);
4642 __ cmpl(temp, Immediate(cids_[i]));
4643 if (i == (num_checks - 1)) {
4644 __ j(NOT_EQUAL, deopt);
4628 } else { 4645 } else {
4629 __ j(EQUAL, &is_ok); 4646 if (use_near_jump) {
4647 __ j(EQUAL, &is_ok, Assembler::kNearJump);
4648 } else {
4649 __ j(EQUAL, &is_ok);
4650 }
4630 } 4651 }
4631 } 4652 }
4632 } 4653 }
4633 __ Bind(&is_ok); 4654 __ Bind(&is_ok);
4634 } 4655 }
4635 4656
4636 4657
4637 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const { 4658 LocationSummary* CheckSmiInstr::MakeLocationSummary(bool opt) const {
4638 const intptr_t kNumInputs = 1; 4659 const intptr_t kNumInputs = 1;
4639 const intptr_t kNumTemps = 0; 4660 const intptr_t kNumTemps = 0;
4640 LocationSummary* summary = 4661 LocationSummary* summary =
4641 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4662 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4642 summary->set_in(0, Location::RequiresRegister()); 4663 summary->set_in(0, Location::RequiresRegister());
4643 return summary; 4664 return summary;
4644 } 4665 }
4645 4666
4646 4667
4647 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4668 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4648 Register value = locs()->in(0).reg(); 4669 Register value = locs()->in(0).reg();
4649 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4670 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4650 kDeoptCheckSmi); 4671 kDeoptCheckSmi);
4651 __ testl(value, Immediate(kSmiTagMask)); 4672 __ testl(value, Immediate(kSmiTagMask));
4652 __ j(NOT_ZERO, deopt); 4673 __ j(NOT_ZERO, deopt);
4653 } 4674 }
4654 4675
4655 4676
4677 LocationSummary* CheckClassIdInstr::MakeLocationSummary(bool opt) const {
4678 const intptr_t kNumInputs = 2;
4679 const intptr_t kNumTemps = 0;
4680 LocationSummary* summary =
4681 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4682 summary->set_in(0, Location::RequiresRegister());
4683 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
4684 return summary;
4685 }
4686
4687
4688 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4689 Register left = locs()->in(0).reg();
4690 Location right = locs()->in(1);
4691 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptCheckClass);
4692 if (right.IsRegister()) {
4693 __ cmpl(left, right.reg());
4694 } else {
4695 ASSERT(right.IsConstant());
4696 const Object& right_const = Smi::Cast(right.constant());
4697 __ cmpl(left, Immediate(reinterpret_cast<int32_t>(right_const.raw())));
4698 }
4699 __ j(NOT_ZERO, deopt);
4700 }
4701
4702
4656 // Length: register or constant. 4703 // Length: register or constant.
4657 // Index: register, constant or stack slot. 4704 // Index: register, constant or stack slot.
4658 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const { 4705 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(bool opt) const {
4659 const intptr_t kNumInputs = 2; 4706 const intptr_t kNumInputs = 2;
4660 const intptr_t kNumTemps = 0; 4707 const intptr_t kNumTemps = 0;
4661 LocationSummary* locs = 4708 LocationSummary* locs =
4662 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4709 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4663 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); 4710 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length()));
4664 ConstantInstr* index_constant = index()->definition()->AsConstant(); 4711 ConstantInstr* index_constant = index()->definition()->AsConstant();
4665 if (index_constant != NULL) { 4712 if (index_constant != NULL) {
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
5379 PcDescriptors::kOther, 5426 PcDescriptors::kOther,
5380 locs()); 5427 locs());
5381 __ Drop(2); // Discard type arguments and receiver. 5428 __ Drop(2); // Discard type arguments and receiver.
5382 } 5429 }
5383 5430
5384 } // namespace dart 5431 } // namespace dart
5385 5432
5386 #undef __ 5433 #undef __
5387 5434
5388 #endif // defined TARGET_ARCH_IA32 5435 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698