| 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 bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); | 5383 const intptr_t kNumTemps = !IsNullCheck() ? 1 : 0; |
| 5384 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; | |
| 5385 LocationSummary* summary = new(isolate) LocationSummary( | 5384 LocationSummary* summary = new(isolate) LocationSummary( |
| 5386 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5385 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5387 summary->set_in(0, Location::RequiresRegister()); | 5386 summary->set_in(0, Location::RequiresRegister()); |
| 5388 if (!IsNullCheck()) { | 5387 if (!IsNullCheck()) { |
| 5389 summary->set_temp(0, Location::RequiresRegister()); | 5388 summary->set_temp(0, Location::RequiresRegister()); |
| 5390 if (need_mask_temp) { | |
| 5391 summary->set_temp(1, Location::RequiresRegister()); | |
| 5392 } | |
| 5393 } | 5389 } |
| 5394 return summary; | 5390 return summary; |
| 5395 } | 5391 } |
| 5396 | 5392 |
| 5397 | 5393 |
| 5398 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5394 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5399 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? | 5395 const ICData::DeoptReasonId deopt_reason = licm_hoisted_ ? |
| 5400 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; | 5396 ICData::kDeoptHoistedCheckClass : ICData::kDeoptCheckClass; |
| 5401 if (IsNullCheck()) { | 5397 if (IsNullCheck()) { |
| 5402 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); | 5398 Label* deopt = compiler->AddDeoptStub(deopt_id(), deopt_reason); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5415 intptr_t cix = 0; | 5411 intptr_t cix = 0; |
| 5416 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { | 5412 if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) { |
| 5417 __ testq(value, Immediate(kSmiTagMask)); | 5413 __ testq(value, Immediate(kSmiTagMask)); |
| 5418 __ j(ZERO, &is_ok); | 5414 __ j(ZERO, &is_ok); |
| 5419 cix++; // Skip first check. | 5415 cix++; // Skip first check. |
| 5420 } else { | 5416 } else { |
| 5421 __ testq(value, Immediate(kSmiTagMask)); | 5417 __ testq(value, Immediate(kSmiTagMask)); |
| 5422 __ j(ZERO, deopt); | 5418 __ j(ZERO, deopt); |
| 5423 } | 5419 } |
| 5424 __ LoadClassId(temp, value); | 5420 __ LoadClassId(temp, value); |
| 5425 | 5421 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| 5426 if (IsDenseSwitch()) { | 5422 const bool use_near_jump = num_checks < 5; |
| 5427 ASSERT(cids_[0] < cids_[cids_.length() - 1]); | 5423 for (intptr_t i = cix; i < num_checks; i++) { |
| 5428 __ subq(temp, Immediate(cids_[0])); | 5424 ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid); |
| 5429 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0])); | 5425 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
| 5430 __ j(ABOVE, deopt); | 5426 if (i == (num_checks - 1)) { |
| 5431 | 5427 __ j(NOT_EQUAL, deopt); |
| 5432 intptr_t mask = ComputeCidMask(); | 5428 } else { |
| 5433 if (!IsDenseMask(mask)) { | 5429 if (use_near_jump) { |
| 5434 // Only need mask if there are missing numbers in the range. | 5430 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 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); | |
| 5449 } else { | 5431 } else { |
| 5450 if (use_near_jump) { | 5432 __ j(EQUAL, &is_ok); |
| 5451 __ j(EQUAL, &is_ok, Assembler::kNearJump); | |
| 5452 } else { | |
| 5453 __ j(EQUAL, &is_ok); | |
| 5454 } | |
| 5455 } | 5433 } |
| 5456 } | 5434 } |
| 5457 } | 5435 } |
| 5458 __ Bind(&is_ok); | 5436 __ Bind(&is_ok); |
| 5459 } | 5437 } |
| 5460 | 5438 |
| 5461 | 5439 |
| 5462 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, | 5440 LocationSummary* CheckSmiInstr::MakeLocationSummary(Isolate* isolate, |
| 5463 bool opt) const { | 5441 bool opt) const { |
| 5464 const intptr_t kNumInputs = 1; | 5442 const intptr_t kNumInputs = 1; |
| 5465 const intptr_t kNumTemps = 0; | 5443 const intptr_t kNumTemps = 0; |
| 5466 LocationSummary* summary = new(isolate) LocationSummary( | 5444 LocationSummary* summary = new(isolate) LocationSummary( |
| 5467 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5445 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5468 summary->set_in(0, Location::RequiresRegister()); | 5446 summary->set_in(0, Location::RequiresRegister()); |
| 5469 return summary; | 5447 return summary; |
| 5470 } | 5448 } |
| 5471 | 5449 |
| 5472 | 5450 |
| 5473 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5451 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5474 Register value = locs()->in(0).reg(); | 5452 Register value = locs()->in(0).reg(); |
| 5475 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); | 5453 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckSmi); |
| 5476 __ testq(value, Immediate(kSmiTagMask)); | 5454 __ testq(value, Immediate(kSmiTagMask)); |
| 5477 __ j(NOT_ZERO, deopt); | 5455 __ j(NOT_ZERO, deopt); |
| 5478 } | 5456 } |
| 5479 | 5457 |
| 5480 | 5458 |
| 5481 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Isolate* isolate, | |
| 5482 bool opt) const { | |
| 5483 const intptr_t kNumInputs = 2; | |
| 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 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | |
| 5489 return summary; | |
| 5490 } | |
| 5491 | |
| 5492 | |
| 5493 void CheckClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 5494 Register left = locs()->in(0).reg(); | |
| 5495 Location right = locs()->in(1); | |
| 5496 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass); | |
| 5497 if (right.IsRegister()) { | |
| 5498 __ cmpq(left, right.reg()); | |
| 5499 } else { | |
| 5500 ASSERT(right.IsConstant()); | |
| 5501 const Object& right_const = Smi::Cast(right.constant()); | |
| 5502 __ CompareImmediate( | |
| 5503 left, Immediate(reinterpret_cast<int64_t>(right_const.raw())), PP); | |
| 5504 } | |
| 5505 __ j(NOT_ZERO, deopt); | |
| 5506 } | |
| 5507 | |
| 5508 | |
| 5509 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, | 5459 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Isolate* isolate, |
| 5510 bool opt) const { | 5460 bool opt) const { |
| 5511 const intptr_t kNumInputs = 2; | 5461 const intptr_t kNumInputs = 2; |
| 5512 const intptr_t kNumTemps = 0; | 5462 const intptr_t kNumTemps = 0; |
| 5513 LocationSummary* locs = new(isolate) LocationSummary( | 5463 LocationSummary* locs = new(isolate) LocationSummary( |
| 5514 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 5464 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5515 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); | 5465 locs->set_in(kLengthPos, Location::RegisterOrSmiConstant(length())); |
| 5516 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); | 5466 locs->set_in(kIndexPos, Location::RegisterOrSmiConstant(index())); |
| 5517 return locs; | 5467 return locs; |
| 5518 } | 5468 } |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5912 __ movq(R10, Immediate(kInvalidObjectPointer)); | 5862 __ movq(R10, Immediate(kInvalidObjectPointer)); |
| 5913 __ movq(RBX, Immediate(kInvalidObjectPointer)); | 5863 __ movq(RBX, Immediate(kInvalidObjectPointer)); |
| 5914 #endif | 5864 #endif |
| 5915 } | 5865 } |
| 5916 | 5866 |
| 5917 } // namespace dart | 5867 } // namespace dart |
| 5918 | 5868 |
| 5919 #undef __ | 5869 #undef __ |
| 5920 | 5870 |
| 5921 #endif // defined TARGET_ARCH_X64 | 5871 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |