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

Side by Side Diff: vm/intermediate_language_ia32.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.h ('k') | vm/intermediate_language_x64.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 case Token::kGTE: return GREATER_EQUAL; 235 case Token::kGTE: return GREATER_EQUAL;
236 default: 236 default:
237 UNREACHABLE(); 237 UNREACHABLE();
238 return OVERFLOW; 238 return OVERFLOW;
239 } 239 }
240 } 240 }
241 241
242 242
243 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 243 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
244 const intptr_t kNumInputs = 2; 244 const intptr_t kNumInputs = 2;
245 if (receiver_class_id() != kObject) { 245 if (receiver_class_id() != kObjectCid) {
246 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); 246 ASSERT((receiver_class_id() == kSmiCid) ||
247 (receiver_class_id() == kDoubleCid));
247 const intptr_t kNumTemps = 1; 248 const intptr_t kNumTemps = 1;
248 LocationSummary* locs = 249 LocationSummary* locs =
249 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 250 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
250 locs->set_in(0, Location::RequiresRegister()); 251 locs->set_in(0, Location::RequiresRegister());
251 locs->set_in(1, Location::RequiresRegister()); 252 locs->set_in(1, Location::RequiresRegister());
252 locs->set_temp(0, Location::RequiresRegister()); 253 locs->set_temp(0, Location::RequiresRegister());
253 locs->set_out(Location::RequiresRegister()); 254 locs->set_out(Location::RequiresRegister());
254 return locs; 255 return locs;
255 } 256 }
256 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 257 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 ASSERT(ic_data.NumberOfChecks() > 0); 319 ASSERT(ic_data.NumberOfChecks() > 0);
319 ASSERT(ic_data.num_args_tested() == 1); 320 ASSERT(ic_data.num_args_tested() == 1);
320 Label* deopt = compiler->AddDeoptStub(deopt_id, 321 Label* deopt = compiler->AddDeoptStub(deopt_id,
321 token_pos, 322 token_pos,
322 try_index, 323 try_index,
323 kDeoptEquality); 324 kDeoptEquality);
324 Register left = locs.in(0).reg(); 325 Register left = locs.in(0).reg();
325 Register right = locs.in(1).reg(); 326 Register right = locs.in(1).reg();
326 __ testl(left, Immediate(kSmiTagMask)); 327 __ testl(left, Immediate(kSmiTagMask));
327 Register temp = locs.temp(0).reg(); 328 Register temp = locs.temp(0).reg();
328 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 329 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
329 Label done, load_class_id; 330 Label done, load_class_id;
330 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 331 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
331 __ movl(temp, Immediate(kSmi)); 332 __ movl(temp, Immediate(kSmiCid));
332 __ jmp(&done, Assembler::kNearJump); 333 __ jmp(&done, Assembler::kNearJump);
333 __ Bind(&load_class_id); 334 __ Bind(&load_class_id);
334 __ LoadClassId(temp, left); 335 __ LoadClassId(temp, left);
335 __ Bind(&done); 336 __ Bind(&done);
336 } else { 337 } else {
337 __ j(ZERO, deopt); // Smi deopts. 338 __ j(ZERO, deopt); // Smi deopts.
338 __ LoadClassId(temp, left); 339 __ LoadClassId(temp, left);
339 } 340 }
340 Condition cond = TokenKindToSmiCondition(kind); 341 Condition cond = TokenKindToSmiCondition(kind);
341 Label done; 342 Label done;
342 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 343 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
343 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0)); 344 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0));
344 Label next_test; 345 Label next_test;
345 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 346 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
346 __ j(NOT_EQUAL, &next_test); 347 __ j(NOT_EQUAL, &next_test);
347 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); 348 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
348 ObjectStore* object_store = Isolate::Current()->object_store(); 349 ObjectStore* object_store = Isolate::Current()->object_store();
349 if (target.owner() == object_store->object_class()) { 350 if (target.owner() == object_store->object_class()) {
350 // Object.== is same as ===. 351 // Object.== is same as ===.
351 __ Drop(2); 352 __ Drop(2);
352 __ cmpl(left, right); 353 __ cmpl(left, right);
353 if (branch != NULL) { 354 if (branch != NULL) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 compiler->EmitDoubleCompareBranch( 520 compiler->EmitDoubleCompareBranch(
520 true_condition, XMM0, XMM1, branch); 521 true_condition, XMM0, XMM1, branch);
521 } else { 522 } else {
522 compiler->EmitDoubleCompareBool( 523 compiler->EmitDoubleCompareBool(
523 true_condition, XMM0, XMM1, locs.out().reg()); 524 true_condition, XMM0, XMM1, locs.out().reg());
524 } 525 }
525 } 526 }
526 527
527 528
528 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 529 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
529 if (receiver_class_id() == kSmi) { 530 if (receiver_class_id() == kSmiCid) {
530 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 531 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
531 deopt_id(), token_pos(), try_index()); 532 deopt_id(), token_pos(), try_index());
532 return; 533 return;
533 } 534 }
534 if (receiver_class_id() == kDouble) { 535 if (receiver_class_id() == kDoubleCid) {
535 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 536 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
536 deopt_id(), token_pos(), try_index()); 537 deopt_id(), token_pos(), try_index());
537 return; 538 return;
538 } 539 }
539 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 540 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
540 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 541 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
541 deopt_id(), token_pos(), try_index()); 542 deopt_id(), token_pos(), try_index());
542 } else { 543 } else {
543 Register left = locs()->in(0).reg(); 544 Register left = locs()->in(0).reg();
544 Register right = locs()->in(1).reg(); 545 Register right = locs()->in(1).reg();
545 __ pushl(left); 546 __ pushl(left);
546 __ pushl(right); 547 __ pushl(right);
547 EmitEqualityAsInstanceCall(compiler, this); 548 EmitEqualityAsInstanceCall(compiler, this);
548 } 549 }
549 } 550 }
550 551
551 552
552 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 553 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
553 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) { 554 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) {
554 const intptr_t kNumInputs = 2; 555 const intptr_t kNumInputs = 2;
555 const intptr_t kNumTemps = 1; 556 const intptr_t kNumTemps = 1;
556 LocationSummary* summary = 557 LocationSummary* summary =
557 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 558 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
558 summary->set_in(0, Location::RequiresRegister()); 559 summary->set_in(0, Location::RequiresRegister());
559 summary->set_in(1, Location::RequiresRegister()); 560 summary->set_in(1, Location::RequiresRegister());
560 summary->set_out(Location::RequiresRegister()); 561 summary->set_out(Location::RequiresRegister());
561 summary->set_temp(0, Location::RequiresRegister()); 562 summary->set_temp(0, Location::RequiresRegister());
562 return summary; 563 return summary;
563 } 564 }
564 ASSERT(operands_class_id() == kObject); 565 ASSERT(operands_class_id() == kObjectCid);
565 return MakeCallSummary(); 566 return MakeCallSummary();
566 } 567 }
567 568
568 569
569 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 570 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
570 if (operands_class_id() == kSmi) { 571 if (operands_class_id() == kSmiCid) {
571 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 572 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
572 deopt_id(), token_pos(), try_index()); 573 deopt_id(), token_pos(), try_index());
573 return; 574 return;
574 } 575 }
575 if (operands_class_id() == kDouble) { 576 if (operands_class_id() == kDoubleCid) {
576 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 577 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
577 deopt_id(), token_pos(), try_index()); 578 deopt_id(), token_pos(), try_index());
578 return; 579 return;
579 } 580 }
580 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 581 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
581 Label* deopt = compiler->AddDeoptStub(deopt_id(), 582 Label* deopt = compiler->AddDeoptStub(deopt_id(),
582 token_pos(), 583 token_pos(),
583 try_index(), 584 try_index(),
584 kDeoptRelationalOp); 585 kDeoptRelationalOp);
585 // Load receiver into EAX, class into EDI. 586 // Load receiver into EAX, class into EDI.
586 Label done; 587 Label done;
587 const intptr_t kNumArguments = 2; 588 const intptr_t kNumArguments = 2;
588 __ movl(EDI, Immediate(kSmi)); 589 __ movl(EDI, Immediate(kSmiCid));
589 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 590 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
590 __ testl(EAX, Immediate(kSmiTagMask)); 591 __ testl(EAX, Immediate(kSmiTagMask));
591 __ j(ZERO, &done); 592 __ j(ZERO, &done);
592 __ LoadClassId(EDI, EAX); 593 __ LoadClassId(EDI, EAX);
593 __ Bind(&done); 594 __ Bind(&done);
594 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 595 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
595 EDI, // Class id register. 596 EDI, // Class id register.
596 kNumArguments, 597 kNumArguments,
597 Array::Handle(), // No named arguments. 598 Array::Handle(), // No named arguments.
598 deopt, // Deoptimize target. 599 deopt, // Deoptimize target.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 compiler->GenerateCall(token_pos(), 659 compiler->GenerateCall(token_pos(),
659 try_index(), 660 try_index(),
660 &StubCode::CallNativeCFunctionLabel(), 661 &StubCode::CallNativeCFunctionLabel(),
661 PcDescriptors::kOther); 662 PcDescriptors::kOther);
662 __ popl(result); 663 __ popl(result);
663 } 664 }
664 665
665 666
666 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 667 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
667 const intptr_t kNumInputs = 2; 668 const intptr_t kNumInputs = 2;
668 if ((receiver_type() == kGrowableObjectArray) || 669 if ((receiver_type() == kGrowableObjectArrayCid) ||
669 (receiver_type() == kArray) || 670 (receiver_type() == kArrayCid) ||
670 (receiver_type() == kImmutableArray)) { 671 (receiver_type() == kImmutableArrayCid)) {
671 const intptr_t kNumTemps = 1; 672 const intptr_t kNumTemps = 1;
672 LocationSummary* locs = 673 LocationSummary* locs =
673 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
674 locs->set_in(0, Location::RequiresRegister()); 675 locs->set_in(0, Location::RequiresRegister());
675 locs->set_in(1, Location::RequiresRegister()); 676 locs->set_in(1, Location::RequiresRegister());
676 locs->set_temp(0, Location::RequiresRegister()); 677 locs->set_temp(0, Location::RequiresRegister());
677 locs->set_out(Location::RequiresRegister()); 678 locs->set_out(Location::RequiresRegister());
678 return locs; 679 return locs;
679 } else { 680 } else {
680 ASSERT(receiver_type() == kIllegalObjectKind); 681 ASSERT(receiver_type() == kIllegalCid);
681 return MakeCallSummary(); 682 return MakeCallSummary();
682 } 683 }
683 } 684 }
684 685
685 686
686 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 687 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
687 LoadIndexedComp* comp) { 688 LoadIndexedComp* comp) {
688 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 689 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
689 comp->token_pos(), 690 comp->token_pos(),
690 comp->try_index(), 691 comp->try_index(),
691 kDeoptLoadIndexedPolymorphic); 692 kDeoptLoadIndexedPolymorphic);
692 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 693 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
693 ASSERT(comp->HasICData()); 694 ASSERT(comp->HasICData());
694 const ICData& ic_data = *comp->ic_data(); 695 const ICData& ic_data = *comp->ic_data();
695 ASSERT(ic_data.num_args_tested() == 1); 696 ASSERT(ic_data.num_args_tested() == 1);
696 // No indexed access on Smi. 697 // No indexed access on Smi.
697 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 698 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
698 // Load receiver into EAX. 699 // Load receiver into EAX.
699 const intptr_t kNumArguments = 2; 700 const intptr_t kNumArguments = 2;
700 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 701 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
701 __ testl(EAX, Immediate(kSmiTagMask)); 702 __ testl(EAX, Immediate(kSmiTagMask));
702 __ j(ZERO, deopt); 703 __ j(ZERO, deopt);
703 __ LoadClassId(EDI, EAX); 704 __ LoadClassId(EDI, EAX);
704 compiler->EmitTestAndCall(ic_data, 705 compiler->EmitTestAndCall(ic_data,
705 EDI, // Class id register. 706 EDI, // Class id register.
706 kNumArguments, 707 kNumArguments,
707 Array::Handle(), // No named arguments. 708 Array::Handle(), // No named arguments.
708 deopt, // Deoptimize target. 709 deopt, // Deoptimize target.
709 NULL, // Fallthrough when done. 710 NULL, // Fallthrough when done.
710 comp->deopt_id(), 711 comp->deopt_id(),
711 comp->token_pos(), 712 comp->token_pos(),
712 comp->try_index()); 713 comp->try_index());
713 } 714 }
714 715
715 716
716 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 717 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
717 if (receiver_type() == kIllegalObjectKind) { 718 if (receiver_type() == kIllegalCid) {
718 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 719 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
719 EmitLoadIndexedPolymorphic(compiler, this); 720 EmitLoadIndexedPolymorphic(compiler, this);
720 } else { 721 } else {
721 compiler->EmitLoadIndexedGeneric(this); 722 compiler->EmitLoadIndexedGeneric(this);
722 } 723 }
723 ASSERT(locs()->out().reg() == EAX); 724 ASSERT(locs()->out().reg() == EAX);
724 return; 725 return;
725 } 726 }
726 727
727 Register receiver = locs()->in(0).reg(); 728 Register receiver = locs()->in(0).reg();
728 Register index = locs()->in(1).reg(); 729 Register index = locs()->in(1).reg();
729 Register result = locs()->out().reg(); 730 Register result = locs()->out().reg();
730 Register temp = locs()->temp(0).reg(); 731 Register temp = locs()->temp(0).reg();
731 732
732 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 733 const DeoptReasonId deopt_reason =
734 (receiver_type() == kGrowableObjectArrayCid) ?
733 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 735 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
734 736
735 Label* deopt = compiler->AddDeoptStub(deopt_id(), 737 Label* deopt = compiler->AddDeoptStub(deopt_id(),
736 token_pos(), 738 token_pos(),
737 try_index(), 739 try_index(),
738 deopt_reason, 740 deopt_reason,
739 receiver, 741 receiver,
740 index); 742 index);
741 743
742 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 744 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
743 __ j(ZERO, deopt); 745 __ j(ZERO, deopt);
744 __ CompareClassId(receiver, receiver_type(), temp); 746 __ CompareClassId(receiver, receiver_type(), temp);
745 __ j(NOT_EQUAL, deopt); 747 __ j(NOT_EQUAL, deopt);
746 748
747 __ testl(index, Immediate(kSmiTagMask)); 749 __ testl(index, Immediate(kSmiTagMask));
748 __ j(NOT_ZERO, deopt); 750 __ j(NOT_ZERO, deopt);
749 751
750 switch (receiver_type()) { 752 switch (receiver_type()) {
751 case kArray: 753 case kArrayCid:
752 case kImmutableArray: 754 case kImmutableArrayCid:
753 __ cmpl(index, FieldAddress(receiver, Array::length_offset())); 755 __ cmpl(index, FieldAddress(receiver, Array::length_offset()));
754 __ j(ABOVE_EQUAL, deopt); 756 __ j(ABOVE_EQUAL, deopt);
755 // Note that index is Smi, i.e, times 2. 757 // Note that index is Smi, i.e, times 2.
756 ASSERT(kSmiTagShift == 1); 758 ASSERT(kSmiTagShift == 1);
757 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray))); 759 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)));
758 break; 760 break;
759 761
760 case kGrowableObjectArray: { 762 case kGrowableObjectArrayCid: {
761 Register temp = locs()->temp(0).reg(); 763 Register temp = locs()->temp(0).reg();
762 764
763 __ cmpl(index, 765 __ cmpl(index,
764 FieldAddress(receiver, GrowableObjectArray::length_offset())); 766 FieldAddress(receiver, GrowableObjectArray::length_offset()));
765 __ j(ABOVE_EQUAL, deopt); 767 __ j(ABOVE_EQUAL, deopt);
766 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 768 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
767 // Note that index is Smi, i.e, times 2. 769 // Note that index is Smi, i.e, times 2.
768 ASSERT(kSmiTagShift == 1); 770 ASSERT(kSmiTagShift == 1);
769 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray))); 771 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray)));
770 break; 772 break;
771 } 773 }
772 774
773 default: 775 default:
774 UNREACHABLE(); 776 UNREACHABLE();
775 break; 777 break;
776 } 778 }
777 } 779 }
778 780
779 781
780 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 782 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
781 const intptr_t kNumInputs = 3; 783 const intptr_t kNumInputs = 3;
782 if ((receiver_type() == kGrowableObjectArray) || 784 if ((receiver_type() == kGrowableObjectArrayCid) ||
783 (receiver_type() == kArray)) { 785 (receiver_type() == kArrayCid)) {
784 const intptr_t kNumTemps = 1; 786 const intptr_t kNumTemps = 1;
785 LocationSummary* locs = 787 LocationSummary* locs =
786 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 788 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
787 locs->set_in(0, Location::RequiresRegister()); 789 locs->set_in(0, Location::RequiresRegister());
788 locs->set_in(1, Location::RequiresRegister()); 790 locs->set_in(1, Location::RequiresRegister());
789 locs->set_in(2, Location::RequiresRegister()); 791 locs->set_in(2, Location::RequiresRegister());
790 locs->set_temp(0, Location::RequiresRegister()); 792 locs->set_temp(0, Location::RequiresRegister());
791 locs->set_out(Location::NoLocation()); 793 locs->set_out(Location::NoLocation());
792 return locs; 794 return locs;
793 } else { 795 } else {
794 ASSERT(receiver_type() == kIllegalObjectKind); 796 ASSERT(receiver_type() == kIllegalCid);
795 return MakeCallSummary(); 797 return MakeCallSummary();
796 } 798 }
797 } 799 }
798 800
799 801
800 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, 802 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
801 StoreIndexedComp* comp) { 803 StoreIndexedComp* comp) {
802 const String& function_name = 804 const String& function_name =
803 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 805 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
804 806
(...skipping 18 matching lines...) Expand all
823 StoreIndexedComp* comp) { 825 StoreIndexedComp* comp) {
824 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 826 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
825 comp->token_pos(), 827 comp->token_pos(),
826 comp->try_index(), 828 comp->try_index(),
827 kDeoptStoreIndexedPolymorphic); 829 kDeoptStoreIndexedPolymorphic);
828 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 830 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
829 ASSERT(comp->HasICData()); 831 ASSERT(comp->HasICData());
830 const ICData& ic_data = *comp->ic_data(); 832 const ICData& ic_data = *comp->ic_data();
831 ASSERT(ic_data.num_args_tested() == 1); 833 ASSERT(ic_data.num_args_tested() == 1);
832 // No indexed access on Smi. 834 // No indexed access on Smi.
833 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 835 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
834 // Load receiver into EAX. 836 // Load receiver into EAX.
835 const intptr_t kNumArguments = 3; 837 const intptr_t kNumArguments = 3;
836 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 838 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
837 __ testl(EAX, Immediate(kSmiTagMask)); 839 __ testl(EAX, Immediate(kSmiTagMask));
838 __ j(ZERO, deopt); 840 __ j(ZERO, deopt);
839 __ LoadClassId(EDI, EAX); 841 __ LoadClassId(EDI, EAX);
840 compiler->EmitTestAndCall(ic_data, 842 compiler->EmitTestAndCall(ic_data,
841 EDI, // Class id register. 843 EDI, // Class id register.
842 kNumArguments, 844 kNumArguments,
843 Array::Handle(), // No named arguments. 845 Array::Handle(), // No named arguments.
844 deopt, // Deoptimize target. 846 deopt, // Deoptimize target.
845 NULL, // Fallthrough when done. 847 NULL, // Fallthrough when done.
846 comp->deopt_id(), 848 comp->deopt_id(),
847 comp->token_pos(), 849 comp->token_pos(),
848 comp->try_index()); 850 comp->try_index());
849 } 851 }
850 852
851 853
852 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 854 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
853 if (receiver_type() == kIllegalObjectKind) { 855 if (receiver_type() == kIllegalCid) {
854 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 856 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
855 EmitStoreIndexedPolymorphic(compiler, this); 857 EmitStoreIndexedPolymorphic(compiler, this);
856 } else { 858 } else {
857 EmitStoreIndexedGeneric(compiler, this); 859 EmitStoreIndexedGeneric(compiler, this);
858 } 860 }
859 return; 861 return;
860 } 862 }
861 863
862 Register receiver = locs()->in(0).reg(); 864 Register receiver = locs()->in(0).reg();
863 Register index = locs()->in(1).reg(); 865 Register index = locs()->in(1).reg();
(...skipping 10 matching lines...) Expand all
874 876
875 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 877 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
876 __ j(ZERO, deopt); 878 __ j(ZERO, deopt);
877 __ CompareClassId(receiver, receiver_type(), temp); 879 __ CompareClassId(receiver, receiver_type(), temp);
878 __ j(NOT_EQUAL, deopt); 880 __ j(NOT_EQUAL, deopt);
879 881
880 __ testl(index, Immediate(kSmiTagMask)); 882 __ testl(index, Immediate(kSmiTagMask));
881 __ j(NOT_ZERO, deopt); 883 __ j(NOT_ZERO, deopt);
882 884
883 switch (receiver_type()) { 885 switch (receiver_type()) {
884 case kArray: 886 case kArrayCid:
885 case kImmutableArray: 887 case kImmutableArrayCid:
886 __ cmpl(index, FieldAddress(receiver, Array::length_offset())); 888 __ cmpl(index, FieldAddress(receiver, Array::length_offset()));
887 __ j(ABOVE_EQUAL, deopt); 889 __ j(ABOVE_EQUAL, deopt);
888 // Note that index is Smi, i.e, times 2. 890 // Note that index is Smi, i.e, times 2.
889 ASSERT(kSmiTagShift == 1); 891 ASSERT(kSmiTagShift == 1);
890 __ StoreIntoObject(receiver, 892 __ StoreIntoObject(receiver,
891 FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)), 893 FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)),
892 value); 894 value);
893 break; 895 break;
894 896
895 case kGrowableObjectArray: { 897 case kGrowableObjectArrayCid: {
896 __ cmpl(index, 898 __ cmpl(index,
897 FieldAddress(receiver, GrowableObjectArray::length_offset())); 899 FieldAddress(receiver, GrowableObjectArray::length_offset()));
898 __ j(ABOVE_EQUAL, deopt); 900 __ j(ABOVE_EQUAL, deopt);
899 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 901 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
900 // Note that index is Smi, i.e, times 2. 902 // Note that index is Smi, i.e, times 2.
901 ASSERT(kSmiTagShift == 1); 903 ASSERT(kSmiTagShift == 1);
902 __ StoreIntoObject(temp, 904 __ StoreIntoObject(temp,
903 FieldAddress(temp, index, TIMES_2, sizeof(RawArray)), 905 FieldAddress(temp, index, TIMES_2, sizeof(RawArray)),
904 value); 906 value);
905 break; 907 break;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1113 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1112 } 1114 }
1113 // Instantiate non-null type arguments. 1115 // Instantiate non-null type arguments.
1114 if (type_arguments().IsUninstantiatedIdentity()) { 1116 if (type_arguments().IsUninstantiatedIdentity()) {
1115 // Check if the instantiator type argument vector is a TypeArguments of a 1117 // Check if the instantiator type argument vector is a TypeArguments of a
1116 // matching length and, if so, use it as the instantiated type_arguments. 1118 // matching length and, if so, use it as the instantiated type_arguments.
1117 // No need to check the instantiator ('instantiator_reg') for null here, 1119 // No need to check the instantiator ('instantiator_reg') for null here,
1118 // because a null instantiator will have the wrong class (Null instead of 1120 // because a null instantiator will have the wrong class (Null instead of
1119 // TypeArguments). 1121 // TypeArguments).
1120 Label type_arguments_uninstantiated; 1122 Label type_arguments_uninstantiated;
1121 __ CompareClassId(instantiator_reg, kTypeArguments, temp); 1123 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp);
1122 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1124 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1123 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1125 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1124 Immediate(Smi::RawValue(len))); 1126 Immediate(Smi::RawValue(len)));
1125 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1127 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1126 __ Bind(&type_arguments_uninstantiated); 1128 __ Bind(&type_arguments_uninstantiated);
1127 } 1129 }
1128 // A runtime call to instantiate the type arguments is required. 1130 // A runtime call to instantiate the type arguments is required.
1129 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1131 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1130 __ PushObject(type_arguments()); 1132 __ PushObject(type_arguments());
1131 __ pushl(instantiator_reg); // Push instantiator type arguments. 1133 __ pushl(instantiator_reg); // Push instantiator type arguments.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 __ cmpl(instantiator_reg, raw_null); 1176 __ cmpl(instantiator_reg, raw_null);
1175 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1177 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1176 } 1178 }
1177 // Instantiate non-null type arguments. 1179 // Instantiate non-null type arguments.
1178 if (type_arguments().IsUninstantiatedIdentity()) { 1180 if (type_arguments().IsUninstantiatedIdentity()) {
1179 // Check if the instantiator type argument vector is a TypeArguments of a 1181 // Check if the instantiator type argument vector is a TypeArguments of a
1180 // matching length and, if so, use it as the instantiated type_arguments. 1182 // matching length and, if so, use it as the instantiated type_arguments.
1181 // No need to check instantiator_reg for null here, because a null 1183 // No need to check instantiator_reg for null here, because a null
1182 // instantiator will have the wrong class (Null instead of TypeArguments). 1184 // instantiator will have the wrong class (Null instead of TypeArguments).
1183 Label type_arguments_uninstantiated; 1185 Label type_arguments_uninstantiated;
1184 __ CompareClassId(instantiator_reg, kTypeArguments, temp_reg); 1186 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
1185 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1187 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1186 Immediate arguments_length = 1188 Immediate arguments_length =
1187 Immediate(Smi::RawValue(type_arguments().Length())); 1189 Immediate(Smi::RawValue(type_arguments().Length()));
1188 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1190 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1189 arguments_length); 1191 arguments_length);
1190 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1192 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1191 __ Bind(&type_arguments_uninstantiated); 1193 __ Bind(&type_arguments_uninstantiated);
1192 } 1194 }
1193 // In the non-factory case, we rely on the allocation stub to 1195 // In the non-factory case, we rely on the allocation stub to
1194 // instantiate the type arguments. 1196 // instantiate the type arguments.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 // TODO(regis): The following emitted code is duplicated in 1245 // TODO(regis): The following emitted code is duplicated in
1244 // VisitExtractConstructorTypeArguments above. The reason is that the code 1246 // VisitExtractConstructorTypeArguments above. The reason is that the code
1245 // is split between two computations, so that each one produces a 1247 // is split between two computations, so that each one produces a
1246 // single value, rather than producing a pair of values. 1248 // single value, rather than producing a pair of values.
1247 // If this becomes an issue, we should expose these tests at the IL level. 1249 // If this becomes an issue, we should expose these tests at the IL level.
1248 1250
1249 // Check if the instantiator type argument vector is a TypeArguments of a 1251 // Check if the instantiator type argument vector is a TypeArguments of a
1250 // matching length and, if so, use it as the instantiated type_arguments. 1252 // matching length and, if so, use it as the instantiated type_arguments.
1251 // No need to check the instantiator (RAX) for null here, because a null 1253 // No need to check the instantiator (RAX) for null here, because a null
1252 // instantiator will have the wrong class (Null instead of TypeArguments). 1254 // instantiator will have the wrong class (Null instead of TypeArguments).
1253 __ CompareClassId(instantiator_reg, kTypeArguments, temp_reg); 1255 __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
1254 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1256 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1255 Immediate arguments_length = 1257 Immediate arguments_length =
1256 Immediate(Smi::RawValue(type_arguments().Length())); 1258 Immediate(Smi::RawValue(type_arguments().Length()));
1257 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1259 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1258 arguments_length); 1260 arguments_length);
1259 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 1261 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
1260 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1262 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1261 // instantiated type arguments, no proper instantiator needed. 1263 // instantiated type arguments, no proper instantiator needed.
1262 __ movl(instantiator_reg, 1264 __ movl(instantiator_reg,
1263 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1265 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 __ shll(left, right_temp); 1540 __ shll(left, right_temp);
1539 __ sarl(left, right_temp); 1541 __ sarl(left, right_temp);
1540 __ cmpl(left, temp); 1542 __ cmpl(left, temp);
1541 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow. 1543 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
1542 // Shift for result now we know there is no overflow. 1544 // Shift for result now we know there is no overflow.
1543 __ shll(left, right_temp); 1545 __ shll(left, right_temp);
1544 __ jmp(&done); 1546 __ jmp(&done);
1545 { 1547 {
1546 __ Bind(&call_method); 1548 __ Bind(&call_method);
1547 Function& target = Function::ZoneHandle( 1549 Function& target = Function::ZoneHandle(
1548 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1550 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1549 ASSERT(!target.IsNull()); 1551 ASSERT(!target.IsNull());
1550 const intptr_t kArgumentCount = 2; 1552 const intptr_t kArgumentCount = 2;
1551 __ pushl(temp); 1553 __ pushl(temp);
1552 __ pushl(right); 1554 __ pushl(right);
1553 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1555 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1554 comp->instance_call()->token_pos(), 1556 comp->instance_call()->token_pos(),
1555 comp->instance_call()->try_index(), 1557 comp->instance_call()->try_index(),
1556 target, 1558 target,
1557 kArgumentCount, 1559 kArgumentCount,
1558 Array::Handle()); // No argument names. 1560 Array::Handle()); // No argument names.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 comp->instance_call()->token_pos(), 1603 comp->instance_call()->token_pos(),
1602 comp->instance_call()->try_index(), 1604 comp->instance_call()->try_index(),
1603 kDeoptMintBinaryOp, 1605 kDeoptMintBinaryOp,
1604 left, 1606 left,
1605 right); 1607 right);
1606 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1608 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1607 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1609 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1608 __ j(NOT_ZERO, &non_smi); 1610 __ j(NOT_ZERO, &non_smi);
1609 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1611 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1610 __ j(ZERO, &smi_smi); 1612 __ j(ZERO, &smi_smi);
1611 __ CompareClassId(right, kMint, temp); // Is argument Mint? 1613 __ CompareClassId(right, kMintCid, temp); // Is argument Mint?
1612 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. 1614 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1613 __ cmpl(left, Immediate(0)); 1615 __ cmpl(left, Immediate(0));
1614 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. 1616 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1615 1617
1616 // Positive Smi receiver, Mint argument. 1618 // Positive Smi receiver, Mint argument.
1617 // Load lower argument Mint word, convert to Smi. It is OK to loose bits. 1619 // Load lower argument Mint word, convert to Smi. It is OK to loose bits.
1618 __ movl(right, FieldAddress(right, Mint::value_offset())); 1620 __ movl(right, FieldAddress(right, Mint::value_offset()));
1619 __ SmiTag(right); 1621 __ SmiTag(right);
1620 __ andl(result, right); 1622 __ andl(result, right);
1621 __ jmp(&done); 1623 __ jmp(&done);
1622 1624
1623 __ Bind(&non_smi); // Receiver is non-Smi. 1625 __ Bind(&non_smi); // Receiver is non-Smi.
1624 __ CompareClassId(left, kMint, temp); // Is receiver Mint? 1626 __ CompareClassId(left, kMintCid, temp); // Is receiver Mint?
1625 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint. 1627 __ j(NOT_EQUAL, deopt); // Receiver neither Smi nor Mint.
1626 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1628 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1627 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument. 1629 __ j(NOT_ZERO, &mint_static_call); // Mint receiver, non-Smi argument.
1628 __ cmpl(right, Immediate(0)); 1630 __ cmpl(right, Immediate(0));
1629 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument. 1631 __ j(LESS, &mint_static_call); // Mint receiver, negative Smi argument.
1630 1632
1631 // Mint receiver, positive Smi argument. 1633 // Mint receiver, positive Smi argument.
1632 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits. 1634 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1633 __ movl(result, FieldAddress(left, Mint::value_offset())); 1635 __ movl(result, FieldAddress(left, Mint::value_offset()));
1634 __ SmiTag(result); 1636 __ SmiTag(result);
1635 __ Bind(&smi_smi); 1637 __ Bind(&smi_smi);
1636 __ andl(result, right); 1638 __ andl(result, right);
1637 __ jmp(&done); 1639 __ jmp(&done);
1638 1640
1639 __ Bind(&smi_static_call); 1641 __ Bind(&smi_static_call);
1640 { 1642 {
1641 Function& target = Function::ZoneHandle( 1643 Function& target = Function::ZoneHandle(
1642 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1644 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1643 if (target.IsNull()) { 1645 if (target.IsNull()) {
1644 __ jmp(deopt); 1646 __ jmp(deopt);
1645 } else { 1647 } else {
1646 __ pushl(left); 1648 __ pushl(left);
1647 __ pushl(right); 1649 __ pushl(right);
1648 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1650 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1649 comp->instance_call()->token_pos(), 1651 comp->instance_call()->token_pos(),
1650 comp->instance_call()->try_index(), 1652 comp->instance_call()->try_index(),
1651 target, 1653 target,
1652 comp->instance_call()->ArgumentCount(), 1654 comp->instance_call()->ArgumentCount(),
1653 comp->instance_call()->argument_names()); 1655 comp->instance_call()->argument_names());
1654 ASSERT(result == EAX); 1656 ASSERT(result == EAX);
1655 __ jmp(&done); 1657 __ jmp(&done);
1656 } 1658 }
1657 } 1659 }
1658 1660
1659 __ Bind(&mint_static_call); 1661 __ Bind(&mint_static_call);
1660 { 1662 {
1661 Function& target = Function::ZoneHandle( 1663 Function& target = Function::ZoneHandle(
1662 comp->ic_data()->GetTargetForReceiverClassId(kMint)); 1664 comp->ic_data()->GetTargetForReceiverClassId(kMintCid));
1663 if (target.IsNull()) { 1665 if (target.IsNull()) {
1664 __ jmp(deopt); 1666 __ jmp(deopt);
1665 } else { 1667 } else {
1666 __ pushl(left); 1668 __ pushl(left);
1667 __ pushl(right); 1669 __ pushl(right);
1668 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1670 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1669 comp->instance_call()->token_pos(), 1671 comp->instance_call()->token_pos(),
1670 comp->instance_call()->try_index(), 1672 comp->instance_call()->try_index(),
1671 target, 1673 target,
1672 comp->instance_call()->ArgumentCount(), 1674 comp->instance_call()->ArgumentCount(),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1770 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1769 1771
1770 Register value = locs()->in(0).reg(); 1772 Register value = locs()->in(0).reg();
1771 Register result = locs()->out().reg(); 1773 Register result = locs()->out().reg();
1772 ASSERT(value == result); 1774 ASSERT(value == result);
1773 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1775 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1774 instance_call()->token_pos(), 1776 instance_call()->token_pos(),
1775 instance_call()->try_index(), 1777 instance_call()->try_index(),
1776 kDeoptUnaryOp, 1778 kDeoptUnaryOp,
1777 value); 1779 value);
1778 if (test_class_id == kSmi) { 1780 if (test_class_id == kSmiCid) {
1779 __ testl(value, Immediate(kSmiTagMask)); 1781 __ testl(value, Immediate(kSmiTagMask));
1780 __ j(NOT_ZERO, deopt); 1782 __ j(NOT_ZERO, deopt);
1781 switch (op_kind()) { 1783 switch (op_kind()) {
1782 case Token::kNEGATE: 1784 case Token::kNEGATE:
1783 __ negl(value); 1785 __ negl(value);
1784 __ j(OVERFLOW, deopt); 1786 __ j(OVERFLOW, deopt);
1785 break; 1787 break;
1786 case Token::kBIT_NOT: 1788 case Token::kBIT_NOT:
1787 __ notl(value); 1789 __ notl(value);
1788 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 1790 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1822 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1821 1823
1822 Register value = locs()->in(0).reg(); 1824 Register value = locs()->in(0).reg();
1823 Register result = locs()->out().reg(); 1825 Register result = locs()->out().reg();
1824 ASSERT(value == result); 1826 ASSERT(value == result);
1825 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1827 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1826 instance_call()->token_pos(), 1828 instance_call()->token_pos(),
1827 instance_call()->try_index(), 1829 instance_call()->try_index(),
1828 kDeoptUnaryOp, 1830 kDeoptUnaryOp,
1829 value); 1831 value);
1830 if (test_class_id == kDouble) { 1832 if (test_class_id == kDoubleCid) {
1831 Register temp = locs()->temp(0).reg(); 1833 Register temp = locs()->temp(0).reg();
1832 __ testl(value, Immediate(kSmiTagMask)); 1834 __ testl(value, Immediate(kSmiTagMask));
1833 __ j(ZERO, deopt); // Smi. 1835 __ j(ZERO, deopt); // Smi.
1834 __ CompareClassId(value, kDouble, temp); 1836 __ CompareClassId(value, kDoubleCid, temp);
1835 __ j(NOT_EQUAL, deopt); 1837 __ j(NOT_EQUAL, deopt);
1836 // Allocate result object. 1838 // Allocate result object.
1837 const Class& double_class = compiler->double_class(); 1839 const Class& double_class = compiler->double_class();
1838 const Code& stub = 1840 const Code& stub =
1839 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1841 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1840 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1842 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1841 __ pushl(value); 1843 __ pushl(value);
1842 compiler->GenerateCall(instance_call()->token_pos(), 1844 compiler->GenerateCall(instance_call()->token_pos(),
1843 instance_call()->try_index(), 1845 instance_call()->try_index(),
1844 &label, 1846 &label,
1845 PcDescriptors::kOther); 1847 PcDescriptors::kOther);
1846 // Result is in EAX. 1848 // Result is in EAX.
1847 ASSERT(result != temp); 1849 ASSERT(result != temp);
1848 __ movl(result, EAX); 1850 __ movl(result, EAX);
1849 __ popl(temp); 1851 __ popl(temp);
1850 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1852 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1851 __ DoubleNegate(XMM0); 1853 __ DoubleNegate(XMM0);
1852 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1854 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1853 } else { 1855 } else {
1854 UNREACHABLE(); 1856 UNREACHABLE();
1855 } 1857 }
1856 } 1858 }
1857 1859
1858 1860
1859 LocationSummary* ToDoubleComp::MakeLocationSummary() const { 1861 LocationSummary* ToDoubleComp::MakeLocationSummary() const {
1860 const intptr_t kNumInputs = 1; 1862 const intptr_t kNumInputs = 1;
1861 if (from() == kDouble) { 1863 if (from() == kDoubleCid) {
1862 const intptr_t kNumTemps = 1; 1864 const intptr_t kNumTemps = 1;
1863 LocationSummary* locs = 1865 LocationSummary* locs =
1864 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1865 locs->set_in(0, Location::RequiresRegister()); 1867 locs->set_in(0, Location::RequiresRegister());
1866 locs->set_temp(0, Location::RequiresRegister()); 1868 locs->set_temp(0, Location::RequiresRegister());
1867 locs->set_out(Location::SameAsFirstInput()); 1869 locs->set_out(Location::SameAsFirstInput());
1868 locs->set_temp(0, Location::RequiresRegister()); 1870 locs->set_temp(0, Location::RequiresRegister());
1869 return locs; 1871 return locs;
1870 } else { 1872 } else {
1871 ASSERT(from() == kSmi); 1873 ASSERT(from() == kSmiCid);
1872 return MakeCallSummary(); // Calls a stub to allocate result. 1874 return MakeCallSummary(); // Calls a stub to allocate result.
1873 } 1875 }
1874 } 1876 }
1875 1877
1876 1878
1877 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1879 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1878 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX; 1880 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : EBX;
1879 Register result = locs()->out().reg(); 1881 Register result = locs()->out().reg();
1880 1882
1881 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1883 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ?
1882 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1884 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1883 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1885 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1884 instance_call()->token_pos(), 1886 instance_call()->token_pos(),
1885 instance_call()->try_index(), 1887 instance_call()->try_index(),
1886 deopt_reason, 1888 deopt_reason,
1887 value); 1889 value);
1888 1890
1889 if (from() == kDouble) { 1891 if (from() == kDoubleCid) {
1890 Register temp = locs()->temp(0).reg(); 1892 Register temp = locs()->temp(0).reg();
1891 __ testl(value, Immediate(kSmiTagMask)); 1893 __ testl(value, Immediate(kSmiTagMask));
1892 __ j(ZERO, deopt); // Deoptimize if Smi. 1894 __ j(ZERO, deopt); // Deoptimize if Smi.
1893 __ CompareClassId(value, kDouble, temp); 1895 __ CompareClassId(value, kDoubleCid, temp);
1894 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1896 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1895 ASSERT(value == result); 1897 ASSERT(value == result);
1896 return; 1898 return;
1897 } 1899 }
1898 1900
1899 ASSERT(from() == kSmi); 1901 ASSERT(from() == kSmiCid);
1900 1902
1901 const Class& double_class = compiler->double_class(); 1903 const Class& double_class = compiler->double_class();
1902 const Code& stub = 1904 const Code& stub =
1903 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1905 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1904 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1906 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1905 1907
1906 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 1908 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
1907 compiler->GenerateCall(instance_call()->token_pos(), 1909 compiler->GenerateCall(instance_call()->token_pos(),
1908 instance_call()->try_index(), 1910 instance_call()->try_index(),
1909 &label, 1911 &label,
(...skipping 20 matching lines...) Expand all
1930 instance_call()->try_index(), 1932 instance_call()->try_index(),
1931 kDeoptPolymorphicInstanceCallTestFail); 1933 kDeoptPolymorphicInstanceCallTestFail);
1932 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1934 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1933 __ jmp(deopt); 1935 __ jmp(deopt);
1934 return; 1936 return;
1935 } 1937 }
1936 ASSERT(HasICData()); 1938 ASSERT(HasICData());
1937 ASSERT(ic_data()->num_args_tested() == 1); 1939 ASSERT(ic_data()->num_args_tested() == 1);
1938 Label handle_smi; 1940 Label handle_smi;
1939 Label* is_smi_label = 1941 Label* is_smi_label =
1940 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1942 ic_data()->GetReceiverClassIdAt(0) == kSmiCid ? &handle_smi : deopt;
1941 1943
1942 // Load receiver into EAX. 1944 // Load receiver into EAX.
1943 __ movl(EAX, 1945 __ movl(EAX,
1944 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1946 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1945 __ testl(EAX, Immediate(kSmiTagMask)); 1947 __ testl(EAX, Immediate(kSmiTagMask));
1946 __ j(ZERO, is_smi_label); 1948 __ j(ZERO, is_smi_label);
1947 Label done; 1949 Label done;
1948 __ LoadClassId(EDI, EAX); 1950 __ LoadClassId(EDI, EAX);
1949 compiler->EmitTestAndCall(*ic_data(), 1951 compiler->EmitTestAndCall(*ic_data(),
1950 EDI, // Class id register. 1952 EDI, // Class id register.
1951 instance_call()->ArgumentCount(), 1953 instance_call()->ArgumentCount(),
1952 instance_call()->argument_names(), 1954 instance_call()->argument_names(),
1953 deopt, 1955 deopt,
1954 (is_smi_label == &handle_smi) ? &done : NULL, 1956 (is_smi_label == &handle_smi) ? &done : NULL,
1955 instance_call()->deopt_id(), 1957 instance_call()->deopt_id(),
1956 instance_call()->token_pos(), 1958 instance_call()->token_pos(),
1957 instance_call()->try_index()); 1959 instance_call()->try_index());
1958 if (is_smi_label == &handle_smi) { 1960 if (is_smi_label == &handle_smi) {
1959 __ Bind(&handle_smi); 1961 __ Bind(&handle_smi);
1960 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1962 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid);
1961 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1963 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1962 compiler->GenerateStaticCall(instance_call()->deopt_id(), 1964 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1963 instance_call()->token_pos(), 1965 instance_call()->token_pos(),
1964 instance_call()->try_index(), 1966 instance_call()->try_index(),
1965 target, 1967 target,
1966 instance_call()->ArgumentCount(), 1968 instance_call()->ArgumentCount(),
1967 instance_call()->argument_names()); 1969 instance_call()->argument_names());
1968 } 1970 }
1969 __ Bind(&done); 1971 __ Bind(&done);
1970 } 1972 }
(...skipping 14 matching lines...) Expand all
1985 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { 1987 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) {
1986 const int kNumInputs = 2; 1988 const int kNumInputs = 2;
1987 const int kNumTemps = 0; 1989 const int kNumTemps = 0;
1988 LocationSummary* locs = 1990 LocationSummary* locs =
1989 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1991 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1990 locs->set_in(0, Location::RequiresRegister()); 1992 locs->set_in(0, Location::RequiresRegister());
1991 locs->set_in(1, Location::RequiresRegister()); 1993 locs->set_in(1, Location::RequiresRegister());
1992 return locs; 1994 return locs;
1993 } 1995 }
1994 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 1996 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
1995 if (ICDataWithBothClassIds(*ic_data(), kSmi) || 1997 if (ICDataWithBothClassIds(*ic_data(), kSmiCid) ||
1996 ICDataWithBothClassIds(*ic_data(), kDouble)) { 1998 ICDataWithBothClassIds(*ic_data(), kDoubleCid)) {
1997 const intptr_t kNumInputs = 2; 1999 const intptr_t kNumInputs = 2;
1998 const intptr_t kNumTemps = 1; 2000 const intptr_t kNumTemps = 1;
1999 LocationSummary* summary = 2001 LocationSummary* summary =
2000 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2002 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2001 summary->set_in(0, Location::RequiresRegister()); 2003 summary->set_in(0, Location::RequiresRegister());
2002 summary->set_in(1, Location::RequiresRegister()); 2004 summary->set_in(1, Location::RequiresRegister());
2003 summary->set_temp(0, Location::RequiresRegister()); 2005 summary->set_temp(0, Location::RequiresRegister());
2004 return summary; 2006 return summary;
2005 } 2007 }
2006 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2008 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
(...skipping 17 matching lines...) Expand all
2024 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { 2026 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) {
2025 Register left = locs()->in(0).reg(); 2027 Register left = locs()->in(0).reg();
2026 Register right = locs()->in(1).reg(); 2028 Register right = locs()->in(1).reg();
2027 __ cmpl(left, right); 2029 __ cmpl(left, right);
2028 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 2030 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
2029 EmitBranchOnCondition(compiler, cond); 2031 EmitBranchOnCondition(compiler, cond);
2030 return; 2032 return;
2031 } 2033 }
2032 // Relational or equality. 2034 // Relational or equality.
2033 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 2035 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
2034 if (ICDataWithBothClassIds(*ic_data(), kSmi)) { 2036 if (ICDataWithBothClassIds(*ic_data(), kSmiCid)) {
2035 EmitSmiComparisonOp(compiler, *locs(), kind(), this, 2037 EmitSmiComparisonOp(compiler, *locs(), kind(), this,
2036 deopt_id(), token_pos(), try_index()); 2038 deopt_id(), token_pos(), try_index());
2037 return; 2039 return;
2038 } 2040 }
2039 if (ICDataWithBothClassIds(*ic_data(), kDouble)) { 2041 if (ICDataWithBothClassIds(*ic_data(), kDoubleCid)) {
2040 EmitDoubleComparisonOp(compiler, *locs(), kind(), this, 2042 EmitDoubleComparisonOp(compiler, *locs(), kind(), this,
2041 deopt_id(), token_pos(), try_index()); 2043 deopt_id(), token_pos(), try_index());
2042 return; 2044 return;
2043 } 2045 }
2044 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. 2046 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
2045 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2047 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
2046 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2048 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(),
2047 deopt_id(), token_pos(), try_index()); 2049 deopt_id(), token_pos(), try_index());
2048 return; 2050 return;
2049 } 2051 }
(...skipping 20 matching lines...) Expand all
2070 ASSERT(locs()->out().reg() == EAX); 2072 ASSERT(locs()->out().reg() == EAX);
2071 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2073 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2072 EmitBranchOnCondition(compiler, branch_condition); 2074 EmitBranchOnCondition(compiler, branch_condition);
2073 } 2075 }
2074 2076
2075 } // namespace dart 2077 } // namespace dart
2076 2078
2077 #undef __ 2079 #undef __
2078 2080
2079 #endif // defined TARGET_ARCH_X64 2081 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language.h ('k') | vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698