Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 } | 84 } |
| 85 if (FLAG_trace_functions) { | 85 if (FLAG_trace_functions) { |
| 86 const Function& function = | 86 const Function& function = |
| 87 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 87 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
| 88 __ LoadObject(temp, function); | 88 __ LoadObject(temp, function); |
| 89 __ pushq(result); // Preserve result. | 89 __ pushq(result); // Preserve result. |
| 90 __ pushq(temp); | 90 __ pushq(temp); |
| 91 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, | 91 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, |
| 92 0, | 92 0, |
| 93 CatchClauseNode::kInvalidTryIndex, | 93 CatchClauseNode::kInvalidTryIndex, |
| 94 kTraceFunctionExitRuntimeEntry); | 94 kTraceFunctionExitRuntimeEntry, |
| 95 NULL); | |
|
Vyacheslav Egorov (Google)
2012/08/13 12:54:46
ReturnInstr is marked as NoCall. This code is susp
| |
| 95 __ popq(temp); // Remove argument. | 96 __ popq(temp); // Remove argument. |
| 96 __ popq(result); // Restore result. | 97 __ popq(result); // Restore result. |
| 97 } | 98 } |
| 98 #if defined(DEBUG) | 99 #if defined(DEBUG) |
| 99 // TODO(srdjan): Fix for functions with finally clause. | 100 // TODO(srdjan): Fix for functions with finally clause. |
| 100 // A finally clause may leave a previously pushed return value if it | 101 // A finally clause may leave a previously pushed return value if it |
| 101 // has its own return instruction. Method that have finally are currently | 102 // has its own return instruction. Method that have finally are currently |
| 102 // not optimized. | 103 // not optimized. |
| 103 if (!compiler->HasFinally()) { | 104 if (!compiler->HasFinally()) { |
| 104 Label done; | 105 Label done; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 Label done; | 218 Label done; |
| 218 __ CompareObject(obj, compiler->bool_true()); | 219 __ CompareObject(obj, compiler->bool_true()); |
| 219 __ j(EQUAL, &done, Assembler::kNearJump); | 220 __ j(EQUAL, &done, Assembler::kNearJump); |
| 220 __ CompareObject(obj, compiler->bool_false()); | 221 __ CompareObject(obj, compiler->bool_false()); |
| 221 __ j(EQUAL, &done, Assembler::kNearJump); | 222 __ j(EQUAL, &done, Assembler::kNearJump); |
| 222 | 223 |
| 223 __ pushq(obj); // Push the source object. | 224 __ pushq(obj); // Push the source object. |
| 224 compiler->GenerateCallRuntime(deopt_id(), | 225 compiler->GenerateCallRuntime(deopt_id(), |
| 225 token_pos(), | 226 token_pos(), |
| 226 try_index(), | 227 try_index(), |
| 227 kConditionTypeErrorRuntimeEntry); | 228 kConditionTypeErrorRuntimeEntry, |
| 229 locs()->stack_bitmap()); | |
| 228 // We should never return here. | 230 // We should never return here. |
| 229 __ int3(); | 231 __ int3(); |
| 230 | 232 |
| 231 __ Bind(&done); | 233 __ Bind(&done); |
| 232 ASSERT(obj == result); | 234 ASSERT(obj == result); |
| 233 } | 235 } |
| 234 | 236 |
| 235 | 237 |
| 236 static Condition TokenKindToSmiCondition(Token::Kind kind) { | 238 static Condition TokenKindToSmiCondition(Token::Kind kind) { |
| 237 switch (kind) { | 239 switch (kind) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 const int kNumberOfArguments = 2; | 294 const int kNumberOfArguments = 2; |
| 293 const Array& kNoArgumentNames = Array::Handle(); | 295 const Array& kNoArgumentNames = Array::Handle(); |
| 294 const int kNumArgumentsChecked = 2; | 296 const int kNumArgumentsChecked = 2; |
| 295 | 297 |
| 296 compiler->GenerateInstanceCall(comp->deopt_id(), | 298 compiler->GenerateInstanceCall(comp->deopt_id(), |
| 297 comp->token_pos(), | 299 comp->token_pos(), |
| 298 comp->try_index(), | 300 comp->try_index(), |
| 299 operator_name, | 301 operator_name, |
| 300 kNumberOfArguments, | 302 kNumberOfArguments, |
| 301 kNoArgumentNames, | 303 kNoArgumentNames, |
| 302 kNumArgumentsChecked); | 304 kNumArgumentsChecked, |
| 305 comp->locs()->stack_bitmap()); | |
| 303 ASSERT(comp->locs()->out().reg() == RAX); | 306 ASSERT(comp->locs()->out().reg() == RAX); |
| 304 if (comp->kind() == Token::kNE) { | 307 if (comp->kind() == Token::kNE) { |
| 305 Label done, false_label; | 308 Label done, false_label; |
| 306 __ CompareObject(RAX, compiler->bool_true()); | 309 __ CompareObject(RAX, compiler->bool_true()); |
| 307 __ j(EQUAL, &false_label, Assembler::kNearJump); | 310 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 308 __ LoadObject(RAX, compiler->bool_true()); | 311 __ LoadObject(RAX, compiler->bool_true()); |
| 309 __ jmp(&done, Assembler::kNearJump); | 312 __ jmp(&done, Assembler::kNearJump); |
| 310 __ Bind(&false_label); | 313 __ Bind(&false_label); |
| 311 __ LoadObject(RAX, compiler->bool_false()); | 314 __ LoadObject(RAX, compiler->bool_false()); |
| 312 __ Bind(&done); | 315 __ Bind(&done); |
| 313 } | 316 } |
| 314 } | 317 } |
| 315 | 318 |
| 316 | 319 |
| 317 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | 320 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
| 318 const ICData& orig_ic_data, | 321 const ICData& orig_ic_data, |
| 319 const LocationSummary& locs, | 322 const LocationSummary& locs, |
| 320 BranchInstr* branch, | 323 BranchInstr* branch, |
| 321 Token::Kind kind, | 324 Token::Kind kind, |
| 322 intptr_t deopt_id, | 325 intptr_t deopt_id, |
| 323 intptr_t token_pos, | 326 intptr_t token_pos, |
| 324 intptr_t try_index) { | 327 intptr_t try_index, |
| 328 BitmapBuilder* stack_bitmap) { | |
| 325 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 329 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 326 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); | 330 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); |
| 327 ASSERT(ic_data.NumberOfChecks() > 0); | 331 ASSERT(ic_data.NumberOfChecks() > 0); |
| 328 ASSERT(ic_data.num_args_tested() == 1); | 332 ASSERT(ic_data.num_args_tested() == 1); |
| 329 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); | 333 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); |
| 330 Register left = locs.in(0).reg(); | 334 Register left = locs.in(0).reg(); |
| 331 Register right = locs.in(1).reg(); | 335 Register right = locs.in(1).reg(); |
| 332 __ testq(left, Immediate(kSmiTagMask)); | 336 __ testq(left, Immediate(kSmiTagMask)); |
| 333 Register temp = locs.temp(0).reg(); | 337 Register temp = locs.temp(0).reg(); |
| 334 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { | 338 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 __ LoadObject(result, compiler->bool_true()); | 373 __ LoadObject(result, compiler->bool_true()); |
| 370 } | 374 } |
| 371 } else { | 375 } else { |
| 372 const int kNumberOfArguments = 2; | 376 const int kNumberOfArguments = 2; |
| 373 const Array& kNoArgumentNames = Array::Handle(); | 377 const Array& kNoArgumentNames = Array::Handle(); |
| 374 compiler->GenerateStaticCall(deopt_id, | 378 compiler->GenerateStaticCall(deopt_id, |
| 375 token_pos, | 379 token_pos, |
| 376 try_index, | 380 try_index, |
| 377 target, | 381 target, |
| 378 kNumberOfArguments, | 382 kNumberOfArguments, |
| 379 kNoArgumentNames); | 383 kNoArgumentNames, |
| 384 stack_bitmap); | |
| 380 if (branch == NULL) { | 385 if (branch == NULL) { |
| 381 if (kind == Token::kNE) { | 386 if (kind == Token::kNE) { |
| 382 Label false_label; | 387 Label false_label; |
| 383 __ CompareObject(RAX, compiler->bool_true()); | 388 __ CompareObject(RAX, compiler->bool_true()); |
| 384 __ j(EQUAL, &false_label, Assembler::kNearJump); | 389 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 385 __ LoadObject(RAX, compiler->bool_true()); | 390 __ LoadObject(RAX, compiler->bool_true()); |
| 386 __ jmp(&done); | 391 __ jmp(&done); |
| 387 __ Bind(&false_label); | 392 __ Bind(&false_label); |
| 388 __ LoadObject(RAX, compiler->bool_false()); | 393 __ LoadObject(RAX, compiler->bool_false()); |
| 389 __ jmp(&done); | 394 __ jmp(&done); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 __ LoadObject(result, compiler->bool_false()); | 439 __ LoadObject(result, compiler->bool_false()); |
| 435 __ jmp(&done); | 440 __ jmp(&done); |
| 436 __ Bind(&load_true); | 441 __ Bind(&load_true); |
| 437 __ LoadObject(result, compiler->bool_true()); | 442 __ LoadObject(result, compiler->bool_true()); |
| 438 } | 443 } |
| 439 __ jmp(&done); | 444 __ jmp(&done); |
| 440 __ Bind(&non_null_compare); // Receiver is not null. | 445 __ Bind(&non_null_compare); // Receiver is not null. |
| 441 __ pushq(left); | 446 __ pushq(left); |
| 442 __ pushq(right); | 447 __ pushq(right); |
| 443 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, | 448 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, |
| 444 deopt_id, token_pos, try_index); | 449 deopt_id, token_pos, try_index, |
| 450 locs.stack_bitmap()); | |
| 445 __ Bind(&done); | 451 __ Bind(&done); |
| 446 } | 452 } |
| 447 | 453 |
| 448 | 454 |
| 449 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 455 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
| 450 const LocationSummary& locs, | 456 const LocationSummary& locs, |
| 451 Token::Kind kind, | 457 Token::Kind kind, |
| 452 BranchInstr* branch, | 458 BranchInstr* branch, |
| 453 intptr_t deopt_id, | 459 intptr_t deopt_id, |
| 454 intptr_t token_pos, | 460 intptr_t token_pos, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 __ LoadClassId(RDI, RAX); | 601 __ LoadClassId(RDI, RAX); |
| 596 __ Bind(&done); | 602 __ Bind(&done); |
| 597 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | 603 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), |
| 598 RDI, // Class id register. | 604 RDI, // Class id register. |
| 599 kNumArguments, | 605 kNumArguments, |
| 600 Array::Handle(), // No named arguments. | 606 Array::Handle(), // No named arguments. |
| 601 deopt, // Deoptimize target. | 607 deopt, // Deoptimize target. |
| 602 NULL, // Fallthrough when done. | 608 NULL, // Fallthrough when done. |
| 603 deopt_id(), | 609 deopt_id(), |
| 604 token_pos(), | 610 token_pos(), |
| 605 try_index()); | 611 try_index(), |
| 612 locs()->stack_bitmap()); | |
| 606 return; | 613 return; |
| 607 } | 614 } |
| 608 const String& function_name = | 615 const String& function_name = |
| 609 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 616 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 610 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 617 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 611 deopt_id(), | 618 deopt_id(), |
| 612 token_pos(), | 619 token_pos(), |
| 613 try_index()); | 620 try_index()); |
| 614 const intptr_t kNumArguments = 2; | 621 const intptr_t kNumArguments = 2; |
| 615 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 622 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 616 compiler->GenerateInstanceCall(deopt_id(), | 623 compiler->GenerateInstanceCall(deopt_id(), |
| 617 token_pos(), | 624 token_pos(), |
| 618 try_index(), | 625 try_index(), |
| 619 function_name, | 626 function_name, |
| 620 kNumArguments, | 627 kNumArguments, |
| 621 Array::ZoneHandle(), // No optional arguments. | 628 Array::ZoneHandle(), // No optional arguments. |
| 622 kNumArgsChecked); | 629 kNumArgsChecked, |
| 630 locs()->stack_bitmap()); | |
| 623 ASSERT(locs()->out().reg() == RAX); | 631 ASSERT(locs()->out().reg() == RAX); |
| 624 } | 632 } |
| 625 | 633 |
| 626 | 634 |
| 627 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 635 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| 628 const intptr_t kNumInputs = 0; | 636 const intptr_t kNumInputs = 0; |
| 629 const intptr_t kNumTemps = 3; | 637 const intptr_t kNumTemps = 3; |
| 630 LocationSummary* locs = | 638 LocationSummary* locs = |
| 631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 639 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 632 locs->set_temp(0, Location::RegisterLocation(RAX)); | 640 locs->set_temp(0, Location::RegisterLocation(RAX)); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 654 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); | 662 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); |
| 655 } else { | 663 } else { |
| 656 __ leaq(RAX, | 664 __ leaq(RAX, |
| 657 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 665 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| 658 } | 666 } |
| 659 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 667 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
| 660 __ movq(R10, Immediate(arg_count)); | 668 __ movq(R10, Immediate(arg_count)); |
| 661 compiler->GenerateCall(token_pos(), | 669 compiler->GenerateCall(token_pos(), |
| 662 try_index(), | 670 try_index(), |
| 663 &StubCode::CallNativeCFunctionLabel(), | 671 &StubCode::CallNativeCFunctionLabel(), |
| 664 PcDescriptors::kOther); | 672 PcDescriptors::kOther, |
| 673 locs()->stack_bitmap()); | |
| 665 __ popq(result); | 674 __ popq(result); |
| 666 } | 675 } |
| 667 | 676 |
| 668 | 677 |
| 669 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { | 678 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
| 670 const intptr_t kNumInputs = 2; | 679 const intptr_t kNumInputs = 2; |
| 671 if (receiver_type() == kGrowableObjectArrayCid) { | 680 if (receiver_type() == kGrowableObjectArrayCid) { |
| 672 const intptr_t kNumTemps = 1; | 681 const intptr_t kNumTemps = 1; |
| 673 LocationSummary* locs = | 682 LocationSummary* locs = |
| 674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 675 locs->set_in(0, Location::RequiresRegister()); | 684 locs->set_in(0, Location::RequiresRegister()); |
| 676 locs->set_in(1, Location::RequiresRegister()); | 685 locs->set_in(1, Location::RequiresRegister()); |
| 677 locs->set_temp(0, Location::RequiresRegister()); | 686 locs->set_temp(0, Location::RequiresRegister()); |
| 678 locs->set_out(Location::RequiresRegister()); | 687 locs->set_out(Location::RequiresRegister()); |
| 679 return locs; | 688 return locs; |
| 680 } else if ((receiver_type() == kArrayCid) || | 689 } else if ((receiver_type() == kArrayCid) || |
| 681 (receiver_type() == kImmutableArrayCid)) { | 690 (receiver_type() == kImmutableArrayCid)) { |
| 682 return LocationSummary::Make(kNumInputs, | 691 return LocationSummary::Make(kNumInputs, |
| 683 Location::RequiresRegister(), | 692 Location::RequiresRegister(), |
| 684 LocationSummary::kNoCall); | 693 LocationSummary::kNoCall); |
| 685 } else { | 694 } else { |
| 686 ASSERT(receiver_type() == kIllegalCid); | 695 ASSERT(receiver_type() == kIllegalCid); |
| 687 return MakeCallSummary(); | 696 return MakeCallSummary(); |
| 688 } | 697 } |
| 689 } | 698 } |
| 690 | 699 |
| 691 | 700 |
| 692 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, | 701 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, |
| 693 LoadIndexedComp* comp) { | 702 LoadIndexedComp* comp) { |
| 694 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | 703 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), |
| 695 comp->try_index(), | 704 comp->try_index(), |
| 696 kDeoptLoadIndexedPolymorphic); | 705 kDeoptLoadIndexedPolymorphic); |
| 697 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | 706 ASSERT(comp->ic_data()->NumberOfChecks() > 0); |
| 698 ASSERT(comp->HasICData()); | 707 ASSERT(comp->HasICData()); |
| 699 const ICData& ic_data = *comp->ic_data(); | 708 const ICData& ic_data = *comp->ic_data(); |
| 700 ASSERT(ic_data.num_args_tested() == 1); | 709 ASSERT(ic_data.num_args_tested() == 1); |
| 701 // No indexed access on Smi. | 710 // No indexed access on Smi. |
| 702 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | 711 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); |
| 703 // Load receiver into RAX. | 712 // Load receiver into RAX. |
| 704 const intptr_t kNumArguments = 2; | 713 const intptr_t kNumArguments = 2; |
| 705 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); | 714 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); |
| 706 __ testq(RAX, Immediate(kSmiTagMask)); | 715 __ testq(RAX, Immediate(kSmiTagMask)); |
| 707 __ j(ZERO, deopt); | 716 __ j(ZERO, deopt); |
| 708 __ LoadClassId(RDI, RAX); | 717 __ LoadClassId(RDI, RAX); |
| 709 compiler->EmitTestAndCall(ic_data, | 718 compiler->EmitTestAndCall(ic_data, |
| 710 RDI, // Class id register. | 719 RDI, // Class id register. |
| 711 kNumArguments, | 720 kNumArguments, |
| 712 Array::Handle(), // No named arguments. | 721 Array::Handle(), // No named arguments. |
| 713 deopt, // Deoptimize target. | 722 deopt, // Deoptimize target. |
| 714 NULL, // Fallthrough when done. | 723 NULL, // Fallthrough when done. |
| 715 comp->deopt_id(), | 724 comp->deopt_id(), |
| 716 comp->token_pos(), | 725 comp->token_pos(), |
| 717 comp->try_index()); | 726 comp->try_index(), |
| 727 comp->locs()->stack_bitmap()); | |
| 718 } | 728 } |
| 719 | 729 |
| 720 | 730 |
| 721 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 731 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 722 if (receiver_type() == kIllegalCid) { | 732 if (receiver_type() == kIllegalCid) { |
| 723 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 733 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 724 EmitLoadIndexedPolymorphic(compiler, this); | 734 EmitLoadIndexedPolymorphic(compiler, this); |
| 725 } else { | 735 } else { |
| 726 compiler->EmitLoadIndexedGeneric(this); | 736 compiler->EmitLoadIndexedGeneric(this); |
| 727 } | 737 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 comp->try_index()); | 825 comp->try_index()); |
| 816 | 826 |
| 817 const intptr_t kNumArguments = 3; | 827 const intptr_t kNumArguments = 3; |
| 818 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 828 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
| 819 compiler->GenerateInstanceCall(comp->deopt_id(), | 829 compiler->GenerateInstanceCall(comp->deopt_id(), |
| 820 comp->token_pos(), | 830 comp->token_pos(), |
| 821 comp->try_index(), | 831 comp->try_index(), |
| 822 function_name, | 832 function_name, |
| 823 kNumArguments, | 833 kNumArguments, |
| 824 Array::ZoneHandle(), // No named arguments. | 834 Array::ZoneHandle(), // No named arguments. |
| 825 kNumArgsChecked); | 835 kNumArgsChecked, |
| 836 comp->locs()->stack_bitmap()); | |
| 826 } | 837 } |
| 827 | 838 |
| 828 | 839 |
| 829 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, | 840 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, |
| 830 StoreIndexedComp* comp) { | 841 StoreIndexedComp* comp) { |
| 831 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | 842 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), |
| 832 comp->try_index(), | 843 comp->try_index(), |
| 833 kDeoptStoreIndexedPolymorphic); | 844 kDeoptStoreIndexedPolymorphic); |
| 834 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | 845 ASSERT(comp->ic_data()->NumberOfChecks() > 0); |
| 835 ASSERT(comp->HasICData()); | 846 ASSERT(comp->HasICData()); |
| 836 const ICData& ic_data = *comp->ic_data(); | 847 const ICData& ic_data = *comp->ic_data(); |
| 837 ASSERT(ic_data.num_args_tested() == 1); | 848 ASSERT(ic_data.num_args_tested() == 1); |
| 838 // No indexed access on Smi. | 849 // No indexed access on Smi. |
| 839 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | 850 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); |
| 840 // Load receiver into RAX. | 851 // Load receiver into RAX. |
| 841 const intptr_t kNumArguments = 3; | 852 const intptr_t kNumArguments = 3; |
| 842 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); | 853 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); |
| 843 __ testq(RAX, Immediate(kSmiTagMask)); | 854 __ testq(RAX, Immediate(kSmiTagMask)); |
| 844 __ j(ZERO, deopt); | 855 __ j(ZERO, deopt); |
| 845 __ LoadClassId(RDI, RAX); | 856 __ LoadClassId(RDI, RAX); |
| 846 compiler->EmitTestAndCall(ic_data, | 857 compiler->EmitTestAndCall(ic_data, |
| 847 RDI, // Class id register. | 858 RDI, // Class id register. |
| 848 kNumArguments, | 859 kNumArguments, |
| 849 Array::Handle(), // No named arguments. | 860 Array::Handle(), // No named arguments. |
| 850 deopt, // deoptimize label. | 861 deopt, // deoptimize label. |
| 851 NULL, // fallthrough when done. | 862 NULL, // fallthrough when done. |
| 852 comp->deopt_id(), | 863 comp->deopt_id(), |
| 853 comp->token_pos(), | 864 comp->token_pos(), |
| 854 comp->try_index()); | 865 comp->try_index(), |
| 866 comp->locs()->stack_bitmap()); | |
| 855 } | 867 } |
| 856 | 868 |
| 857 | 869 |
| 858 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 870 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 859 if (receiver_type() == kIllegalCid) { | 871 if (receiver_type() == kIllegalCid) { |
| 860 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 872 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 861 EmitStoreIndexedPolymorphic(compiler, this); | 873 EmitStoreIndexedPolymorphic(compiler, this); |
| 862 } else { | 874 } else { |
| 863 EmitStoreIndexedGeneric(compiler, this); | 875 EmitStoreIndexedGeneric(compiler, this); |
| 864 } | 876 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 | 989 |
| 978 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 990 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 979 ASSERT(locs()->in(0).reg() == RAX); // Value. | 991 ASSERT(locs()->in(0).reg() == RAX); // Value. |
| 980 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. | 992 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. |
| 981 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. | 993 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. |
| 982 | 994 |
| 983 compiler->GenerateInstanceOf(deopt_id(), | 995 compiler->GenerateInstanceOf(deopt_id(), |
| 984 token_pos(), | 996 token_pos(), |
| 985 try_index(), | 997 try_index(), |
| 986 type(), | 998 type(), |
| 987 negate_result()); | 999 negate_result(), |
| 1000 locs()->stack_bitmap()); | |
| 988 ASSERT(locs()->out().reg() == RAX); | 1001 ASSERT(locs()->out().reg() == RAX); |
| 989 } | 1002 } |
| 990 | 1003 |
| 991 | 1004 |
| 992 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 1005 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
| 993 const intptr_t kNumInputs = 1; | 1006 const intptr_t kNumInputs = 1; |
| 994 const intptr_t kNumTemps = 0; | 1007 const intptr_t kNumTemps = 0; |
| 995 LocationSummary* locs = | 1008 LocationSummary* locs = |
| 996 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1009 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 997 locs->set_in(0, Location::RegisterLocation(RBX)); | 1010 locs->set_in(0, Location::RegisterLocation(RBX)); |
| 998 locs->set_out(Location::RegisterLocation(RAX)); | 1011 locs->set_out(Location::RegisterLocation(RAX)); |
| 999 return locs; | 1012 return locs; |
| 1000 } | 1013 } |
| 1001 | 1014 |
| 1002 | 1015 |
| 1003 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1016 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1004 // Allocate the array. R10 = length, RBX = element type. | 1017 // Allocate the array. R10 = length, RBX = element type. |
| 1005 ASSERT(locs()->in(0).reg() == RBX); | 1018 ASSERT(locs()->in(0).reg() == RBX); |
| 1006 __ movq(R10, Immediate(Smi::RawValue(ElementCount()))); | 1019 __ movq(R10, Immediate(Smi::RawValue(ElementCount()))); |
| 1007 compiler->GenerateCall(token_pos(), | 1020 compiler->GenerateCall(token_pos(), |
| 1008 try_index(), | 1021 try_index(), |
| 1009 &StubCode::AllocateArrayLabel(), | 1022 &StubCode::AllocateArrayLabel(), |
| 1010 PcDescriptors::kOther); | 1023 PcDescriptors::kOther, |
| 1024 locs()->stack_bitmap()); | |
| 1011 ASSERT(locs()->out().reg() == RAX); | 1025 ASSERT(locs()->out().reg() == RAX); |
| 1012 | 1026 |
| 1013 // Pop the element values from the stack into the array. | 1027 // Pop the element values from the stack into the array. |
| 1014 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); | 1028 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); |
| 1015 for (int i = ElementCount() - 1; i >= 0; --i) { | 1029 for (int i = ElementCount() - 1; i >= 0; --i) { |
| 1016 ASSERT(ElementAt(i)->IsUse()); | 1030 ASSERT(ElementAt(i)->IsUse()); |
| 1017 __ popq(Address(R10, i * kWordSize)); | 1031 __ popq(Address(R10, i * kWordSize)); |
| 1018 } | 1032 } |
| 1019 } | 1033 } |
| 1020 | 1034 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1040 Register result = locs()->out().reg(); | 1054 Register result = locs()->out().reg(); |
| 1041 | 1055 |
| 1042 // Push the result place holder initialized to NULL. | 1056 // Push the result place holder initialized to NULL. |
| 1043 __ PushObject(Object::ZoneHandle()); | 1057 __ PushObject(Object::ZoneHandle()); |
| 1044 __ PushObject(cls); | 1058 __ PushObject(cls); |
| 1045 __ pushq(type_arguments); | 1059 __ pushq(type_arguments); |
| 1046 __ pushq(instantiator_type_arguments); | 1060 __ pushq(instantiator_type_arguments); |
| 1047 compiler->GenerateCallRuntime(deopt_id(), | 1061 compiler->GenerateCallRuntime(deopt_id(), |
| 1048 token_pos(), | 1062 token_pos(), |
| 1049 try_index(), | 1063 try_index(), |
| 1050 kAllocateObjectWithBoundsCheckRuntimeEntry); | 1064 kAllocateObjectWithBoundsCheckRuntimeEntry, |
| 1065 locs()->stack_bitmap()); | |
| 1051 // Pop instantiator type arguments, type arguments, and class. | 1066 // Pop instantiator type arguments, type arguments, and class. |
| 1052 __ Drop(3); | 1067 __ Drop(3); |
| 1053 __ popq(result); // Pop new instance. | 1068 __ popq(result); // Pop new instance. |
| 1054 } | 1069 } |
| 1055 | 1070 |
| 1056 | 1071 |
| 1057 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 1072 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
| 1058 return LocationSummary::Make(1, | 1073 return LocationSummary::Make(1, |
| 1059 Location::RequiresRegister(), | 1074 Location::RequiresRegister(), |
| 1060 LocationSummary::kNoCall); | 1075 LocationSummary::kNoCall); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1125 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 1140 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| 1126 __ Bind(&type_arguments_uninstantiated); | 1141 __ Bind(&type_arguments_uninstantiated); |
| 1127 } | 1142 } |
| 1128 // A runtime call to instantiate the type arguments is required. | 1143 // A runtime call to instantiate the type arguments is required. |
| 1129 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1144 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1130 __ PushObject(type_arguments()); | 1145 __ PushObject(type_arguments()); |
| 1131 __ pushq(instantiator_reg); // Push instantiator type arguments. | 1146 __ pushq(instantiator_reg); // Push instantiator type arguments. |
| 1132 compiler->GenerateCallRuntime(deopt_id(), | 1147 compiler->GenerateCallRuntime(deopt_id(), |
| 1133 token_pos(), | 1148 token_pos(), |
| 1134 try_index(), | 1149 try_index(), |
| 1135 kInstantiateTypeArgumentsRuntimeEntry); | 1150 kInstantiateTypeArgumentsRuntimeEntry, |
| 1151 locs()->stack_bitmap()); | |
| 1136 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 1152 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| 1137 __ popq(result_reg); // Pop instantiated type arguments. | 1153 __ popq(result_reg); // Pop instantiated type arguments. |
| 1138 __ Bind(&type_arguments_instantiated); | 1154 __ Bind(&type_arguments_instantiated); |
| 1139 ASSERT(instantiator_reg == result_reg); | 1155 ASSERT(instantiator_reg == result_reg); |
| 1140 // 'result_reg': Instantiated type arguments. | 1156 // 'result_reg': Instantiated type arguments. |
| 1141 } | 1157 } |
| 1142 | 1158 |
| 1143 | 1159 |
| 1144 LocationSummary* | 1160 LocationSummary* |
| 1145 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { | 1161 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1293 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1278 ASSERT(locs()->temp(0).reg() == R10); | 1294 ASSERT(locs()->temp(0).reg() == R10); |
| 1279 ASSERT(locs()->out().reg() == RAX); | 1295 ASSERT(locs()->out().reg() == RAX); |
| 1280 | 1296 |
| 1281 __ movq(R10, Immediate(num_context_variables())); | 1297 __ movq(R10, Immediate(num_context_variables())); |
| 1282 const ExternalLabel label("alloc_context", | 1298 const ExternalLabel label("alloc_context", |
| 1283 StubCode::AllocateContextEntryPoint()); | 1299 StubCode::AllocateContextEntryPoint()); |
| 1284 compiler->GenerateCall(token_pos(), | 1300 compiler->GenerateCall(token_pos(), |
| 1285 try_index(), | 1301 try_index(), |
| 1286 &label, | 1302 &label, |
| 1287 PcDescriptors::kOther); | 1303 PcDescriptors::kOther, |
| 1304 locs()->stack_bitmap()); | |
| 1288 } | 1305 } |
| 1289 | 1306 |
| 1290 | 1307 |
| 1291 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1308 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
| 1292 const intptr_t kNumInputs = 1; | 1309 const intptr_t kNumInputs = 1; |
| 1293 const intptr_t kNumTemps = 0; | 1310 const intptr_t kNumTemps = 0; |
| 1294 LocationSummary* locs = | 1311 LocationSummary* locs = |
| 1295 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 1296 locs->set_in(0, Location::RegisterLocation(RAX)); | 1313 locs->set_in(0, Location::RegisterLocation(RAX)); |
| 1297 locs->set_out(Location::RegisterLocation(RAX)); | 1314 locs->set_out(Location::RegisterLocation(RAX)); |
| 1298 return locs; | 1315 return locs; |
| 1299 } | 1316 } |
| 1300 | 1317 |
| 1301 | 1318 |
| 1302 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1319 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1303 Register context_value = locs()->in(0).reg(); | 1320 Register context_value = locs()->in(0).reg(); |
| 1304 Register result = locs()->out().reg(); | 1321 Register result = locs()->out().reg(); |
| 1305 | 1322 |
| 1306 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1323 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 1307 __ pushq(context_value); | 1324 __ pushq(context_value); |
| 1308 compiler->GenerateCallRuntime(deopt_id(), | 1325 compiler->GenerateCallRuntime(deopt_id(), |
| 1309 token_pos(), | 1326 token_pos(), |
| 1310 try_index(), | 1327 try_index(), |
| 1311 kCloneContextRuntimeEntry); | 1328 kCloneContextRuntimeEntry, |
| 1329 locs()->stack_bitmap()); | |
| 1312 __ popq(result); // Remove argument. | 1330 __ popq(result); // Remove argument. |
| 1313 __ popq(result); // Get result (cloned context). | 1331 __ popq(result); // Get result (cloned context). |
| 1314 } | 1332 } |
| 1315 | 1333 |
| 1316 | 1334 |
| 1317 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1335 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
| 1318 return LocationSummary::Make(0, | 1336 return LocationSummary::Make(0, |
| 1319 Location::NoLocation(), | 1337 Location::NoLocation(), |
| 1320 LocationSummary::kNoCall); | 1338 LocationSummary::kNoCall); |
| 1321 } | 1339 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1357 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1375 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1358 Register temp = locs()->temp(0).reg(); | 1376 Register temp = locs()->temp(0).reg(); |
| 1359 // Generate stack overflow check. | 1377 // Generate stack overflow check. |
| 1360 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); | 1378 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); |
| 1361 __ cmpq(RSP, Address(temp, 0)); | 1379 __ cmpq(RSP, Address(temp, 0)); |
| 1362 Label no_stack_overflow; | 1380 Label no_stack_overflow; |
| 1363 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); | 1381 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); |
| 1364 compiler->GenerateCallRuntime(deopt_id(), | 1382 compiler->GenerateCallRuntime(deopt_id(), |
| 1365 token_pos(), | 1383 token_pos(), |
| 1366 try_index(), | 1384 try_index(), |
| 1367 kStackOverflowRuntimeEntry); | 1385 kStackOverflowRuntimeEntry, |
| 1386 locs()->stack_bitmap()); | |
| 1368 __ Bind(&no_stack_overflow); | 1387 __ Bind(&no_stack_overflow); |
| 1369 } | 1388 } |
| 1370 | 1389 |
| 1371 | 1390 |
| 1372 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1391 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 1373 const intptr_t kNumInputs = 2; | 1392 const intptr_t kNumInputs = 2; |
| 1374 | 1393 |
| 1375 // Double operation are handled in DoubleBinaryOpComp. | 1394 // Double operation are handled in DoubleBinaryOpComp. |
| 1376 ASSERT(operands_type() != kDoubleOperands); | 1395 ASSERT(operands_type() != kDoubleOperands); |
| 1377 | 1396 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 __ shlq(left, right_temp); | 1561 __ shlq(left, right_temp); |
| 1543 __ jmp(&done); | 1562 __ jmp(&done); |
| 1544 { | 1563 { |
| 1545 __ Bind(&call_method); | 1564 __ Bind(&call_method); |
| 1546 Function& target = Function::ZoneHandle( | 1565 Function& target = Function::ZoneHandle( |
| 1547 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); | 1566 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
| 1548 ASSERT(!target.IsNull()); | 1567 ASSERT(!target.IsNull()); |
| 1549 const intptr_t kArgumentCount = 2; | 1568 const intptr_t kArgumentCount = 2; |
| 1550 __ pushq(temp); | 1569 __ pushq(temp); |
| 1551 __ pushq(right); | 1570 __ pushq(right); |
| 1552 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1571 compiler->GenerateStaticCall( |
| 1553 comp->instance_call()->token_pos(), | 1572 comp->instance_call()->deopt_id(), |
| 1554 comp->instance_call()->try_index(), | 1573 comp->instance_call()->token_pos(), |
| 1555 target, | 1574 comp->instance_call()->try_index(), |
| 1556 kArgumentCount, | 1575 target, |
| 1557 Array::Handle()); // No argument names. | 1576 kArgumentCount, |
| 1577 Array::Handle(), // No argument names. | |
| 1578 comp->locs()->stack_bitmap()); | |
| 1558 ASSERT(result == RAX); | 1579 ASSERT(result == RAX); |
| 1559 } | 1580 } |
| 1560 __ Bind(&done); | 1581 __ Bind(&done); |
| 1561 break; | 1582 break; |
| 1562 } | 1583 } |
| 1563 case Token::kDIV: { | 1584 case Token::kDIV: { |
| 1564 // Dispatches to 'Double./'. | 1585 // Dispatches to 'Double./'. |
| 1565 // TODO(srdjan): Implement as conversion to double and double division. | 1586 // TODO(srdjan): Implement as conversion to double and double division. |
| 1566 UNREACHABLE(); | 1587 UNREACHABLE(); |
| 1567 break; | 1588 break; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1635 | 1656 |
| 1636 __ Bind(&smi_static_call); | 1657 __ Bind(&smi_static_call); |
| 1637 { | 1658 { |
| 1638 Function& target = Function::ZoneHandle( | 1659 Function& target = Function::ZoneHandle( |
| 1639 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); | 1660 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
| 1640 if (target.IsNull()) { | 1661 if (target.IsNull()) { |
| 1641 __ jmp(deopt); | 1662 __ jmp(deopt); |
| 1642 } else { | 1663 } else { |
| 1643 __ pushq(left); | 1664 __ pushq(left); |
| 1644 __ pushq(right); | 1665 __ pushq(right); |
| 1645 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1666 compiler->GenerateStaticCall( |
| 1646 comp->instance_call()->token_pos(), | 1667 comp->instance_call()->deopt_id(), |
| 1647 comp->instance_call()->try_index(), | 1668 comp->instance_call()->token_pos(), |
| 1648 target, | 1669 comp->instance_call()->try_index(), |
| 1649 comp->instance_call()->ArgumentCount(), | 1670 target, |
| 1650 comp->instance_call()->argument_names()); | 1671 comp->instance_call()->ArgumentCount(), |
| 1672 comp->instance_call()->argument_names(), | |
| 1673 comp->locs()->stack_bitmap()); | |
| 1651 ASSERT(result == RAX); | 1674 ASSERT(result == RAX); |
| 1652 __ jmp(&done); | 1675 __ jmp(&done); |
| 1653 } | 1676 } |
| 1654 } | 1677 } |
| 1655 | 1678 |
| 1656 __ Bind(&mint_static_call); | 1679 __ Bind(&mint_static_call); |
| 1657 { | 1680 { |
| 1658 Function& target = Function::ZoneHandle( | 1681 Function& target = Function::ZoneHandle( |
| 1659 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); | 1682 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); |
| 1660 if (target.IsNull()) { | 1683 if (target.IsNull()) { |
| 1661 __ jmp(deopt); | 1684 __ jmp(deopt); |
| 1662 } else { | 1685 } else { |
| 1663 __ pushq(left); | 1686 __ pushq(left); |
| 1664 __ pushq(right); | 1687 __ pushq(right); |
| 1665 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1688 compiler->GenerateStaticCall( |
| 1666 comp->instance_call()->token_pos(), | 1689 comp->instance_call()->deopt_id(), |
| 1667 comp->instance_call()->try_index(), | 1690 comp->instance_call()->token_pos(), |
| 1668 target, | 1691 comp->instance_call()->try_index(), |
| 1669 comp->instance_call()->ArgumentCount(), | 1692 target, |
| 1670 comp->instance_call()->argument_names()); | 1693 comp->instance_call()->ArgumentCount(), |
| 1694 comp->instance_call()->argument_names(), | |
| 1695 comp->locs()->stack_bitmap()); | |
| 1671 ASSERT(result == RAX); | 1696 ASSERT(result == RAX); |
| 1672 } | 1697 } |
| 1673 } | 1698 } |
| 1674 __ Bind(&done); | 1699 __ Bind(&done); |
| 1675 } | 1700 } |
| 1676 | 1701 |
| 1677 | 1702 |
| 1678 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1703 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1679 switch (operands_type()) { | 1704 switch (operands_type()) { |
| 1680 case kSmiOperands: | 1705 case kSmiOperands: |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1702 Register temp = RDX; | 1727 Register temp = RDX; |
| 1703 Register result = locs()->out().reg(); | 1728 Register result = locs()->out().reg(); |
| 1704 | 1729 |
| 1705 const Class& double_class = compiler->double_class(); | 1730 const Class& double_class = compiler->double_class(); |
| 1706 const Code& stub = | 1731 const Code& stub = |
| 1707 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1732 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1708 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1733 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1709 compiler->GenerateCall(instance_call()->token_pos(), | 1734 compiler->GenerateCall(instance_call()->token_pos(), |
| 1710 instance_call()->try_index(), | 1735 instance_call()->try_index(), |
| 1711 &label, | 1736 &label, |
| 1712 PcDescriptors::kOther); | 1737 PcDescriptors::kOther, |
| 1738 locs()->stack_bitmap()); | |
| 1713 // Newly allocated object is now in the result register (RAX). | 1739 // Newly allocated object is now in the result register (RAX). |
| 1714 ASSERT(result == RAX); | 1740 ASSERT(result == RAX); |
| 1715 __ popq(right); | 1741 __ popq(right); |
| 1716 __ popq(left); | 1742 __ popq(left); |
| 1717 | 1743 |
| 1718 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1744 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1719 instance_call()->try_index(), | 1745 instance_call()->try_index(), |
| 1720 kDeoptDoubleBinaryOp, | 1746 kDeoptDoubleBinaryOp, |
| 1721 left, | 1747 left, |
| 1722 right); | 1748 right); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 __ j(NOT_EQUAL, deopt); | 1855 __ j(NOT_EQUAL, deopt); |
| 1830 // Allocate result object. | 1856 // Allocate result object. |
| 1831 const Class& double_class = compiler->double_class(); | 1857 const Class& double_class = compiler->double_class(); |
| 1832 const Code& stub = | 1858 const Code& stub = |
| 1833 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1859 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1834 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1860 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1835 __ pushq(value); | 1861 __ pushq(value); |
| 1836 compiler->GenerateCall(instance_call()->token_pos(), | 1862 compiler->GenerateCall(instance_call()->token_pos(), |
| 1837 instance_call()->try_index(), | 1863 instance_call()->try_index(), |
| 1838 &label, | 1864 &label, |
| 1839 PcDescriptors::kOther); | 1865 PcDescriptors::kOther, |
| 1866 instance_call()->locs()->stack_bitmap()); | |
| 1840 // Result is in RAX. | 1867 // Result is in RAX. |
| 1841 ASSERT(result != temp); | 1868 ASSERT(result != temp); |
| 1842 __ movq(result, RAX); | 1869 __ movq(result, RAX); |
| 1843 __ popq(temp); | 1870 __ popq(temp); |
| 1844 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 1871 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
| 1845 __ DoubleNegate(XMM0); | 1872 __ DoubleNegate(XMM0); |
| 1846 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1873 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1847 } else { | 1874 } else { |
| 1848 UNREACHABLE(); | 1875 UNREACHABLE(); |
| 1849 } | 1876 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1890 | 1917 |
| 1891 const Class& double_class = compiler->double_class(); | 1918 const Class& double_class = compiler->double_class(); |
| 1892 const Code& stub = | 1919 const Code& stub = |
| 1893 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1920 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1894 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1921 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1895 | 1922 |
| 1896 // TODO(vegorov): allocate box in the driver loop to avoid spilling. | 1923 // TODO(vegorov): allocate box in the driver loop to avoid spilling. |
| 1897 compiler->GenerateCall(instance_call()->token_pos(), | 1924 compiler->GenerateCall(instance_call()->token_pos(), |
| 1898 instance_call()->try_index(), | 1925 instance_call()->try_index(), |
| 1899 &label, | 1926 &label, |
| 1900 PcDescriptors::kOther); | 1927 PcDescriptors::kOther, |
| 1928 locs()->stack_bitmap()); | |
| 1901 ASSERT(result == RAX); | 1929 ASSERT(result == RAX); |
| 1902 __ popq(value); | 1930 __ popq(value); |
| 1903 | 1931 |
| 1904 __ testq(value, Immediate(kSmiTagMask)); | 1932 __ testq(value, Immediate(kSmiTagMask)); |
| 1905 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | 1933 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
| 1906 __ SmiUntag(value); | 1934 __ SmiUntag(value); |
| 1907 __ cvtsi2sd(XMM0, value); | 1935 __ cvtsi2sd(XMM0, value); |
| 1908 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1936 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1909 } | 1937 } |
| 1910 | 1938 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1936 Label done; | 1964 Label done; |
| 1937 __ LoadClassId(RDI, RAX); | 1965 __ LoadClassId(RDI, RAX); |
| 1938 compiler->EmitTestAndCall(*ic_data(), | 1966 compiler->EmitTestAndCall(*ic_data(), |
| 1939 RDI, // Class id register. | 1967 RDI, // Class id register. |
| 1940 instance_call()->ArgumentCount(), | 1968 instance_call()->ArgumentCount(), |
| 1941 instance_call()->argument_names(), | 1969 instance_call()->argument_names(), |
| 1942 deopt, | 1970 deopt, |
| 1943 (is_smi_label == &handle_smi) ? &done : NULL, | 1971 (is_smi_label == &handle_smi) ? &done : NULL, |
| 1944 instance_call()->deopt_id(), | 1972 instance_call()->deopt_id(), |
| 1945 instance_call()->token_pos(), | 1973 instance_call()->token_pos(), |
| 1946 instance_call()->try_index()); | 1974 instance_call()->try_index(), |
| 1975 locs()->stack_bitmap()); | |
| 1947 if (is_smi_label == &handle_smi) { | 1976 if (is_smi_label == &handle_smi) { |
| 1948 __ Bind(&handle_smi); | 1977 __ Bind(&handle_smi); |
| 1949 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); | 1978 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); |
| 1950 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); | 1979 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); |
| 1951 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 1980 compiler->GenerateStaticCall(instance_call()->deopt_id(), |
| 1952 instance_call()->token_pos(), | 1981 instance_call()->token_pos(), |
| 1953 instance_call()->try_index(), | 1982 instance_call()->try_index(), |
| 1954 target, | 1983 target, |
| 1955 instance_call()->ArgumentCount(), | 1984 instance_call()->ArgumentCount(), |
| 1956 instance_call()->argument_names()); | 1985 instance_call()->argument_names(), |
| 1986 locs()->stack_bitmap()); | |
| 1957 } | 1987 } |
| 1958 __ Bind(&done); | 1988 __ Bind(&done); |
| 1959 } | 1989 } |
| 1960 | 1990 |
| 1961 | 1991 |
| 1962 // TODO(srdjan): Move to shared. | 1992 // TODO(srdjan): Move to shared. |
| 1963 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { | 1993 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { |
| 1964 if (ic_data.num_args_tested() != 2) return false; | 1994 if (ic_data.num_args_tested() != 2) return false; |
| 1965 if (ic_data.NumberOfChecks() != 1) return false; | 1995 if (ic_data.NumberOfChecks() != 1) return false; |
| 1966 Function& target = Function::Handle(); | 1996 Function& target = Function::Handle(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2048 token_pos(), | 2078 token_pos(), |
| 2049 try_index()); | 2079 try_index()); |
| 2050 const intptr_t kNumArguments = 2; | 2080 const intptr_t kNumArguments = 2; |
| 2051 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 2081 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 2052 compiler->GenerateInstanceCall(deopt_id(), | 2082 compiler->GenerateInstanceCall(deopt_id(), |
| 2053 token_pos(), | 2083 token_pos(), |
| 2054 try_index(), | 2084 try_index(), |
| 2055 function_name, | 2085 function_name, |
| 2056 kNumArguments, | 2086 kNumArguments, |
| 2057 Array::ZoneHandle(), // No optional arguments. | 2087 Array::ZoneHandle(), // No optional arguments. |
| 2058 kNumArgsChecked); | 2088 kNumArgsChecked, |
| 2089 locs()->stack_bitmap()); | |
| 2059 ASSERT(locs()->out().reg() == RAX); | 2090 ASSERT(locs()->out().reg() == RAX); |
| 2060 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2091 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
| 2061 EmitBranchOnCondition(compiler, branch_condition); | 2092 EmitBranchOnCondition(compiler, branch_condition); |
| 2062 } | 2093 } |
| 2063 | 2094 |
| 2064 } // namespace dart | 2095 } // namespace dart |
| 2065 | 2096 |
| 2066 #undef __ | 2097 #undef __ |
| 2067 | 2098 |
| 2068 #endif // defined TARGET_ARCH_X64 | 2099 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |