| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 case BELOW_EQUAL: return ABOVE; | 116 case BELOW_EQUAL: return ABOVE; |
| 117 case ABOVE: return BELOW_EQUAL; | 117 case ABOVE: return BELOW_EQUAL; |
| 118 case ABOVE_EQUAL: return BELOW; | 118 case ABOVE_EQUAL: return BELOW; |
| 119 default: | 119 default: |
| 120 UNIMPLEMENTED(); | 120 UNIMPLEMENTED(); |
| 121 return EQUAL; | 121 return EQUAL; |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 static bool BindsToSmiConstant(Value* val, intptr_t* smi_value) { | |
| 127 if (!val->BindsToConstant()) { | |
| 128 return false; | |
| 129 } | |
| 130 | |
| 131 const Object& bound_constant = val->BoundConstant(); | |
| 132 if (!bound_constant.IsSmi()) { | |
| 133 return false; | |
| 134 } | |
| 135 | |
| 136 *smi_value = Smi::Cast(bound_constant).Value(); | |
| 137 return true; | |
| 138 } | |
| 139 | |
| 140 | |
| 141 // Detect pattern when one value is zero and another is a power of 2. | 126 // Detect pattern when one value is zero and another is a power of 2. |
| 142 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { | 127 static bool IsPowerOfTwoKind(intptr_t v1, intptr_t v2) { |
| 143 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || | 128 return (Utils::IsPowerOfTwo(v1) && (v2 == 0)) || |
| 144 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); | 129 (Utils::IsPowerOfTwo(v2) && (v1 == 0)); |
| 145 } | 130 } |
| 146 | 131 |
| 147 | 132 |
| 148 bool IfThenElseInstr::Supports(ComparisonInstr* comparison, | |
| 149 Value* v1, | |
| 150 Value* v2) { | |
| 151 if (!(comparison->IsStrictCompare() && | |
| 152 !comparison->AsStrictCompare()->needs_number_check()) && | |
| 153 !(comparison->IsEqualityCompare() && | |
| 154 (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) { | |
| 155 return false; | |
| 156 } | |
| 157 | |
| 158 intptr_t v1_value, v2_value; | |
| 159 | |
| 160 if (!BindsToSmiConstant(v1, &v1_value) || | |
| 161 !BindsToSmiConstant(v2, &v2_value)) { | |
| 162 return false; | |
| 163 } | |
| 164 | |
| 165 return false; | |
| 166 } | |
| 167 | |
| 168 | |
| 169 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { | 133 LocationSummary* IfThenElseInstr::MakeLocationSummary() const { |
| 170 const intptr_t kNumInputs = 2; | 134 const intptr_t kNumInputs = 2; |
| 171 const intptr_t kNumTemps = 0; | 135 const intptr_t kNumTemps = 0; |
| 172 LocationSummary* locs = | 136 LocationSummary* locs = |
| 173 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 137 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 174 locs->set_in(0, Location::RegisterOrConstant(left())); | 138 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 175 locs->set_in(1, Location::RegisterOrConstant(right())); | 139 locs->set_in(1, Location::RegisterOrConstant(right())); |
| 176 // TODO(vegorov): support byte register constraints in the register allocator. | 140 // TODO(vegorov): support byte register constraints in the register allocator. |
| 177 locs->set_out(Location::RegisterLocation(RDX)); | 141 locs->set_out(Location::RegisterLocation(RDX)); |
| 178 return locs; | 142 return locs; |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 case BELOW_EQUAL: return ABOVE_EQUAL; | 402 case BELOW_EQUAL: return ABOVE_EQUAL; |
| 439 case ABOVE: return BELOW; | 403 case ABOVE: return BELOW; |
| 440 case ABOVE_EQUAL: return BELOW_EQUAL; | 404 case ABOVE_EQUAL: return BELOW_EQUAL; |
| 441 default: | 405 default: |
| 442 UNIMPLEMENTED(); | 406 UNIMPLEMENTED(); |
| 443 return EQUAL; | 407 return EQUAL; |
| 444 } | 408 } |
| 445 } | 409 } |
| 446 | 410 |
| 447 | 411 |
| 412 static void EmitBranchOnValue(FlowGraphCompiler* compiler, |
| 413 TargetEntryInstr* true_successor, |
| 414 TargetEntryInstr* false_successor, |
| 415 bool value) { |
| 416 if (value && !compiler->CanFallThroughTo(true_successor)) { |
| 417 __ jmp(compiler->GetJumpLabel(true_successor)); |
| 418 } else if (!value && !compiler->CanFallThroughTo(false_successor)) { |
| 419 __ jmp(compiler->GetJumpLabel(false_successor)); |
| 420 } |
| 421 } |
| 422 |
| 423 |
| 424 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 425 TargetEntryInstr* true_successor, |
| 426 TargetEntryInstr* false_successor, |
| 427 Condition true_condition) { |
| 428 if (compiler->CanFallThroughTo(false_successor)) { |
| 429 // If the next block is the false successor, fall through to it. |
| 430 __ j(true_condition, compiler->GetJumpLabel(true_successor)); |
| 431 } else { |
| 432 // If the next block is not the false successor, branch to it. |
| 433 Condition false_condition = NegateCondition(true_condition); |
| 434 __ j(false_condition, compiler->GetJumpLabel(false_successor)); |
| 435 |
| 436 // Fall through or jump to the true successor. |
| 437 if (!compiler->CanFallThroughTo(true_successor)) { |
| 438 __ jmp(compiler->GetJumpLabel(true_successor)); |
| 439 } |
| 440 } |
| 441 } |
| 442 |
| 443 |
| 448 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 444 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
| 449 const LocationSummary& locs, | 445 const LocationSummary& locs, |
| 450 Token::Kind kind, | 446 Token::Kind kind, |
| 451 BranchInstr* branch) { | 447 BranchInstr* branch) { |
| 452 Location left = locs.in(0); | 448 Location left = locs.in(0); |
| 453 Location right = locs.in(1); | 449 Location right = locs.in(1); |
| 454 ASSERT(!left.IsConstant() || !right.IsConstant()); | 450 ASSERT(!left.IsConstant() || !right.IsConstant()); |
| 455 | 451 |
| 456 Condition true_condition = TokenKindToSmiCondition(kind); | 452 Condition true_condition = TokenKindToSmiCondition(kind); |
| 457 | 453 |
| 458 if (left.IsConstant()) { | 454 if (left.IsConstant()) { |
| 459 __ CompareObject(right.reg(), left.constant(), PP); | 455 __ CompareObject(right.reg(), left.constant(), PP); |
| 460 true_condition = FlipCondition(true_condition); | 456 true_condition = FlipCondition(true_condition); |
| 461 } else if (right.IsConstant()) { | 457 } else if (right.IsConstant()) { |
| 462 __ CompareObject(left.reg(), right.constant(), PP); | 458 __ CompareObject(left.reg(), right.constant(), PP); |
| 463 } else if (right.IsStackSlot()) { | 459 } else if (right.IsStackSlot()) { |
| 464 __ cmpq(left.reg(), right.ToStackSlotAddress()); | 460 __ cmpq(left.reg(), right.ToStackSlotAddress()); |
| 465 } else { | 461 } else { |
| 466 __ cmpq(left.reg(), right.reg()); | 462 __ cmpq(left.reg(), right.reg()); |
| 467 } | 463 } |
| 468 | 464 |
| 469 if (branch != NULL) { | 465 if (branch != NULL) { |
| 470 branch->EmitBranchOnCondition(compiler, true_condition); | 466 EmitBranchOnCondition(compiler, |
| 467 branch->true_successor(), |
| 468 branch->false_successor(), |
| 469 true_condition); |
| 471 } else { | 470 } else { |
| 472 Register result = locs.out().reg(); | 471 Register result = locs.out().reg(); |
| 473 Label done, is_true; | 472 Label done, is_true; |
| 474 __ j(true_condition, &is_true); | 473 __ j(true_condition, &is_true); |
| 475 __ LoadObject(result, Bool::False(), PP); | 474 __ LoadObject(result, Bool::False(), PP); |
| 476 __ jmp(&done); | 475 __ jmp(&done); |
| 477 __ Bind(&is_true); | 476 __ Bind(&is_true); |
| 478 __ LoadObject(result, Bool::True(), PP); | 477 __ LoadObject(result, Bool::True(), PP); |
| 479 __ Bind(&done); | 478 __ Bind(&done); |
| 480 } | 479 } |
| 481 } | 480 } |
| 482 | 481 |
| 483 | 482 |
| 484 static Condition TokenKindToDoubleCondition(Token::Kind kind) { | 483 static Condition TokenKindToDoubleCondition(Token::Kind kind) { |
| 485 switch (kind) { | 484 switch (kind) { |
| 486 case Token::kEQ: return EQUAL; | 485 case Token::kEQ: return EQUAL; |
| 487 case Token::kNE: return NOT_EQUAL; | 486 case Token::kNE: return NOT_EQUAL; |
| 488 case Token::kLT: return BELOW; | 487 case Token::kLT: return BELOW; |
| 489 case Token::kGT: return ABOVE; | 488 case Token::kGT: return ABOVE; |
| 490 case Token::kLTE: return BELOW_EQUAL; | 489 case Token::kLTE: return BELOW_EQUAL; |
| 491 case Token::kGTE: return ABOVE_EQUAL; | 490 case Token::kGTE: return ABOVE_EQUAL; |
| 492 default: | 491 default: |
| 493 UNREACHABLE(); | 492 UNREACHABLE(); |
| 494 return OVERFLOW; | 493 return OVERFLOW; |
| 495 } | 494 } |
| 496 } | 495 } |
| 497 | 496 |
| 498 | 497 |
| 498 static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler, |
| 499 Condition true_condition, |
| 500 FpuRegister left, |
| 501 FpuRegister right, |
| 502 BranchInstr* branch) { |
| 503 ASSERT(branch != NULL); |
| 504 __ comisd(left, right); |
| 505 BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ? |
| 506 branch->true_successor() : branch->false_successor(); |
| 507 __ j(PARITY_EVEN, compiler->GetJumpLabel(nan_result)); |
| 508 EmitBranchOnCondition(compiler, |
| 509 branch->true_successor(), |
| 510 branch->false_successor(), |
| 511 true_condition); |
| 512 } |
| 513 |
| 514 |
| 515 static void EmitDoubleCompareBool(FlowGraphCompiler* compiler, |
| 516 Condition true_condition, |
| 517 FpuRegister left, |
| 518 FpuRegister right, |
| 519 Register result) { |
| 520 __ comisd(left, right); |
| 521 Label is_false, is_true, done; |
| 522 // x == NaN -> false, x != NaN -> true. |
| 523 Label* nan_label = (true_condition == NOT_EQUAL) ? &is_true : &is_false; |
| 524 __ j(PARITY_EVEN, nan_label, Assembler::kNearJump); |
| 525 __ j(true_condition, &is_true, Assembler::kNearJump); |
| 526 __ Bind(&is_false); |
| 527 __ LoadObject(result, Bool::False(), PP); |
| 528 __ jmp(&done); |
| 529 __ Bind(&is_true); |
| 530 __ LoadObject(result, Bool::True(), PP); |
| 531 __ Bind(&done); |
| 532 } |
| 533 |
| 534 |
| 499 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, | 535 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, |
| 500 const LocationSummary& locs, | 536 const LocationSummary& locs, |
| 501 Token::Kind kind, | 537 Token::Kind kind, |
| 502 BranchInstr* branch) { | 538 BranchInstr* branch) { |
| 503 XmmRegister left = locs.in(0).fpu_reg(); | 539 XmmRegister left = locs.in(0).fpu_reg(); |
| 504 XmmRegister right = locs.in(1).fpu_reg(); | 540 XmmRegister right = locs.in(1).fpu_reg(); |
| 505 | 541 |
| 506 Condition true_condition = TokenKindToDoubleCondition(kind); | 542 Condition true_condition = TokenKindToDoubleCondition(kind); |
| 507 if (branch != NULL) { | 543 if (branch != NULL) { |
| 508 compiler->EmitDoubleCompareBranch( | 544 EmitDoubleCompareBranch(compiler, true_condition, left, right, branch); |
| 509 true_condition, left, right, branch); | |
| 510 } else { | 545 } else { |
| 511 compiler->EmitDoubleCompareBool( | 546 EmitDoubleCompareBool(compiler, true_condition, |
| 512 true_condition, left, right, locs.out().reg()); | 547 left, right, locs.out().reg()); |
| 513 } | 548 } |
| 514 } | 549 } |
| 515 | 550 |
| 516 | 551 |
| 517 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 552 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 518 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); | 553 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
| 519 BranchInstr* kNoBranch = NULL; | 554 BranchInstr* kNoBranch = NULL; |
| 520 if (operation_cid() == kSmiCid) { | 555 if (operation_cid() == kSmiCid) { |
| 521 // Deoptimizes if both arguments not Smi. | 556 // Deoptimizes if both arguments not Smi. |
| 522 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 557 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 Register left_reg = locs()->in(0).reg(); | 608 Register left_reg = locs()->in(0).reg(); |
| 574 Location right = locs()->in(1); | 609 Location right = locs()->in(1); |
| 575 if (right.IsConstant()) { | 610 if (right.IsConstant()) { |
| 576 ASSERT(right.constant().IsSmi()); | 611 ASSERT(right.constant().IsSmi()); |
| 577 const int64_t imm = | 612 const int64_t imm = |
| 578 reinterpret_cast<int64_t>(right.constant().raw()); | 613 reinterpret_cast<int64_t>(right.constant().raw()); |
| 579 __ TestImmediate(left_reg, Immediate(imm), PP); | 614 __ TestImmediate(left_reg, Immediate(imm), PP); |
| 580 } else { | 615 } else { |
| 581 __ testq(left_reg, right.reg()); | 616 __ testq(left_reg, right.reg()); |
| 582 } | 617 } |
| 583 branch->EmitBranchOnCondition(compiler, branch_condition); | 618 EmitBranchOnCondition(compiler, |
| 619 branch->true_successor(), |
| 620 branch->false_successor(), |
| 621 branch_condition); |
| 584 } | 622 } |
| 585 | 623 |
| 586 | 624 |
| 587 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 625 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 588 const intptr_t kNumInputs = 2; | 626 const intptr_t kNumInputs = 2; |
| 589 const intptr_t kNumTemps = 0; | 627 const intptr_t kNumTemps = 0; |
| 590 if (operation_cid() == kDoubleCid) { | 628 if (operation_cid() == kDoubleCid) { |
| 591 LocationSummary* summary = | 629 LocationSummary* summary = |
| 592 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 630 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 593 summary->set_in(0, Location::RequiresFpuRegister()); | 631 summary->set_in(0, Location::RequiresFpuRegister()); |
| (...skipping 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4310 } | 4348 } |
| 4311 | 4349 |
| 4312 // We can fall through if the successor is the next block in the list. | 4350 // We can fall through if the successor is the next block in the list. |
| 4313 // Otherwise, we need a jump. | 4351 // Otherwise, we need a jump. |
| 4314 if (!compiler->CanFallThroughTo(successor())) { | 4352 if (!compiler->CanFallThroughTo(successor())) { |
| 4315 __ jmp(compiler->GetJumpLabel(successor())); | 4353 __ jmp(compiler->GetJumpLabel(successor())); |
| 4316 } | 4354 } |
| 4317 } | 4355 } |
| 4318 | 4356 |
| 4319 | 4357 |
| 4320 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler, | |
| 4321 bool value) { | |
| 4322 if (value && !compiler->CanFallThroughTo(true_successor())) { | |
| 4323 __ jmp(compiler->GetJumpLabel(true_successor())); | |
| 4324 } else if (!value && !compiler->CanFallThroughTo(false_successor())) { | |
| 4325 __ jmp(compiler->GetJumpLabel(false_successor())); | |
| 4326 } | |
| 4327 } | |
| 4328 | |
| 4329 | |
| 4330 void ControlInstruction::EmitBranchOnCondition(FlowGraphCompiler* compiler, | |
| 4331 Condition true_condition) { | |
| 4332 if (compiler->CanFallThroughTo(false_successor())) { | |
| 4333 // If the next block is the false successor, fall through to it. | |
| 4334 __ j(true_condition, compiler->GetJumpLabel(true_successor())); | |
| 4335 } else { | |
| 4336 // If the next block is not the false successor, branch to it. | |
| 4337 Condition false_condition = NegateCondition(true_condition); | |
| 4338 __ j(false_condition, compiler->GetJumpLabel(false_successor())); | |
| 4339 | |
| 4340 // Fall through or jump to the true successor. | |
| 4341 if (!compiler->CanFallThroughTo(true_successor())) { | |
| 4342 __ jmp(compiler->GetJumpLabel(true_successor())); | |
| 4343 } | |
| 4344 } | |
| 4345 } | |
| 4346 | |
| 4347 | |
| 4348 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { | 4358 LocationSummary* CurrentContextInstr::MakeLocationSummary() const { |
| 4349 return LocationSummary::Make(0, | 4359 return LocationSummary::Make(0, |
| 4350 Location::RequiresRegister(), | 4360 Location::RequiresRegister(), |
| 4351 LocationSummary::kNoCall); | 4361 LocationSummary::kNoCall); |
| 4352 } | 4362 } |
| 4353 | 4363 |
| 4354 | 4364 |
| 4355 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4365 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 4356 __ MoveRegister(locs()->out().reg(), CTX); | 4366 __ MoveRegister(locs()->out().reg(), CTX); |
| 4357 } | 4367 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4414 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 4424 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 4415 BranchInstr* branch) { | 4425 BranchInstr* branch) { |
| 4416 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); | 4426 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); |
| 4417 Location left = locs()->in(0); | 4427 Location left = locs()->in(0); |
| 4418 Location right = locs()->in(1); | 4428 Location right = locs()->in(1); |
| 4419 if (left.IsConstant() && right.IsConstant()) { | 4429 if (left.IsConstant() && right.IsConstant()) { |
| 4420 // TODO(vegorov): should be eliminated earlier by constant propagation. | 4430 // TODO(vegorov): should be eliminated earlier by constant propagation. |
| 4421 const bool result = (kind() == Token::kEQ_STRICT) ? | 4431 const bool result = (kind() == Token::kEQ_STRICT) ? |
| 4422 left.constant().raw() == right.constant().raw() : | 4432 left.constant().raw() == right.constant().raw() : |
| 4423 left.constant().raw() != right.constant().raw(); | 4433 left.constant().raw() != right.constant().raw(); |
| 4424 branch->EmitBranchOnValue(compiler, result); | 4434 EmitBranchOnValue(compiler, |
| 4435 branch->true_successor(), |
| 4436 branch->false_successor(), |
| 4437 result); |
| 4425 return; | 4438 return; |
| 4426 } | 4439 } |
| 4427 if (left.IsConstant()) { | 4440 if (left.IsConstant()) { |
| 4428 compiler->EmitEqualityRegConstCompare(right.reg(), | 4441 compiler->EmitEqualityRegConstCompare(right.reg(), |
| 4429 left.constant(), | 4442 left.constant(), |
| 4430 needs_number_check(), | 4443 needs_number_check(), |
| 4431 token_pos()); | 4444 token_pos()); |
| 4432 } else if (right.IsConstant()) { | 4445 } else if (right.IsConstant()) { |
| 4433 compiler->EmitEqualityRegConstCompare(left.reg(), | 4446 compiler->EmitEqualityRegConstCompare(left.reg(), |
| 4434 right.constant(), | 4447 right.constant(), |
| 4435 needs_number_check(), | 4448 needs_number_check(), |
| 4436 token_pos()); | 4449 token_pos()); |
| 4437 } else { | 4450 } else { |
| 4438 compiler->EmitEqualityRegRegCompare(left.reg(), | 4451 compiler->EmitEqualityRegRegCompare(left.reg(), |
| 4439 right.reg(), | 4452 right.reg(), |
| 4440 needs_number_check(), | 4453 needs_number_check(), |
| 4441 token_pos()); | 4454 token_pos()); |
| 4442 } | 4455 } |
| 4443 | 4456 |
| 4444 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; | 4457 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
| 4445 branch->EmitBranchOnCondition(compiler, true_condition); | 4458 EmitBranchOnCondition(compiler, |
| 4459 branch->true_successor(), |
| 4460 branch->false_successor(), |
| 4461 true_condition); |
| 4446 } | 4462 } |
| 4447 | 4463 |
| 4448 | 4464 |
| 4449 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 4465 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { |
| 4450 const intptr_t kNumInputs = 0; | 4466 const intptr_t kNumInputs = 0; |
| 4451 const intptr_t kNumTemps = 1; | 4467 const intptr_t kNumTemps = 1; |
| 4452 LocationSummary* result = | 4468 LocationSummary* result = |
| 4453 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4469 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 4454 result->set_out(Location::RegisterLocation(RAX)); | 4470 result->set_out(Location::RegisterLocation(RAX)); |
| 4455 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. | 4471 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4554 PcDescriptors::kOther, | 4570 PcDescriptors::kOther, |
| 4555 locs()); | 4571 locs()); |
| 4556 __ Drop(2); // Discard type arguments and receiver. | 4572 __ Drop(2); // Discard type arguments and receiver. |
| 4557 } | 4573 } |
| 4558 | 4574 |
| 4559 } // namespace dart | 4575 } // namespace dart |
| 4560 | 4576 |
| 4561 #undef __ | 4577 #undef __ |
| 4562 | 4578 |
| 4563 #endif // defined TARGET_ARCH_X64 | 4579 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |