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

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: Created 6 years, 5 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 5464 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698