| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 5362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5373 | 5373 |
| 5374 | 5374 |
| 5375 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5375 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5376 comparison()->EmitBranchCode(compiler, this); | 5376 comparison()->EmitBranchCode(compiler, this); |
| 5377 } | 5377 } |
| 5378 | 5378 |
| 5379 | 5379 |
| 5380 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, | 5380 LocationSummary* CheckClassInstr::MakeLocationSummary(Isolate* isolate, |
| 5381 bool opt) const { | 5381 bool opt) const { |
| 5382 const intptr_t kNumInputs = 1; | 5382 const intptr_t kNumInputs = 1; |
| 5383 const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; | 5383 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); |
| 5384 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; |
| 5384 LocationSummary* summary = new(isolate) LocationSummary( | 5385 LocationSummary* summary = new(isolate) LocationSummary( |
| 5385 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5386 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5386 summary->set_in(0, Location::RequiresRegister()); | 5387 summary->set_in(0, Location::RequiresRegister()); |
| 5387 if (!IsNullCheck()) { | 5388 if (!IsNullCheck()) { |
| 5388 summary->set_temp(0, Location::RequiresRegister()); | 5389 summary->set_temp(0, Location::RequiresRegister()); |
| 5390 if (need_mask_temp) { |
| 5391 summary->set_temp(1, Location::RequiresRegister()); |
| 5392 } |
| 5389 } | 5393 } |
| 5390 return summary; | 5394 return summary; |
| 5391 } | 5395 } |
| 5392 | 5396 |
| 5393 | 5397 |
| 5394 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5398 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5395 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5399 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5396 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5400 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5397 if (IsNullCheck()) { | 5401 if (IsNullCheck()) { |
| 5398 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5402 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5411 intptr_t cix = 0; | 5415 intptr_t cix = 0; |
| 5412 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5416 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 5413 __ testq(value, Immediate(kSmiTagMask)); | 5417 __ testq(value, Immediate(kSmiTagMask)); |
| 5414 __ j(ZERO, &is_ok); | 5418 __ j(ZERO, &is_ok); |
| 5415 cix++; // Skip first check. | 5419 cix++; // Skip first check. |
| 5416 } else { | 5420 } else { |
| 5417 __ testq(value, Immediate(kSmiTagMask)); | 5421 __ testq(value, Immediate(kSmiTagMask)); |
| 5418 __ j(ZERO, deopt); | 5422 __ j(ZERO, deopt); |
| 5419 } | 5423 } |
| 5420 __ LoadClassId(temp, value); | 5424 __ LoadClassId(temp, value); |
| 5421 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 5425 |
| 5422 const bool use_near_jump = num_checks < 5; | 5426 if (IsDenseSwitch()) { |
| 5423 for (intptr_t i = cix; i < num_checks; i++) { | 5427 ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
| 5424 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); | 5428 __ subq(temp, Immediate(cids_[0])); |
| 5425 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); | 5429 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); |
| 5426 if (i == (num_checks - 1)) { | 5430 __ j(ABOVE, deopt); |
| 5427 __ j(NOT_EQUAL, deopt); | 5431 |
| 5428 } else { | 5432 intptr_t mask = ComputeCidMask(); |
| 5429 if (use_near_jump) { | 5433 if (!IsDenseMask(mask)) { |
| 5430 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 5434 // Only need mask if there are missing numbers in the range. |
| 5435 ASSERT(cids_.length() > 2); |
| 5436 Register mask_reg = locs()->temp(1).reg(); |
| 5437 __ movq(mask_reg, Immediate(mask)); |
| 5438 __ btq(mask_reg, temp); |
| 5439 __ j(NOT_CARRY, deopt); |
| 5440 } |
| 5441 } else { |
| 5442 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 5443 const bool use_near_jump = num_checks < 5; |
| 5444 for (intptr_t i = cix; i < num_checks; i++) { |
| 5445 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| 5446 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| 5447 if (i == (num_checks - 1)) { |
| 5448 __ j(NOT_EQUAL, deopt); |
| 5431 } else { | 5449 } else { |
| 5432 __ j(EQUAL, &is_ok); | 5450 if (use_near_jump) { |
| 5451 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 5452 } else { |
| 5453 __ j(EQUAL, &is_ok); |
| 5454 } |
| 5433 } | 5455 } |
| 5434 } | 5456 } |
| 5435 } | 5457 } |
| 5436 __ Bind(&is_ok); | 5458 __ Bind(&is_ok); |
| 5437 } | 5459 } |
| 5438 | 5460 |
| 5439 | 5461 |
| 5440 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 5462 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5441 bool opt) const { | 5463 bool opt) const { |
| 5442 const intptr_t kNumInputs = 1; | 5464 const intptr_t kNumInputs = 1; |
| 5443 const intptr_t kNumTemps = 0; | 5465 const intptr_t kNumTemps = 0; |
| 5444 LocationSummary* summary = new(isolate) LocationSummary( | 5466 LocationSummary* summary = new(isolate) LocationSummary( |
| 5445 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5467 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5446 summary->set_in(0, Location::RequiresRegister()); | 5468 summary->set_in(0, Location::RequiresRegister()); |
| 5447 return summary; | 5469 return summary; |
| 5448 } | 5470 } |
| 5449 | 5471 |
| 5450 | 5472 |
| 5451 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5473 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5452 Register value = locs()->in(0).reg(); | 5474 Register value = locs()->in(0).reg(); |
| 5453 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5475 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5454 __ testq(value, Immediate(kSmiTagMask)); | 5476 __ testq(value, Immediate(kSmiTagMask)); |
| 5455 __ j(NOT_ZERO, deopt); | 5477 __ j(NOT_ZERO, deopt); |
| 5456 } | 5478 } |
| 5457 | 5479 |
| 5458 | 5480 |
| 5481 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, |
| 5482 bool opt) const { |
| 5483 const intptr_t kNumInputs = 1; |
| 5484 const intptr_t kNumTemps = 0; |
| 5485 LocationSummary* summary = new(isolate) LocationSummary( |
| 5486 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5487 summary->set_in(0, Location::RequiresRegister()); |
| 5488 return summary; |
| 5489 } |
| 5490 |
| 5491 |
| 5492 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5493 Register value = locs()->in(0).reg(); |
| 5494 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); |
| 5495 __ CompareImmediate(value, Immediate(Smi::RawValue(cid_)), PP); |
| 5496 __ j(NOT_ZERO, deopt); |
| 5497 } |
| 5498 |
| 5499 |
| 5459 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5500 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 5460 bool opt) const { | 5501 bool opt) const { |
| 5461 const intptr_t kNumInputs = 2; | 5502 const intptr_t kNumInputs = 2; |
| 5462 const intptr_t kNumTemps = 0; | 5503 const intptr_t kNumTemps = 0; |
| 5463 LocationSummary* locs = new(isolate) LocationSummary( | 5504 LocationSummary* locs = new(isolate) LocationSummary( |
| 5464 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5505 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5465 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5506 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5466 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5507 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5467 return locs; | 5508 return locs; |
| 5468 } | 5509 } |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5862 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5903 __ movq(R10, Immediate(kInvalidObjectPointer)); |
| 5863 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5904 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
| 5864 #endif | 5905 #endif |
| 5865 } | 5906 } |
| 5866 | 5907 |
| 5867 } // namespace dart | 5908 } // namespace dart |
| 5868 | 5909 |
| 5869 #undef __ | 5910 #undef __ |
| 5870 | 5911 |
| 5871 #endif // defined TARGET_ARCH_X64 | 5912 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |