Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1045)

Side by Side Diff: vm/intermediate_language_x64.cc

Issue 10827209: Unify class ids and snapshot object ids list so that we don't have disparate and sometimes confusin… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/intermediate_language_ia32.cc ('k') | vm/intrinsifier_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 case Token::kGTE: return GREATER_EQUAL; 243 case Token::kGTE: return GREATER_EQUAL;
244 default: 244 default:
245 UNREACHABLE(); 245 UNREACHABLE();
246 return OVERFLOW; 246 return OVERFLOW;
247 } 247 }
248 } 248 }
249 249
250 250
251 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 251 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
252 const intptr_t kNumInputs = 2; 252 const intptr_t kNumInputs = 2;
253 if (receiver_class_id() != kObject) { 253 if (receiver_class_id() != kObjectCid) {
254 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); 254 ASSERT((receiver_class_id() == kSmiCid) ||
255 (receiver_class_id() == kDoubleCid));
255 const intptr_t kNumTemps = 1; 256 const intptr_t kNumTemps = 1;
256 LocationSummary* locs = 257 LocationSummary* locs =
257 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
258 locs->set_in(0, Location::RequiresRegister()); 259 locs->set_in(0, Location::RequiresRegister());
259 locs->set_in(1, Location::RequiresRegister()); 260 locs->set_in(1, Location::RequiresRegister());
260 locs->set_temp(0, Location::RequiresRegister()); 261 locs->set_temp(0, Location::RequiresRegister());
261 locs->set_out(Location::RequiresRegister()); 262 locs->set_out(Location::RequiresRegister());
262 return locs; 263 return locs;
263 } 264 }
264 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 265 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 ASSERT(ic_data.NumberOfChecks() > 0); 327 ASSERT(ic_data.NumberOfChecks() > 0);
327 ASSERT(ic_data.num_args_tested() == 1); 328 ASSERT(ic_data.num_args_tested() == 1);
328 Label* deopt = compiler->AddDeoptStub(deopt_id, 329 Label* deopt = compiler->AddDeoptStub(deopt_id,
329 token_pos, 330 token_pos,
330 try_index, 331 try_index,
331 kDeoptEquality); 332 kDeoptEquality);
332 Register left = locs.in(0).reg(); 333 Register left = locs.in(0).reg();
333 Register right = locs.in(1).reg(); 334 Register right = locs.in(1).reg();
334 __ testq(left, Immediate(kSmiTagMask)); 335 __ testq(left, Immediate(kSmiTagMask));
335 Register temp = locs.temp(0).reg(); 336 Register temp = locs.temp(0).reg();
336 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 337 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
337 Label done, load_class_id; 338 Label done, load_class_id;
338 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 339 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
339 __ movq(temp, Immediate(kSmi)); 340 __ movq(temp, Immediate(kSmiCid));
340 __ jmp(&done, Assembler::kNearJump); 341 __ jmp(&done, Assembler::kNearJump);
341 __ Bind(&load_class_id); 342 __ Bind(&load_class_id);
342 __ LoadClassId(temp, left); 343 __ LoadClassId(temp, left);
343 __ Bind(&done); 344 __ Bind(&done);
344 } else { 345 } else {
345 __ j(ZERO, deopt); // Smi deopts. 346 __ j(ZERO, deopt); // Smi deopts.
346 __ LoadClassId(temp, left); 347 __ LoadClassId(temp, left);
347 } 348 }
348 Condition cond = TokenKindToSmiCondition(kind); 349 Condition cond = TokenKindToSmiCondition(kind);
349 Label done; 350 Label done;
350 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 351 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
351 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0)); 352 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0));
352 Label next_test; 353 Label next_test;
353 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 354 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
354 __ j(NOT_EQUAL, &next_test); 355 __ j(NOT_EQUAL, &next_test);
355 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); 356 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
356 ObjectStore* object_store = Isolate::Current()->object_store(); 357 ObjectStore* object_store = Isolate::Current()->object_store();
357 if (target.owner() == object_store->object_class()) { 358 if (target.owner() == object_store->object_class()) {
358 // Object.== is same as ===. 359 // Object.== is same as ===.
359 __ Drop(2); 360 __ Drop(2);
360 __ cmpq(left, right); 361 __ cmpq(left, right);
361 if (branch != NULL) { 362 if (branch != NULL) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 compiler->EmitDoubleCompareBranch( 528 compiler->EmitDoubleCompareBranch(
528 true_condition, XMM0, XMM1, branch); 529 true_condition, XMM0, XMM1, branch);
529 } else { 530 } else {
530 compiler->EmitDoubleCompareBool( 531 compiler->EmitDoubleCompareBool(
531 true_condition, XMM0, XMM1, locs.out().reg()); 532 true_condition, XMM0, XMM1, locs.out().reg());
532 } 533 }
533 } 534 }
534 535
535 536
536 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 537 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
537 if (receiver_class_id() == kSmi) { 538 if (receiver_class_id() == kSmiCid) {
538 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 539 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
539 deopt_id(), token_pos(), try_index()); 540 deopt_id(), token_pos(), try_index());
540 return; 541 return;
541 } 542 }
542 if (receiver_class_id() == kDouble) { 543 if (receiver_class_id() == kDoubleCid) {
543 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 544 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
544 deopt_id(), token_pos(), try_index()); 545 deopt_id(), token_pos(), try_index());
545 return; 546 return;
546 } 547 }
547 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 548 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
548 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 549 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
549 deopt_id(), token_pos(), try_index()); 550 deopt_id(), token_pos(), try_index());
550 } else { 551 } else {
551 Register left = locs()->in(0).reg(); 552 Register left = locs()->in(0).reg();
552 Register right = locs()->in(1).reg(); 553 Register right = locs()->in(1).reg();
553 __ pushq(left); 554 __ pushq(left);
554 __ pushq(right); 555 __ pushq(right);
555 EmitEqualityAsInstanceCall(compiler, this); 556 EmitEqualityAsInstanceCall(compiler, this);
556 } 557 }
557 } 558 }
558 559
559 560
560 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 561 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
561 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { 562 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) {
562 const intptr_t kNumInputs = 2; 563 const intptr_t kNumInputs = 2;
563 const intptr_t kNumTemps = 1; 564 const intptr_t kNumTemps = 1;
564 LocationSummary* summary = 565 LocationSummary* summary =
565 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 566 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
566 summary->set_in(0, Location::RequiresRegister()); 567 summary->set_in(0, Location::RequiresRegister());
567 summary->set_in(1, Location::RequiresRegister()); 568 summary->set_in(1, Location::RequiresRegister());
568 summary->set_out(Location::RequiresRegister()); 569 summary->set_out(Location::RequiresRegister());
569 summary->set_temp(0, Location::RequiresRegister()); 570 summary->set_temp(0, Location::RequiresRegister());
570 return summary; 571 return summary;
571 } 572 }
572 ASSERT(operands_class_id() == kObject); 573 ASSERT(operands_class_id() == kObjectCid);
573 return MakeCallSummary(); 574 return MakeCallSummary();
574 } 575 }
575 576
576 577
577 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 578 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
578 if (operands_class_id() == kSmi) { 579 if (operands_class_id() == kSmiCid) {
579 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 580 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
580 deopt_id(), token_pos(), try_index()); 581 deopt_id(), token_pos(), try_index());
581 return; 582 return;
582 } 583 }
583 if (operands_class_id() == kDouble) { 584 if (operands_class_id() == kDoubleCid) {
584 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 585 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
585 deopt_id(), token_pos(), try_index()); 586 deopt_id(), token_pos(), try_index());
586 return; 587 return;
587 } 588 }
588 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 589 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
589 Label* deopt = compiler->AddDeoptStub(deopt_id(), 590 Label* deopt = compiler->AddDeoptStub(deopt_id(),
590 token_pos(), 591 token_pos(),
591 try_index(), 592 try_index(),
592 kDeoptRelationalOp); 593 kDeoptRelationalOp);
593 // Load receiver into RAX, class into RDI. 594 // Load receiver into RAX, class into RDI.
594 Label done; 595 Label done;
595 const intptr_t kNumArguments = 2; 596 const intptr_t kNumArguments = 2;
596 __ movq(RDI, Immediate(kSmi)); 597 __ movq(RDI, Immediate(kSmiCid));
597 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 598 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
598 __ testq(RAX, Immediate(kSmiTagMask)); 599 __ testq(RAX, Immediate(kSmiTagMask));
599 __ j(ZERO, &done); 600 __ j(ZERO, &done);
600 __ LoadClassId(RDI, RAX); 601 __ LoadClassId(RDI, RAX);
601 __ Bind(&done); 602 __ Bind(&done);
602 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 603 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
603 RDI, // Class id register. 604 RDI, // Class id register.
604 kNumArguments, 605 kNumArguments,
605 Array::Handle(), // No named arguments. 606 Array::Handle(), // No named arguments.
606 deopt, // Deoptimize target. 607 deopt, // Deoptimize target.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 compiler->GenerateCall(token_pos(), 667 compiler->GenerateCall(token_pos(),
667 try_index(), 668 try_index(),
668 &StubCode::CallNativeCFunctionLabel(), 669 &StubCode::CallNativeCFunctionLabel(),
669 PcDescriptors::kOther); 670 PcDescriptors::kOther);
670 __ popq(result); 671 __ popq(result);
671 } 672 }
672 673
673 674
674 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 675 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
675 const intptr_t kNumInputs = 2; 676 const intptr_t kNumInputs = 2;
676 if (receiver_type() == kGrowableObjectArray) { 677 if (receiver_type() == kGrowableObjectArrayCid) {
677 const intptr_t kNumTemps = 1; 678 const intptr_t kNumTemps = 1;
678 LocationSummary* locs = 679 LocationSummary* locs =
679 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
680 locs->set_in(0, Location::RequiresRegister()); 681 locs->set_in(0, Location::RequiresRegister());
681 locs->set_in(1, Location::RequiresRegister()); 682 locs->set_in(1, Location::RequiresRegister());
682 locs->set_temp(0, Location::RequiresRegister()); 683 locs->set_temp(0, Location::RequiresRegister());
683 locs->set_out(Location::RequiresRegister()); 684 locs->set_out(Location::RequiresRegister());
684 return locs; 685 return locs;
685 } else if ((receiver_type() == kArray) || 686 } else if ((receiver_type() == kArrayCid) ||
686 (receiver_type() == kImmutableArray)) { 687 (receiver_type() == kImmutableArrayCid)) {
687 return LocationSummary::Make(kNumInputs, 688 return LocationSummary::Make(kNumInputs,
688 Location::RequiresRegister(), 689 Location::RequiresRegister(),
689 LocationSummary::kNoCall); 690 LocationSummary::kNoCall);
690 } else { 691 } else {
691 ASSERT(receiver_type() == kIllegalObjectKind); 692 ASSERT(receiver_type() == kIllegalCid);
692 return MakeCallSummary(); 693 return MakeCallSummary();
693 } 694 }
694 } 695 }
695 696
696 697
697 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 698 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
698 LoadIndexedComp* comp) { 699 LoadIndexedComp* comp) {
699 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 700 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
700 comp->token_pos(), 701 comp->token_pos(),
701 comp->try_index(), 702 comp->try_index(),
702 kDeoptLoadIndexedPolymorphic); 703 kDeoptLoadIndexedPolymorphic);
703 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 704 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
704 ASSERT(comp->HasICData()); 705 ASSERT(comp->HasICData());
705 const ICData& ic_data = *comp->ic_data(); 706 const ICData& ic_data = *comp->ic_data();
706 ASSERT(ic_data.num_args_tested() == 1); 707 ASSERT(ic_data.num_args_tested() == 1);
707 // No indexed access on Smi. 708 // No indexed access on Smi.
708 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 709 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
709 // Load receiver into RAX. 710 // Load receiver into RAX.
710 const intptr_t kNumArguments = 2; 711 const intptr_t kNumArguments = 2;
711 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 712 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
712 __ testq(RAX, Immediate(kSmiTagMask)); 713 __ testq(RAX, Immediate(kSmiTagMask));
713 __ j(ZERO, deopt); 714 __ j(ZERO, deopt);
714 __ LoadClassId(RDI, RAX); 715 __ LoadClassId(RDI, RAX);
715 compiler->EmitTestAndCall(ic_data, 716 compiler->EmitTestAndCall(ic_data,
716 RDI, // Class id register. 717 RDI, // Class id register.
717 kNumArguments, 718 kNumArguments,
718 Array::Handle(), // No named arguments. 719 Array::Handle(), // No named arguments.
719 deopt, // Deoptimize target. 720 deopt, // Deoptimize target.
720 NULL, // Fallthrough when done. 721 NULL, // Fallthrough when done.
721 comp->deopt_id(), 722 comp->deopt_id(),
722 comp->token_pos(), 723 comp->token_pos(),
723 comp->try_index()); 724 comp->try_index());
724 } 725 }
725 726
726 727
727 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 728 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
728 if (receiver_type() == kIllegalObjectKind) { 729 if (receiver_type() == kIllegalCid) {
729 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 730 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
730 EmitLoadIndexedPolymorphic(compiler, this); 731 EmitLoadIndexedPolymorphic(compiler, this);
731 } else { 732 } else {
732 compiler->EmitLoadIndexedGeneric(this); 733 compiler->EmitLoadIndexedGeneric(this);
733 } 734 }
734 ASSERT(locs()->out().reg() == RAX); 735 ASSERT(locs()->out().reg() == RAX);
735 return; 736 return;
736 } 737 }
737 738
738 Register receiver = locs()->in(0).reg(); 739 Register receiver = locs()->in(0).reg();
739 Register index = locs()->in(1).reg(); 740 Register index = locs()->in(1).reg();
740 Register result = locs()->out().reg(); 741 Register result = locs()->out().reg();
741 742
742 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 743 const DeoptReasonId deopt_reason =
744 (receiver_type() == kGrowableObjectArrayCid) ?
743 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 745 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
744 746
745 Label* deopt = compiler->AddDeoptStub(deopt_id(), 747 Label* deopt = compiler->AddDeoptStub(deopt_id(),
746 token_pos(), 748 token_pos(),
747 try_index(), 749 try_index(),
748 deopt_reason, 750 deopt_reason,
749 receiver, 751 receiver,
750 index); 752 index);
751 753
752 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 754 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
753 __ j(ZERO, deopt); 755 __ j(ZERO, deopt);
754 __ CompareClassId(receiver, receiver_type()); 756 __ CompareClassId(receiver, receiver_type());
755 __ j(NOT_EQUAL, deopt); 757 __ j(NOT_EQUAL, deopt);
756 758
757 __ testq(index, Immediate(kSmiTagMask)); 759 __ testq(index, Immediate(kSmiTagMask));
758 __ j(NOT_ZERO, deopt); 760 __ j(NOT_ZERO, deopt);
759 761
760 switch (receiver_type()) { 762 switch (receiver_type()) {
761 case kArray: 763 case kArrayCid:
762 case kImmutableArray: 764 case kImmutableArrayCid:
763 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); 765 __ cmpq(index, FieldAddress(receiver, Array::length_offset()));
764 __ j(ABOVE_EQUAL, deopt); 766 __ j(ABOVE_EQUAL, deopt);
765 // Note that index is Smi, i.e, times 4. 767 // Note that index is Smi, i.e, times 4.
766 ASSERT(kSmiTagShift == 1); 768 ASSERT(kSmiTagShift == 1);
767 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); 769 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)));
768 break; 770 break;
769 771
770 case kGrowableObjectArray: { 772 case kGrowableObjectArrayCid: {
771 Register temp = locs()->temp(0).reg(); 773 Register temp = locs()->temp(0).reg();
772 774
773 __ cmpq(index, 775 __ cmpq(index,
774 FieldAddress(receiver, GrowableObjectArray::length_offset())); 776 FieldAddress(receiver, GrowableObjectArray::length_offset()));
775 __ j(ABOVE_EQUAL, deopt); 777 __ j(ABOVE_EQUAL, deopt);
776 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 778 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
777 // Note that index is Smi, i.e, times 4. 779 // Note that index is Smi, i.e, times 4.
778 ASSERT(kSmiTagShift == 1); 780 ASSERT(kSmiTagShift == 1);
779 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); 781 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray)));
780 break; 782 break;
781 } 783 }
782 784
783 default: 785 default:
784 UNREACHABLE(); 786 UNREACHABLE();
785 break; 787 break;
786 } 788 }
787 } 789 }
788 790
789 791
790 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 792 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
791 const intptr_t kNumInputs = 3; 793 const intptr_t kNumInputs = 3;
792 if (receiver_type() == kGrowableObjectArray) { 794 if (receiver_type() == kGrowableObjectArrayCid) {
793 const intptr_t kNumTemps = 1; 795 const intptr_t kNumTemps = 1;
794 LocationSummary* locs = 796 LocationSummary* locs =
795 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
796 locs->set_in(0, Location::RequiresRegister()); 798 locs->set_in(0, Location::RequiresRegister());
797 locs->set_in(1, Location::RequiresRegister()); 799 locs->set_in(1, Location::RequiresRegister());
798 locs->set_in(2, Location::RequiresRegister()); 800 locs->set_in(2, Location::RequiresRegister());
799 locs->set_temp(0, Location::RequiresRegister()); 801 locs->set_temp(0, Location::RequiresRegister());
800 locs->set_out(Location::NoLocation()); 802 locs->set_out(Location::NoLocation());
801 return locs; 803 return locs;
802 } else if (receiver_type() == kArray) { 804 } else if (receiver_type() == kArrayCid) {
803 return LocationSummary::Make(kNumInputs, 805 return LocationSummary::Make(kNumInputs,
804 Location::NoLocation(), 806 Location::NoLocation(),
805 LocationSummary::kNoCall); 807 LocationSummary::kNoCall);
806 } else { 808 } else {
807 ASSERT(receiver_type() == kIllegalObjectKind); 809 ASSERT(receiver_type() == kIllegalCid);
808 return MakeCallSummary(); 810 return MakeCallSummary();
809 } 811 }
810 } 812 }
811 813
812 814
813 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, 815 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
814 StoreIndexedComp* comp) { 816 StoreIndexedComp* comp) {
815 const String& function_name = 817 const String& function_name =
816 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 818 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
817 819
(...skipping 18 matching lines...) Expand all
836 StoreIndexedComp* comp) { 838 StoreIndexedComp* comp) {
837 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 839 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
838 comp->token_pos(), 840 comp->token_pos(),
839 comp->try_index(), 841 comp->try_index(),
840 kDeoptStoreIndexedPolymorphic); 842 kDeoptStoreIndexedPolymorphic);
841 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 843 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
842 ASSERT(comp->HasICData()); 844 ASSERT(comp->HasICData());
843 const ICData& ic_data = *comp->ic_data(); 845 const ICData& ic_data = *comp->ic_data();
844 ASSERT(ic_data.num_args_tested() == 1); 846 ASSERT(ic_data.num_args_tested() == 1);
845 // No indexed access on Smi. 847 // No indexed access on Smi.
846 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 848 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
847 // Load receiver into RAX. 849 // Load receiver into RAX.
848 const intptr_t kNumArguments = 3; 850 const intptr_t kNumArguments = 3;
849 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 851 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
850 __ testq(RAX, Immediate(kSmiTagMask)); 852 __ testq(RAX, Immediate(kSmiTagMask));
851 __ j(ZERO, deopt); 853 __ j(ZERO, deopt);
852 __ LoadClassId(RDI, RAX); 854 __ LoadClassId(RDI, RAX);
853 compiler->EmitTestAndCall(ic_data, 855 compiler->EmitTestAndCall(ic_data,
854 RDI, // Class id register. 856 RDI, // Class id register.
855 kNumArguments, 857 kNumArguments,
856 Array::Handle(), // No named arguments. 858 Array::Handle(), // No named arguments.
857 deopt, // deoptimize label. 859 deopt, // deoptimize label.
858 NULL, // fallthrough when done. 860 NULL, // fallthrough when done.
859 comp->deopt_id(), 861 comp->deopt_id(),
860 comp->token_pos(), 862 comp->token_pos(),
861 comp->try_index()); 863 comp->try_index());
862 } 864 }
863 865
864 866
865 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 867 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
866 if (receiver_type() == kIllegalObjectKind) { 868 if (receiver_type() == kIllegalCid) {
867 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 869 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
868 EmitStoreIndexedPolymorphic(compiler, this); 870 EmitStoreIndexedPolymorphic(compiler, this);
869 } else { 871 } else {
870 EmitStoreIndexedGeneric(compiler, this); 872 EmitStoreIndexedGeneric(compiler, this);
871 } 873 }
872 return; 874 return;
873 } 875 }
874 876
875 Register receiver = locs()->in(0).reg(); 877 Register receiver = locs()->in(0).reg();
876 Register index = locs()->in(1).reg(); 878 Register index = locs()->in(1).reg();
877 Register value = locs()->in(2).reg(); 879 Register value = locs()->in(2).reg();
878 880
879 Label* deopt = compiler->AddDeoptStub(deopt_id(), 881 Label* deopt = compiler->AddDeoptStub(deopt_id(),
880 token_pos(), 882 token_pos(),
881 try_index(), 883 try_index(),
882 kDeoptStoreIndexed, 884 kDeoptStoreIndexed,
883 receiver, 885 receiver,
884 index, 886 index,
885 value); 887 value);
886 888
887 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 889 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
888 __ j(ZERO, deopt); 890 __ j(ZERO, deopt);
889 __ CompareClassId(receiver, receiver_type()); 891 __ CompareClassId(receiver, receiver_type());
890 __ j(NOT_EQUAL, deopt); 892 __ j(NOT_EQUAL, deopt);
891 893
892 __ testq(index, Immediate(kSmiTagMask)); 894 __ testq(index, Immediate(kSmiTagMask));
893 __ j(NOT_ZERO, deopt); 895 __ j(NOT_ZERO, deopt);
894 896
895 switch (receiver_type()) { 897 switch (receiver_type()) {
896 case kArray: 898 case kArrayCid:
897 case kImmutableArray: 899 case kImmutableArrayCid:
898 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); 900 __ cmpq(index, FieldAddress(receiver, Array::length_offset()));
899 __ j(ABOVE_EQUAL, deopt); 901 __ j(ABOVE_EQUAL, deopt);
900 // Note that index is Smi, i.e, times 4. 902 // Note that index is Smi, i.e, times 4.
901 ASSERT(kSmiTagShift == 1); 903 ASSERT(kSmiTagShift == 1);
902 __ StoreIntoObject(receiver, 904 __ StoreIntoObject(receiver,
903 FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), 905 FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)),
904 value); 906 value);
905 break; 907 break;
906 908
907 case kGrowableObjectArray: { 909 case kGrowableObjectArrayCid: {
908 Register temp = locs()->temp(0).reg(); 910 Register temp = locs()->temp(0).reg();
909 __ cmpq(index, 911 __ cmpq(index,
910 FieldAddress(receiver, GrowableObjectArray::length_offset())); 912 FieldAddress(receiver, GrowableObjectArray::length_offset()));
911 __ j(ABOVE_EQUAL, deopt); 913 __ j(ABOVE_EQUAL, deopt);
912 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 914 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
913 // Note that index is Smi, i.e, times 4. 915 // Note that index is Smi, i.e, times 4.
914 ASSERT(kSmiTagShift == 1); 916 ASSERT(kSmiTagShift == 1);
915 __ StoreIntoObject(temp, 917 __ StoreIntoObject(temp,
916 FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), 918 FieldAddress(temp, index, TIMES_4, sizeof(RawArray)),
917 value); 919 value);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1123 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1122 } 1124 }
1123 // Instantiate non-null type arguments. 1125 // Instantiate non-null type arguments.
1124 if (type_arguments().IsUninstantiatedIdentity()) { 1126 if (type_arguments().IsUninstantiatedIdentity()) {
1125 // Check if the instantiator type argument vector is a TypeArguments of a 1127 // Check if the instantiator type argument vector is a TypeArguments of a
1126 // matching length and, if so, use it as the instantiated type_arguments. 1128 // matching length and, if so, use it as the instantiated type_arguments.
1127 // No need to check the instantiator ('instantiator_reg') for null here, 1129 // No need to check the instantiator ('instantiator_reg') for null here,
1128 // because a null instantiator will have the wrong class (Null instead of 1130 // because a null instantiator will have the wrong class (Null instead of
1129 // TypeArguments). 1131 // TypeArguments).
1130 Label type_arguments_uninstantiated; 1132 Label type_arguments_uninstantiated;
1131 __ CompareClassId(instantiator_reg, kTypeArguments); 1133 __ CompareClassId(instantiator_reg, kTypeArgumentsCid);
1132 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1134 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1133 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1135 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1134 Immediate(Smi::RawValue(len))); 1136 Immediate(Smi::RawValue(len)));
1135 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1137 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1136 __ Bind(&type_arguments_uninstantiated); 1138 __ Bind(&type_arguments_uninstantiated);
1137 } 1139 }
1138 // A runtime call to instantiate the type arguments is required. 1140 // A runtime call to instantiate the type arguments is required.
1139 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1141 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1140 __ PushObject(type_arguments()); 1142 __ PushObject(type_arguments());
1141 __ pushq(instantiator_reg); // Push instantiator type arguments. 1143 __ pushq(instantiator_reg); // Push instantiator type arguments.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 __ cmpq(instantiator_reg, raw_null); 1184 __ cmpq(instantiator_reg, raw_null);
1183 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1185 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1184 } 1186 }
1185 // Instantiate non-null type arguments. 1187 // Instantiate non-null type arguments.
1186 if (type_arguments().IsUninstantiatedIdentity()) { 1188 if (type_arguments().IsUninstantiatedIdentity()) {
1187 // Check if the instantiator type argument vector is a TypeArguments of a 1189 // Check if the instantiator type argument vector is a TypeArguments of a
1188 // matching length and, if so, use it as the instantiated type_arguments. 1190 // matching length and, if so, use it as the instantiated type_arguments.
1189 // No need to check instantiator_reg for null here, because a null 1191 // No need to check instantiator_reg for null here, because a null
1190 // instantiator will have the wrong class (Null instead of TypeArguments). 1192 // instantiator will have the wrong class (Null instead of TypeArguments).
1191 Label type_arguments_uninstantiated; 1193 Label type_arguments_uninstantiated;
1192 __ CompareClassId(instantiator_reg, kTypeArguments); 1194 __ CompareClassId(instantiator_reg, kTypeArgumentsCid);
1193 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1195 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1194 Immediate arguments_length = 1196 Immediate arguments_length =
1195 Immediate(Smi::RawValue(type_arguments().Length())); 1197 Immediate(Smi::RawValue(type_arguments().Length()));
1196 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1198 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1197 arguments_length); 1199 arguments_length);
1198 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1200 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1199 __ Bind(&type_arguments_uninstantiated); 1201 __ Bind(&type_arguments_uninstantiated);
1200 } 1202 }
1201 // In the non-factory case, we rely on the allocation stub to 1203 // In the non-factory case, we rely on the allocation stub to
1202 // instantiate the type arguments. 1204 // instantiate the type arguments.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 // TODO(regis): The following emitted code is duplicated in 1251 // TODO(regis): The following emitted code is duplicated in
1250 // VisitExtractConstructorTypeArguments above. The reason is that the code 1252 // VisitExtractConstructorTypeArguments above. The reason is that the code
1251 // is split between two computations, so that each one produces a 1253 // is split between two computations, so that each one produces a
1252 // single value, rather than producing a pair of values. 1254 // single value, rather than producing a pair of values.
1253 // If this becomes an issue, we should expose these tests at the IL level. 1255 // If this becomes an issue, we should expose these tests at the IL level.
1254 1256
1255 // Check if the instantiator type argument vector is a TypeArguments of a 1257 // Check if the instantiator type argument vector is a TypeArguments of a
1256 // matching length and, if so, use it as the instantiated type_arguments. 1258 // matching length and, if so, use it as the instantiated type_arguments.
1257 // No need to check the instantiator (RAX) for null here, because a null 1259 // No need to check the instantiator (RAX) for null here, because a null
1258 // instantiator will have the wrong class (Null instead of TypeArguments). 1260 // instantiator will have the wrong class (Null instead of TypeArguments).
1259 __ CompareClassId(instantiator_reg, kTypeArguments); 1261 __ CompareClassId(instantiator_reg, kTypeArgumentsCid);
1260 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1262 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1261 Immediate arguments_length = 1263 Immediate arguments_length =
1262 Immediate(Smi::RawValue(type_arguments().Length())); 1264 Immediate(Smi::RawValue(type_arguments().Length()));
1263 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1265 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1264 arguments_length); 1266 arguments_length);
1265 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1267 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1266 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1268 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1267 // instantiated type arguments, no proper instantiator needed. 1269 // instantiated type arguments, no proper instantiator needed.
1268 __ movq(instantiator_reg, 1270 __ movq(instantiator_reg,
1269 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1271 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1548 __ shlq(left, right_temp); 1550 __ shlq(left, right_temp);
1549 __ sarq(left, right_temp); 1551 __ sarq(left, right_temp);
1550 __ cmpq(left, temp); 1552 __ cmpq(left, temp);
1551 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow. 1553 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
1552 // Shift for result now we know there is no overflow. 1554 // Shift for result now we know there is no overflow.
1553 __ shlq(left, right_temp); 1555 __ shlq(left, right_temp);
1554 __ jmp(&done); 1556 __ jmp(&done);
1555 { 1557 {
1556 __ Bind(&call_method); 1558 __ Bind(&call_method);
1557 Function& target = Function::ZoneHandle( 1559 Function& target = Function::ZoneHandle(
1558 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1560 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1559 ASSERT(!target.IsNull()); 1561 ASSERT(!target.IsNull());
1560 const intptr_t kArgumentCount = 2; 1562 const intptr_t kArgumentCount = 2;
1561 __ pushq(temp); 1563 __ pushq(temp);
1562 __ pushq(right); 1564 __ pushq(right);
1563 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1565 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1564 comp->instance_call()->token_pos(), 1566 comp->instance_call()->token_pos(),
1565 comp->instance_call()->try_index(), 1567 comp->instance_call()->try_index(),
1566 target, 1568 target,
1567 kArgumentCount, 1569 kArgumentCount,
1568 Array::Handle()); // No argument names. 1570 Array::Handle()); // No argument names.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 comp->instance_call()->token_pos(), 1612 comp->instance_call()->token_pos(),
1611 comp->instance_call()->try_index(), 1613 comp->instance_call()->try_index(),
1612 kDeoptMintBinaryOp, 1614 kDeoptMintBinaryOp,
1613 left, 1615 left,
1614 right); 1616 right);
1615 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1617 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1616 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1618 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1617 __ j(NOT_ZERO, &non_smi); 1619 __ j(NOT_ZERO, &non_smi);
1618 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi? 1620 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1619 __ j(ZERO, &smi_smi); 1621 __ j(ZERO, &smi_smi);
1620 __ CompareClassId(right, kMint); // Is argument Mint? 1622 __ CompareClassId(right, kMintCid); // Is argument Mint?
1621 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. 1623 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1622 __ cmpq(left, Immediate(0)); 1624 __ cmpq(left, Immediate(0));
1623 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. 1625 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1624 1626
1625 // Positive Smi receiver, Mint argument. 1627 // Positive Smi receiver, Mint argument.
1626 // Load lower argument Mint word, convert to Smi. It is OK to loose bits. 1628 // Load lower argument Mint word, convert to Smi. It is OK to loose bits.
1627 __ movq(right, FieldAddress(right, Mint::value_offset())); 1629 __ movq(right, FieldAddress(right, Mint::value_offset()));
1628 __ SmiTag(right); 1630 __ SmiTag(right);
1629 __ andq(result, right); 1631 __ andq(result, right);
1630 __ jmp(&done); 1632 __ jmp(&done);
1631 1633
1632 __ Bind(&non_smi); // Receiver is non-Smi. 1634 __ Bind(&non_smi); // Receiver is non-Smi.
1633 __ CompareClassId(left, kMint); // Is receiver Mint? 1635 __ CompareClassId(left, kMintCid); // Is receiver Mint?
1634 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint. 1636 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint.
1635 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi? 1637 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1636 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument. 1638 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument.
1637 __ cmpq(right, Immediate(0)); 1639 __ cmpq(right, Immediate(0));
1638 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument. 1640 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument.
1639 1641
1640 // Mint receiver, positive Smi argument. 1642 // Mint receiver, positive Smi argument.
1641 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits. 1643 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1642 __ movq(result, FieldAddress(left, Mint::value_offset())); 1644 __ movq(result, FieldAddress(left, Mint::value_offset()));
1643 __ SmiTag(result); 1645 __ SmiTag(result);
1644 __ Bind(&smi_smi); 1646 __ Bind(&smi_smi);
1645 __ andq(result, right); 1647 __ andq(result, right);
1646 __ jmp(&done); 1648 __ jmp(&done);
1647 1649
1648 __ Bind(&smi_static_call); 1650 __ Bind(&smi_static_call);
1649 { 1651 {
1650 Function& target = Function::ZoneHandle( 1652 Function& target = Function::ZoneHandle(
1651 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1653 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1652 if (target.IsNull()) { 1654 if (target.IsNull()) {
1653 __ jmp(deopt); 1655 __ jmp(deopt);
1654 } else { 1656 } else {
1655 __ pushq(left); 1657 __ pushq(left);
1656 __ pushq(right); 1658 __ pushq(right);
1657 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1659 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1658 comp->instance_call()->token_pos(), 1660 comp->instance_call()->token_pos(),
1659 comp->instance_call()->try_index(), 1661 comp->instance_call()->try_index(),
1660 target, 1662 target,
1661 comp->instance_call()->ArgumentCount(), 1663 comp->instance_call()->ArgumentCount(),
1662 comp->instance_call()->argument_names()); 1664 comp->instance_call()->argument_names());
1663 ASSERT(result == RAX); 1665 ASSERT(result == RAX);
1664 __ jmp(&done); 1666 __ jmp(&done);
1665 } 1667 }
1666 } 1668 }
1667 1669
1668 __ Bind(&mint_static_call); 1670 __ Bind(&mint_static_call);
1669 { 1671 {
1670 Function& target = Function::ZoneHandle( 1672 Function& target = Function::ZoneHandle(
1671 comp->ic_data()->GetTargetForReceiverClassId(kMint)); 1673 comp->ic_data()->GetTargetForReceiverClassId(kMintCid));
1672 if (target.IsNull()) { 1674 if (target.IsNull()) {
1673 __ jmp(deopt); 1675 __ jmp(deopt);
1674 } else { 1676 } else {
1675 __ pushq(left); 1677 __ pushq(left);
1676 __ pushq(right); 1678 __ pushq(right);
1677 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1679 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1678 comp->instance_call()->token_pos(), 1680 comp->instance_call()->token_pos(),
1679 comp->instance_call()->try_index(), 1681 comp->instance_call()->try_index(),
1680 target, 1682 target,
1681 comp->instance_call()->ArgumentCount(), 1683 comp->instance_call()->ArgumentCount(),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1779 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1778 1780
1779 Register value = locs()->in(0).reg(); 1781 Register value = locs()->in(0).reg();
1780 Register result = locs()->out().reg(); 1782 Register result = locs()->out().reg();
1781 ASSERT(value == result); 1783 ASSERT(value == result);
1782 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1784 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1783 instance_call()->token_pos(), 1785 instance_call()->token_pos(),
1784 instance_call()->try_index(), 1786 instance_call()->try_index(),
1785 kDeoptUnaryOp, 1787 kDeoptUnaryOp,
1786 value); 1788 value);
1787 if (test_class_id == kSmi) { 1789 if (test_class_id == kSmiCid) {
1788 __ testq(value, Immediate(kSmiTagMask)); 1790 __ testq(value, Immediate(kSmiTagMask));
1789 __ j(NOT_ZERO, deopt); 1791 __ j(NOT_ZERO, deopt);
1790 switch (op_kind()) { 1792 switch (op_kind()) {
1791 case Token::kNEGATE: 1793 case Token::kNEGATE:
1792 __ negq(value); 1794 __ negq(value);
1793 __ j(OVERFLOW, deopt); 1795 __ j(OVERFLOW, deopt);
1794 break; 1796 break;
1795 case Token::kBIT_NOT: 1797 case Token::kBIT_NOT:
1796 __ notq(value); 1798 __ notq(value);
1797 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 1799 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1831 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1830 1832
1831 Register value = locs()->in(0).reg(); 1833 Register value = locs()->in(0).reg();
1832 Register result = locs()->out().reg(); 1834 Register result = locs()->out().reg();
1833 ASSERT(value == result); 1835 ASSERT(value == result);
1834 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1836 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1835 instance_call()->token_pos(), 1837 instance_call()->token_pos(),
1836 instance_call()->try_index(), 1838 instance_call()->try_index(),
1837 kDeoptUnaryOp, 1839 kDeoptUnaryOp,
1838 value); 1840 value);
1839 if (test_class_id == kDouble) { 1841 if (test_class_id == kDoubleCid) {
1840 Register temp = locs()->temp(0).reg(); 1842 Register temp = locs()->temp(0).reg();
1841 __ testq(value, Immediate(kSmiTagMask)); 1843 __ testq(value, Immediate(kSmiTagMask));
1842 __ j(ZERO, deopt); // Smi. 1844 __ j(ZERO, deopt); // Smi.
1843 __ CompareClassId(value, kDouble); 1845 __ CompareClassId(value, kDoubleCid);
1844 __ j(NOT_EQUAL, deopt); 1846 __ j(NOT_EQUAL, deopt);
1845 // Allocate result object. 1847 // Allocate result object.
1846 const Class& double_class = compiler->double_class(); 1848 const Class& double_class = compiler->double_class();
1847 const Code& stub = 1849 const Code& stub =
1848 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1850 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1849 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1851 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1850 __ pushq(value); 1852 __ pushq(value);
1851 compiler->GenerateCall(instance_call()->token_pos(), 1853 compiler->GenerateCall(instance_call()->token_pos(),
1852 instance_call()->try_index(), 1854 instance_call()->try_index(),
1853 &label, 1855 &label,
1854 PcDescriptors::kOther); 1856 PcDescriptors::kOther);
1855 // Result is in RAX. 1857 // Result is in RAX.
1856 ASSERT(result != temp); 1858 ASSERT(result != temp);
1857 __ movq(result, RAX); 1859 __ movq(result, RAX);
1858 __ popq(temp); 1860 __ popq(temp);
1859 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1861 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1860 __ DoubleNegate(XMM0); 1862 __ DoubleNegate(XMM0);
1861 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1863 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1862 } else { 1864 } else {
1863 UNREACHABLE(); 1865 UNREACHABLE();
1864 } 1866 }
1865 } 1867 }
1866 1868
1867 1869
1868 LocationSummary* ToDoubleComp::MakeLocationSummary() const { 1870 LocationSummary* ToDoubleComp::MakeLocationSummary() const {
1869 const intptr_t kNumInputs = 1; 1871 const intptr_t kNumInputs = 1;
1870 if (from() == kDouble) { 1872 if (from() == kDoubleCid) {
1871 const intptr_t kNumTemps = 0; 1873 const intptr_t kNumTemps = 0;
1872 LocationSummary* locs = 1874 LocationSummary* locs =
1873 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1875 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1874 locs->set_in(0, Location::RequiresRegister()); 1876 locs->set_in(0, Location::RequiresRegister());
1875 locs->set_out(Location::SameAsFirstInput()); 1877 locs->set_out(Location::SameAsFirstInput());
1876 return locs; 1878 return locs;
1877 } else { 1879 } else {
1878 ASSERT(from() == kSmi); 1880 ASSERT(from() == kSmiCid);
1879 return MakeCallSummary(); // Calls a stub to allocate result. 1881 return MakeCallSummary(); // Calls a stub to allocate result.
1880 } 1882 }
1881 } 1883 }
1882 1884
1883 1885
1884 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1886 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1885 Register value = (from() == kDouble) ? locs()->in(0).reg() : RBX; 1887 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : RBX;
1886 Register result = locs()->out().reg(); 1888 Register result = locs()->out().reg();
1887 1889
1888 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1890 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ?
1889 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1891 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1890 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1892 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1891 instance_call()->token_pos(), 1893 instance_call()->token_pos(),
1892 instance_call()->try_index(), 1894 instance_call()->try_index(),
1893 deopt_reason, 1895 deopt_reason,
1894 value); 1896 value);
1895 1897
1896 if (from() == kDouble) { 1898 if (from() == kDoubleCid) {
1897 __ testq(value, Immediate(kSmiTagMask)); 1899 __ testq(value, Immediate(kSmiTagMask));
1898 __ j(ZERO, deopt); // Deoptimize if Smi. 1900 __ j(ZERO, deopt); // Deoptimize if Smi.
1899 __ CompareClassId(value, kDouble); 1901 __ CompareClassId(value, kDoubleCid);
1900 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1902 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1901 ASSERT(value == result); 1903 ASSERT(value == result);
1902 return; 1904 return;
1903 } 1905 }
1904 1906
1905 ASSERT(from() == kSmi); 1907 ASSERT(from() == kSmiCid);
1906 1908
1907 const Class& double_class = compiler->double_class(); 1909 const Class& double_class = compiler->double_class();
1908 const Code& stub = 1910 const Code& stub =
1909 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1911 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1910 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1912 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1911 1913
1912 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 1914 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
1913 compiler->GenerateCall(instance_call()->token_pos(), 1915 compiler->GenerateCall(instance_call()->token_pos(),
1914 instance_call()->try_index(), 1916 instance_call()->try_index(),
1915 &label, 1917 &label,
(...skipping 20 matching lines...) Expand all
1936 instance_call()->try_index(), 1938 instance_call()->try_index(),
1937 kDeoptPolymorphicInstanceCallTestFail); 1939 kDeoptPolymorphicInstanceCallTestFail);
1938 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1940 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1939 __ jmp(deopt); 1941 __ jmp(deopt);
1940 return; 1942 return;
1941 } 1943 }
1942 ASSERT(HasICData()); 1944 ASSERT(HasICData());
1943 ASSERT(ic_data()->num_args_tested() == 1); 1945 ASSERT(ic_data()->num_args_tested() == 1);
1944 Label handle_smi; 1946 Label handle_smi;
1945 Label* is_smi_label = 1947 Label* is_smi_label =
1946 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1948 ic_data()->GetReceiverClassIdAt(0) == kSmiCid ? &handle_smi : deopt;
1947 1949
1948 // Load receiver into RAX. 1950 // Load receiver into RAX.
1949 __ movq(RAX, 1951 __ movq(RAX,
1950 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1952 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1951 __ testq(RAX, Immediate(kSmiTagMask)); 1953 __ testq(RAX, Immediate(kSmiTagMask));
1952 __ j(ZERO, is_smi_label); 1954 __ j(ZERO, is_smi_label);
1953 Label done; 1955 Label done;
1954 __ LoadClassId(RDI, RAX); 1956 __ LoadClassId(RDI, RAX);
1955 compiler->EmitTestAndCall(*ic_data(), 1957 compiler->EmitTestAndCall(*ic_data(),
1956 RDI, // Class id register. 1958 RDI, // Class id register.
1957 instance_call()->ArgumentCount(), 1959 instance_call()->ArgumentCount(),
1958 instance_call()->argument_names(), 1960 instance_call()->argument_names(),
1959 deopt, 1961 deopt,
1960 (is_smi_label == &handle_smi) ? &done : NULL, 1962 (is_smi_label == &handle_smi) ? &done : NULL,
1961 instance_call()->deopt_id(), 1963 instance_call()->deopt_id(),
1962 instance_call()->token_pos(), 1964 instance_call()->token_pos(),
1963 instance_call()->try_index()); 1965 instance_call()->try_index());
1964 if (is_smi_label == &handle_smi) { 1966 if (is_smi_label == &handle_smi) {
1965 __ Bind(&handle_smi); 1967 __ Bind(&handle_smi);
1966 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1968 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid);
1967 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1969 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1968 compiler->GenerateStaticCall(instance_call()->deopt_id(), 1970 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1969 instance_call()->token_pos(), 1971 instance_call()->token_pos(),
1970 instance_call()->try_index(), 1972 instance_call()->try_index(),
1971 target, 1973 target,
1972 instance_call()->ArgumentCount(), 1974 instance_call()->ArgumentCount(),
1973 instance_call()->argument_names()); 1975 instance_call()->argument_names());
1974 } 1976 }
1975 __ Bind(&done); 1977 __ Bind(&done);
1976 } 1978 }
(...skipping 14 matching lines...) Expand all
1991 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { 1993 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) {
1992 const int kNumInputs = 2; 1994 const int kNumInputs = 2;
1993 const int kNumTemps = 0; 1995 const int kNumTemps = 0;
1994 LocationSummary* locs = 1996 LocationSummary* locs =
1995 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1996 locs->set_in(0, Location::RequiresRegister()); 1998 locs->set_in(0, Location::RequiresRegister());
1997 locs->set_in(1, Location::RequiresRegister()); 1999 locs->set_in(1, Location::RequiresRegister());
1998 return locs; 2000 return locs;
1999 } 2001 }
2000 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 2002 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
2001 if (ICDataWithBothClassIds(*ic_data(), kSmi) || 2003 if (ICDataWithBothClassIds(*ic_data(), kSmiCid) ||
2002 ICDataWithBothClassIds(*ic_data(), kDouble)) { 2004 ICDataWithBothClassIds(*ic_data(), kDoubleCid)) {
2003 const intptr_t kNumInputs = 2; 2005 const intptr_t kNumInputs = 2;
2004 const intptr_t kNumTemps = 1; 2006 const intptr_t kNumTemps = 1;
2005 LocationSummary* summary = 2007 LocationSummary* summary =
2006 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2008 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2007 summary->set_in(0, Location::RequiresRegister()); 2009 summary->set_in(0, Location::RequiresRegister());
2008 summary->set_in(1, Location::RequiresRegister()); 2010 summary->set_in(1, Location::RequiresRegister());
2009 summary->set_temp(0, Location::RequiresRegister()); 2011 summary->set_temp(0, Location::RequiresRegister());
2010 return summary; 2012 return summary;
2011 } 2013 }
2012 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2014 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
(...skipping 17 matching lines...) Expand all
2030 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { 2032 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) {
2031 Register left = locs()->in(0).reg(); 2033 Register left = locs()->in(0).reg();
2032 Register right = locs()->in(1).reg(); 2034 Register right = locs()->in(1).reg();
2033 __ cmpq(left, right); 2035 __ cmpq(left, right);
2034 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 2036 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
2035 EmitBranchOnCondition(compiler, cond); 2037 EmitBranchOnCondition(compiler, cond);
2036 return; 2038 return;
2037 } 2039 }
2038 // Relational or equality. 2040 // Relational or equality.
2039 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 2041 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
2040 if (ICDataWithBothClassIds(*ic_data(), kSmi)) { 2042 if (ICDataWithBothClassIds(*ic_data(), kSmiCid)) {
2041 EmitSmiComparisonOp(compiler, *locs(), kind(), this, 2043 EmitSmiComparisonOp(compiler, *locs(), kind(), this,
2042 deopt_id(), token_pos(), try_index()); 2044 deopt_id(), token_pos(), try_index());
2043 return; 2045 return;
2044 } 2046 }
2045 if (ICDataWithBothClassIds(*ic_data(), kDouble)) { 2047 if (ICDataWithBothClassIds(*ic_data(), kDoubleCid)) {
2046 EmitDoubleComparisonOp(compiler, *locs(), kind(), this, 2048 EmitDoubleComparisonOp(compiler, *locs(), kind(), this,
2047 deopt_id(), token_pos(), try_index()); 2049 deopt_id(), token_pos(), try_index());
2048 return; 2050 return;
2049 } 2051 }
2050 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. 2052 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
2051 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2053 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
2052 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2054 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(),
2053 deopt_id(), token_pos(), try_index()); 2055 deopt_id(), token_pos(), try_index());
2054 return; 2056 return;
2055 } 2057 }
(...skipping 20 matching lines...) Expand all
2076 ASSERT(locs()->out().reg() == RAX); 2078 ASSERT(locs()->out().reg() == RAX);
2077 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2079 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2078 EmitBranchOnCondition(compiler, branch_condition); 2080 EmitBranchOnCondition(compiler, branch_condition);
2079 } 2081 }
2080 2082
2081 } // namespace dart 2083 } // namespace dart
2082 2084
2083 #undef __ 2085 #undef __
2084 2086
2085 #endif // defined TARGET_ARCH_X64 2087 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language_ia32.cc ('k') | vm/intrinsifier_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698