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 |