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

Side by Side Diff: runtime/vm/intermediate_language_x64.cc

Issue 22825023: Uses an object pool on x64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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 | « runtime/vm/instructions_x64_test.cc ('k') | runtime/vm/intrinsifier_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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 89 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
90 ASSERT(fp_sp_dist <= 0); 90 ASSERT(fp_sp_dist <= 0);
91 __ movq(RDI, RSP); 91 __ movq(RDI, RSP);
92 __ subq(RDI, RBP); 92 __ subq(RDI, RBP);
93 __ cmpq(RDI, Immediate(fp_sp_dist)); 93 __ cmpq(RDI, Immediate(fp_sp_dist));
94 __ j(EQUAL, &done, Assembler::kNearJump); 94 __ j(EQUAL, &done, Assembler::kNearJump);
95 __ int3(); 95 __ int3();
96 __ Bind(&done); 96 __ Bind(&done);
97 } 97 }
98 #endif 98 #endif
99 __ LeaveFrame();
100 __ ret();
101 99
102 // Generate 8 bytes of NOPs so that the debugger can patch the 100 __ ReturnPatchable();
103 // return pattern with a call to the debug stub.
104 // Note that the nop(8) byte pattern is not recognized by the debugger.
105 __ nop(1);
106 __ nop(1);
107 __ nop(1);
108 __ nop(1);
109 __ nop(1);
110 __ nop(1);
111 __ nop(1);
112 __ nop(1);
113 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 101 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
114 Isolate::kNoDeoptId, 102 Isolate::kNoDeoptId,
115 token_pos()); 103 token_pos());
116 } 104 }
117 105
118 106
119 static Condition NegateCondition(Condition condition) { 107 static Condition NegateCondition(Condition condition) {
120 switch (condition) { 108 switch (condition) {
121 case EQUAL: return NOT_EQUAL; 109 case EQUAL: return NOT_EQUAL;
122 case NOT_EQUAL: return EQUAL; 110 case NOT_EQUAL: return EQUAL;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 return LocationSummary::Make(kNumInputs, 296 return LocationSummary::Make(kNumInputs,
309 Location::RequiresRegister(), 297 Location::RequiresRegister(),
310 LocationSummary::kNoCall); 298 LocationSummary::kNoCall);
311 } 299 }
312 300
313 301
314 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 302 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
315 // The register allocator drops constant definitions that have no uses. 303 // The register allocator drops constant definitions that have no uses.
316 if (!locs()->out().IsInvalid()) { 304 if (!locs()->out().IsInvalid()) {
317 Register result = locs()->out().reg(); 305 Register result = locs()->out().reg();
318 __ LoadObject(result, value()); 306 __ LoadObject(result, value(), PP);
319 } 307 }
320 } 308 }
321 309
322 310
323 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 311 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const {
324 const intptr_t kNumInputs = 3; 312 const intptr_t kNumInputs = 3;
325 const intptr_t kNumTemps = 0; 313 const intptr_t kNumTemps = 0;
326 LocationSummary* summary = 314 LocationSummary* summary =
327 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 315 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
328 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 316 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 const ICData& original_ic_data) { 446 const ICData& original_ic_data) {
459 if (!compiler->is_optimizing()) { 447 if (!compiler->is_optimizing()) {
460 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 448 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
461 deopt_id, 449 deopt_id,
462 token_pos); 450 token_pos);
463 } 451 }
464 const int kNumberOfArguments = 2; 452 const int kNumberOfArguments = 2;
465 const Array& kNoArgumentNames = Object::null_array(); 453 const Array& kNoArgumentNames = Object::null_array();
466 const int kNumArgumentsChecked = 2; 454 const int kNumArgumentsChecked = 2;
467 455
468 const Immediate& raw_null =
469 Immediate(reinterpret_cast<intptr_t>(Object::null()));
470 Label check_identity; 456 Label check_identity;
471 __ cmpq(Address(RSP, 0 * kWordSize), raw_null); 457 __ LoadObject(TMP, Object::Handle(), PP);
458 __ cmpq(Address(RSP, 0 * kWordSize), TMP);
472 __ j(EQUAL, &check_identity); 459 __ j(EQUAL, &check_identity);
473 __ cmpq(Address(RSP, 1 * kWordSize), raw_null); 460 __ cmpq(Address(RSP, 1 * kWordSize), TMP);
474 __ j(EQUAL, &check_identity); 461 __ j(EQUAL, &check_identity);
475 462
476 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); 463 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
477 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 464 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
478 ASSERT(!original_ic_data.IsNull()); 465 ASSERT(!original_ic_data.IsNull());
479 if (original_ic_data.NumberOfChecks() == 0) { 466 if (original_ic_data.NumberOfChecks() == 0) {
480 // IC call for reoptimization populates original ICData. 467 // IC call for reoptimization populates original ICData.
481 equality_ic_data = original_ic_data.raw(); 468 equality_ic_data = original_ic_data.raw();
482 } else { 469 } else {
483 // Megamorphic call. 470 // Megamorphic call.
(...skipping 20 matching lines...) Expand all
504 491
505 __ Bind(&check_identity); 492 __ Bind(&check_identity);
506 Label equality_done; 493 Label equality_done;
507 if (compiler->is_optimizing()) { 494 if (compiler->is_optimizing()) {
508 // No need to update IC data. 495 // No need to update IC data.
509 Label is_true; 496 Label is_true;
510 __ popq(RAX); 497 __ popq(RAX);
511 __ popq(RDX); 498 __ popq(RDX);
512 __ cmpq(RAX, RDX); 499 __ cmpq(RAX, RDX);
513 __ j(EQUAL, &is_true); 500 __ j(EQUAL, &is_true);
514 __ LoadObject(RAX, Bool::Get(kind != Token::kEQ)); 501 __ LoadObject(RAX, Bool::Get(kind != Token::kEQ), PP);
515 __ jmp(&equality_done); 502 __ jmp(&equality_done);
516 __ Bind(&is_true); 503 __ Bind(&is_true);
517 __ LoadObject(RAX, Bool::Get(kind == Token::kEQ)); 504 __ LoadObject(RAX, Bool::Get(kind == Token::kEQ), PP);
518 if (kind == Token::kNE) { 505 if (kind == Token::kNE) {
519 // Skip not-equal result conversion. 506 // Skip not-equal result conversion.
520 __ jmp(&equality_done); 507 __ jmp(&equality_done);
521 } 508 }
522 } else { 509 } else {
523 // Call stub, load IC data in register. The stub will update ICData if 510 // Call stub, load IC data in register. The stub will update ICData if
524 // necessary. 511 // necessary.
525 Register ic_data_reg = locs->temp(0).reg(); 512 Register ic_data_reg = locs->temp(0).reg();
526 ASSERT(ic_data_reg == RBX); // Stub depends on it. 513 ASSERT(ic_data_reg == RBX); // Stub depends on it.
527 __ LoadObject(ic_data_reg, equality_ic_data); 514 __ LoadObject(ic_data_reg, equality_ic_data, PP);
528 compiler->GenerateCall(token_pos, 515 compiler->GenerateCall(token_pos,
529 &StubCode::EqualityWithNullArgLabel(), 516 &StubCode::EqualityWithNullArgLabel(),
530 PcDescriptors::kRuntimeCall, 517 PcDescriptors::kRuntimeCall,
531 locs); 518 locs);
532 __ Drop(2); 519 __ Drop(2);
533 } 520 }
534 __ Bind(&check_ne); 521 __ Bind(&check_ne);
535 if (kind == Token::kNE) { 522 if (kind == Token::kNE) {
536 Label true_label, done; 523 Label true_label, done;
537 // Negate the condition: true label returns false and vice versa. 524 // Negate the condition: true label returns false and vice versa.
538 __ CompareObject(RAX, Bool::True()); 525 __ CompareObject(RAX, Bool::True());
539 __ j(EQUAL, &true_label, Assembler::kNearJump); 526 __ j(EQUAL, &true_label, Assembler::kNearJump);
540 __ LoadObject(RAX, Bool::True()); 527 __ LoadObject(RAX, Bool::True(), PP);
541 __ jmp(&done, Assembler::kNearJump); 528 __ jmp(&done, Assembler::kNearJump);
542 __ Bind(&true_label); 529 __ Bind(&true_label);
543 __ LoadObject(RAX, Bool::False()); 530 __ LoadObject(RAX, Bool::False(), PP);
544 __ Bind(&done); 531 __ Bind(&done);
545 } 532 }
546 __ Bind(&equality_done); 533 __ Bind(&equality_done);
547 } 534 }
548 535
549 536
550 static void LoadValueCid(FlowGraphCompiler* compiler, 537 static void LoadValueCid(FlowGraphCompiler* compiler,
551 Register value_cid_reg, 538 Register value_cid_reg,
552 Register value_reg, 539 Register value_reg,
553 Label* value_is_smi = NULL) { 540 Label* value_is_smi = NULL) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 // Object.== is same as ===. 590 // Object.== is same as ===.
604 __ Drop(2); 591 __ Drop(2);
605 __ cmpq(left, right); 592 __ cmpq(left, right);
606 if (branch != NULL) { 593 if (branch != NULL) {
607 branch->EmitBranchOnCondition(compiler, cond); 594 branch->EmitBranchOnCondition(compiler, cond);
608 } else { 595 } else {
609 // This case should be rare. 596 // This case should be rare.
610 Register result = locs->out().reg(); 597 Register result = locs->out().reg();
611 Label load_true; 598 Label load_true;
612 __ j(cond, &load_true, Assembler::kNearJump); 599 __ j(cond, &load_true, Assembler::kNearJump);
613 __ LoadObject(result, Bool::False()); 600 __ LoadObject(result, Bool::False(), PP);
614 __ jmp(&done); 601 __ jmp(&done);
615 __ Bind(&load_true); 602 __ Bind(&load_true);
616 __ LoadObject(result, Bool::True()); 603 __ LoadObject(result, Bool::True(), PP);
617 } 604 }
618 } else { 605 } else {
619 const int kNumberOfArguments = 2; 606 const int kNumberOfArguments = 2;
620 const Array& kNoArgumentNames = Object::null_array(); 607 const Array& kNoArgumentNames = Object::null_array();
621 compiler->GenerateStaticCall(deopt_id, 608 compiler->GenerateStaticCall(deopt_id,
622 token_pos, 609 token_pos,
623 target, 610 target,
624 kNumberOfArguments, 611 kNumberOfArguments,
625 kNoArgumentNames, 612 kNoArgumentNames,
626 locs); 613 locs);
627 if (branch == NULL) { 614 if (branch == NULL) {
628 if (kind == Token::kNE) { 615 if (kind == Token::kNE) {
629 Label false_label; 616 Label false_label;
630 __ CompareObject(RAX, Bool::True()); 617 __ CompareObject(RAX, Bool::True());
631 __ j(EQUAL, &false_label, Assembler::kNearJump); 618 __ j(EQUAL, &false_label, Assembler::kNearJump);
632 __ LoadObject(RAX, Bool::True()); 619 __ LoadObject(RAX, Bool::True(), PP);
633 __ jmp(&done); 620 __ jmp(&done);
634 __ Bind(&false_label); 621 __ Bind(&false_label);
635 __ LoadObject(RAX, Bool::False()); 622 __ LoadObject(RAX, Bool::False(), PP);
636 } 623 }
637 } else { 624 } else {
638 if (branch->is_checked()) { 625 if (branch->is_checked()) {
639 EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler); 626 EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
640 } 627 }
641 __ CompareObject(RAX, Bool::True()); 628 __ CompareObject(RAX, Bool::True());
642 branch->EmitBranchOnCondition(compiler, cond); 629 branch->EmitBranchOnCondition(compiler, cond);
643 } 630 }
644 } 631 }
645 if (i < len - 1) { 632 if (i < len - 1) {
(...skipping 13 matching lines...) Expand all
659 BranchInstr* branch, 646 BranchInstr* branch,
660 intptr_t deopt_id) { 647 intptr_t deopt_id) {
661 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 648 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
662 Register left = locs.in(0).reg(); 649 Register left = locs.in(0).reg();
663 Register right = locs.in(1).reg(); 650 Register right = locs.in(1).reg();
664 Register temp = locs.temp(0).reg(); 651 Register temp = locs.temp(0).reg();
665 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); 652 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
666 __ testq(left, Immediate(kSmiTagMask)); 653 __ testq(left, Immediate(kSmiTagMask));
667 __ j(ZERO, deopt); 654 __ j(ZERO, deopt);
668 // 'left' is not Smi. 655 // 'left' is not Smi.
669 const Immediate& raw_null = 656
670 Immediate(reinterpret_cast<intptr_t>(Object::null()));
671 Label identity_compare; 657 Label identity_compare;
672 __ cmpq(right, raw_null); 658 __ CompareObject(right, Object::Handle());
673 __ j(EQUAL, &identity_compare); 659 __ j(EQUAL, &identity_compare);
674 __ cmpq(left, raw_null); 660 __ CompareObject(left, Object::Handle());
675 __ j(EQUAL, &identity_compare); 661 __ j(EQUAL, &identity_compare);
676 662
677 __ LoadClassId(temp, left); 663 __ LoadClassId(temp, left);
678 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 664 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
679 const intptr_t len = ic_data.NumberOfChecks(); 665 const intptr_t len = ic_data.NumberOfChecks();
680 for (intptr_t i = 0; i < len; i++) { 666 for (intptr_t i = 0; i < len; i++) {
681 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 667 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
682 if (i == (len - 1)) { 668 if (i == (len - 1)) {
683 __ j(NOT_EQUAL, deopt); 669 __ j(NOT_EQUAL, deopt);
684 } else { 670 } else {
685 __ j(EQUAL, &identity_compare); 671 __ j(EQUAL, &identity_compare);
686 } 672 }
687 } 673 }
688 __ Bind(&identity_compare); 674 __ Bind(&identity_compare);
689 __ cmpq(left, right); 675 __ cmpq(left, right);
690 if (branch == NULL) { 676 if (branch == NULL) {
691 Label done, is_equal; 677 Label done, is_equal;
692 Register result = locs.out().reg(); 678 Register result = locs.out().reg();
693 __ j(EQUAL, &is_equal, Assembler::kNearJump); 679 __ j(EQUAL, &is_equal, Assembler::kNearJump);
694 // Not equal. 680 // Not equal.
695 __ LoadObject(result, Bool::Get(kind != Token::kEQ)); 681 __ LoadObject(result, Bool::Get(kind != Token::kEQ), PP);
696 __ jmp(&done, Assembler::kNearJump); 682 __ jmp(&done, Assembler::kNearJump);
697 __ Bind(&is_equal); 683 __ Bind(&is_equal);
698 __ LoadObject(result, Bool::Get(kind == Token::kEQ)); 684 __ LoadObject(result, Bool::Get(kind == Token::kEQ), PP);
699 __ Bind(&done); 685 __ Bind(&done);
700 } else { 686 } else {
701 Condition cond = TokenKindToSmiCondition(kind); 687 Condition cond = TokenKindToSmiCondition(kind);
702 branch->EmitBranchOnCondition(compiler, cond); 688 branch->EmitBranchOnCondition(compiler, cond);
703 } 689 }
704 } 690 }
705 691
706 692
707 // First test if receiver is NULL, in which case === is applied. 693 // First test if receiver is NULL, in which case === is applied.
708 // If type feedback was provided (lists of <class-id, target>), do a 694 // If type feedback was provided (lists of <class-id, target>), do a
709 // type by type check (either === or static call to the operator. 695 // type by type check (either === or static call to the operator.
710 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 696 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
711 LocationSummary* locs, 697 LocationSummary* locs,
712 Token::Kind kind, 698 Token::Kind kind,
713 BranchInstr* branch, 699 BranchInstr* branch,
714 const ICData& ic_data, 700 const ICData& ic_data,
715 intptr_t deopt_id, 701 intptr_t deopt_id,
716 intptr_t token_pos) { 702 intptr_t token_pos) {
717 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 703 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
718 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 704 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
719 Register left = locs->in(0).reg(); 705 Register left = locs->in(0).reg();
720 Register right = locs->in(1).reg(); 706 Register right = locs->in(1).reg();
721 const Immediate& raw_null = 707
722 Immediate(reinterpret_cast<intptr_t>(Object::null()));
723 Label done, identity_compare, non_null_compare; 708 Label done, identity_compare, non_null_compare;
724 __ cmpq(right, raw_null); 709 __ CompareObject(right, Object::Handle());
725 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 710 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
726 __ cmpq(left, raw_null); 711 __ CompareObject(left, Object::Handle());
727 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); 712 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
728 // Comparison with NULL is "===". 713 // Comparison with NULL is "===".
729 __ Bind(&identity_compare); 714 __ Bind(&identity_compare);
730 __ cmpq(left, right); 715 __ cmpq(left, right);
731 Condition cond = TokenKindToSmiCondition(kind); 716 Condition cond = TokenKindToSmiCondition(kind);
732 if (branch != NULL) { 717 if (branch != NULL) {
733 branch->EmitBranchOnCondition(compiler, cond); 718 branch->EmitBranchOnCondition(compiler, cond);
734 } else { 719 } else {
735 Register result = locs->out().reg(); 720 Register result = locs->out().reg();
736 Label load_true; 721 Label load_true;
737 __ j(cond, &load_true, Assembler::kNearJump); 722 __ j(cond, &load_true, Assembler::kNearJump);
738 __ LoadObject(result, Bool::False()); 723 __ LoadObject(result, Bool::False(), PP);
739 __ jmp(&done); 724 __ jmp(&done);
740 __ Bind(&load_true); 725 __ Bind(&load_true);
741 __ LoadObject(result, Bool::True()); 726 __ LoadObject(result, Bool::True(), PP);
742 } 727 }
743 __ jmp(&done); 728 __ jmp(&done);
744 __ Bind(&non_null_compare); // Receiver is not null. 729 __ Bind(&non_null_compare); // Receiver is not null.
745 __ pushq(left); 730 __ pushq(left);
746 __ pushq(right); 731 __ pushq(right);
747 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 732 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
748 deopt_id, token_pos); 733 deopt_id, token_pos);
749 __ Bind(&done); 734 __ Bind(&done);
750 } 735 }
751 736
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 } else { 774 } else {
790 __ cmpq(left.reg(), right.reg()); 775 __ cmpq(left.reg(), right.reg());
791 } 776 }
792 777
793 if (branch != NULL) { 778 if (branch != NULL) {
794 branch->EmitBranchOnCondition(compiler, true_condition); 779 branch->EmitBranchOnCondition(compiler, true_condition);
795 } else { 780 } else {
796 Register result = locs.out().reg(); 781 Register result = locs.out().reg();
797 Label done, is_true; 782 Label done, is_true;
798 __ j(true_condition, &is_true); 783 __ j(true_condition, &is_true);
799 __ LoadObject(result, Bool::False()); 784 __ LoadObject(result, Bool::False(), PP);
800 __ jmp(&done); 785 __ jmp(&done);
801 __ Bind(&is_true); 786 __ Bind(&is_true);
802 __ LoadObject(result, Bool::True()); 787 __ LoadObject(result, Bool::True(), PP);
803 __ Bind(&done); 788 __ Bind(&done);
804 } 789 }
805 } 790 }
806 791
807 792
808 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 793 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
809 switch (kind) { 794 switch (kind) {
810 case Token::kEQ: return EQUAL; 795 case Token::kEQ: return EQUAL;
811 case Token::kNE: return NOT_EQUAL; 796 case Token::kNE: return NOT_EQUAL;
812 case Token::kLT: return BELOW; 797 case Token::kLT: return BELOW;
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) { 1505 if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
1521 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) { 1506 if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
1522 // Currently we can't have different location summaries for optimized 1507 // Currently we can't have different location summaries for optimized
1523 // and non-optimized code. So instead we manually pick up a register 1508 // and non-optimized code. So instead we manually pick up a register
1524 // that is known to be free because we know how non-optimizing compiler 1509 // that is known to be free because we know how non-optimizing compiler
1525 // allocates registers. 1510 // allocates registers.
1526 field_reg = RBX; 1511 field_reg = RBX;
1527 ASSERT((field_reg != value_reg) && (field_reg != value_cid_reg)); 1512 ASSERT((field_reg != value_reg) && (field_reg != value_cid_reg));
1528 } 1513 }
1529 1514
1530 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); 1515 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP);
1531 1516
1532 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); 1517 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
1533 FieldAddress field_nullability_operand( 1518 FieldAddress field_nullability_operand(
1534 field_reg, Field::is_nullable_offset()); 1519 field_reg, Field::is_nullable_offset());
1535 FieldAddress field_length_operand( 1520 FieldAddress field_length_operand(
1536 field_reg, Field::guarded_list_length_offset()); 1521 field_reg, Field::guarded_list_length_offset());
1537 1522
1538 if (value_cid == kDynamicCid) { 1523 if (value_cid == kDynamicCid) {
1539 if (value_cid_reg == kNoRegister) { 1524 if (value_cid_reg == kNoRegister) {
1540 ASSERT(!compiler->is_optimizing()); 1525 ASSERT(!compiler->is_optimizing());
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 __ movq(field_length_operand, 1689 __ movq(field_length_operand,
1705 Immediate(Smi::RawValue(Field::kNoFixedLength))); 1690 Immediate(Smi::RawValue(Field::kNoFixedLength)));
1706 } 1691 }
1707 } 1692 }
1708 } 1693 }
1709 if (!ok_is_fall_through) { 1694 if (!ok_is_fall_through) {
1710 __ jmp(&ok); 1695 __ jmp(&ok);
1711 } 1696 }
1712 } else { 1697 } else {
1713 if (field_reg != kNoRegister) { 1698 if (field_reg != kNoRegister) {
1714 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); 1699 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP);
1715 } 1700 }
1716 1701
1717 if (value_cid == kDynamicCid) { 1702 if (value_cid == kDynamicCid) {
1718 // Field's guarded class id is fixed but value's class id is not known. 1703 // Field's guarded class id is fixed but value's class id is not known.
1719 __ testq(value_reg, Immediate(kSmiTagMask)); 1704 __ testq(value_reg, Immediate(kSmiTagMask));
1720 1705
1721 if (field_cid != kSmiCid) { 1706 if (field_cid != kSmiCid) {
1722 __ j(ZERO, fail); 1707 __ j(ZERO, fail);
1723 __ LoadClassId(value_cid_reg, value_reg); 1708 __ LoadClassId(value_cid_reg, value_reg);
1724 __ cmpq(value_cid_reg, Immediate(field_cid)); 1709 __ cmpq(value_cid_reg, Immediate(field_cid));
(...skipping 15 matching lines...) Expand all
1740 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1725 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1741 // Destroy value_cid_reg (safe because we are finished with it). 1726 // Destroy value_cid_reg (safe because we are finished with it).
1742 __ movq(value_cid_reg, 1727 __ movq(value_cid_reg,
1743 FieldAddress(value_reg, TypedData::length_offset())); 1728 FieldAddress(value_reg, TypedData::length_offset()));
1744 } 1729 }
1745 __ cmpq(value_cid_reg, field_length_operand); 1730 __ cmpq(value_cid_reg, field_length_operand);
1746 } 1731 }
1747 1732
1748 if (field().is_nullable() && (field_cid != kNullCid)) { 1733 if (field().is_nullable() && (field_cid != kNullCid)) {
1749 __ j(EQUAL, &ok); 1734 __ j(EQUAL, &ok);
1750 const Immediate& raw_null = 1735 __ CompareObject(value_reg, Object::Handle());
1751 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1752 __ cmpq(value_reg, raw_null);
1753 } 1736 }
1754 1737
1755 if (ok_is_fall_through) { 1738 if (ok_is_fall_through) {
1756 __ j(NOT_EQUAL, fail); 1739 __ j(NOT_EQUAL, fail);
1757 } else { 1740 } else {
1758 __ j(EQUAL, &ok); 1741 __ j(EQUAL, &ok);
1759 } 1742 }
1760 } else { 1743 } else {
1761 // Both value's and field's class id is known. 1744 // Both value's and field's class id is known.
1762 if ((value_cid != field_cid) && (value_cid != nullability)) { 1745 if ((value_cid != field_cid) && (value_cid != nullability)) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1867 : Location::RequiresRegister()); 1850 : Location::RequiresRegister());
1868 locs->set_temp(0, Location::RequiresRegister()); 1851 locs->set_temp(0, Location::RequiresRegister());
1869 return locs; 1852 return locs;
1870 } 1853 }
1871 1854
1872 1855
1873 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1856 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1874 Register value = locs()->in(0).reg(); 1857 Register value = locs()->in(0).reg();
1875 Register temp = locs()->temp(0).reg(); 1858 Register temp = locs()->temp(0).reg();
1876 1859
1877 __ LoadObject(temp, field()); 1860 __ LoadObject(temp, field(), PP);
1878 if (this->value()->NeedsStoreBuffer()) { 1861 if (this->value()->NeedsStoreBuffer()) {
1879 __ StoreIntoObject(temp, 1862 __ StoreIntoObject(temp,
1880 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); 1863 FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi());
1881 } else { 1864 } else {
1882 __ StoreIntoObjectNoBarrier( 1865 __ StoreIntoObjectNoBarrier(
1883 temp, FieldAddress(temp, Field::value_offset()), value); 1866 temp, FieldAddress(temp, Field::value_offset()), value);
1884 } 1867 }
1885 } 1868 }
1886 1869
1887 1870
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 // (or null). 2004 // (or null).
2022 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2005 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2023 !type_arguments().CanShareInstantiatorTypeArguments( 2006 !type_arguments().CanShareInstantiatorTypeArguments(
2024 instantiator_class())); 2007 instantiator_class()));
2025 // If the instantiator is null and if the type argument vector 2008 // If the instantiator is null and if the type argument vector
2026 // instantiated from null becomes a vector of dynamic, then use null as 2009 // instantiated from null becomes a vector of dynamic, then use null as
2027 // the type arguments. 2010 // the type arguments.
2028 Label type_arguments_instantiated; 2011 Label type_arguments_instantiated;
2029 const intptr_t len = type_arguments().Length(); 2012 const intptr_t len = type_arguments().Length();
2030 if (type_arguments().IsRawInstantiatedRaw(len)) { 2013 if (type_arguments().IsRawInstantiatedRaw(len)) {
2031 const Immediate& raw_null = 2014 __ CompareObject(instantiator_reg, Object::Handle());
2032 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2033 __ cmpq(instantiator_reg, raw_null);
2034 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2015 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2035 } 2016 }
2036 // Instantiate non-null type arguments. 2017 // Instantiate non-null type arguments.
2037 // A runtime call to instantiate the type arguments is required. 2018 // A runtime call to instantiate the type arguments is required.
2038 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2019 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2039 __ PushObject(type_arguments()); 2020 __ PushObject(type_arguments());
2040 __ pushq(instantiator_reg); // Push instantiator type arguments. 2021 __ pushq(instantiator_reg); // Push instantiator type arguments.
2041 compiler->GenerateCallRuntime(token_pos(), 2022 compiler->GenerateCallRuntime(token_pos(),
2042 deopt_id(), 2023 deopt_id(),
2043 kInstantiateTypeArgumentsRuntimeEntry, 2024 kInstantiateTypeArgumentsRuntimeEntry,
(...skipping 27 matching lines...) Expand all
2071 // instantiator_reg is the instantiator type argument vector, i.e. an 2052 // instantiator_reg is the instantiator type argument vector, i.e. an
2072 // AbstractTypeArguments object (or null). 2053 // AbstractTypeArguments object (or null).
2073 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2054 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2074 !type_arguments().CanShareInstantiatorTypeArguments( 2055 !type_arguments().CanShareInstantiatorTypeArguments(
2075 instantiator_class())); 2056 instantiator_class()));
2076 // If the instantiator is null and if the type argument vector 2057 // If the instantiator is null and if the type argument vector
2077 // instantiated from null becomes a vector of dynamic, then use null as 2058 // instantiated from null becomes a vector of dynamic, then use null as
2078 // the type arguments. 2059 // the type arguments.
2079 Label type_arguments_instantiated; 2060 Label type_arguments_instantiated;
2080 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 2061 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
2081 const Immediate& raw_null = 2062
2082 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2063 __ CompareObject(instantiator_reg, Object::Handle());
2083 __ cmpq(instantiator_reg, raw_null);
2084 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2064 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2085 // Instantiate non-null type arguments. 2065 // Instantiate non-null type arguments.
2086 // In the non-factory case, we rely on the allocation stub to 2066 // In the non-factory case, we rely on the allocation stub to
2087 // instantiate the type arguments. 2067 // instantiate the type arguments.
2088 __ LoadObject(result_reg, type_arguments()); 2068 __ LoadObject(result_reg, type_arguments(), PP);
2089 // result_reg: uninstantiated type arguments. 2069 // result_reg: uninstantiated type arguments.
2090 2070
2091 __ Bind(&type_arguments_instantiated); 2071 __ Bind(&type_arguments_instantiated);
2092 // result_reg: uninstantiated or instantiated type arguments. 2072 // result_reg: uninstantiated or instantiated type arguments.
2093 } 2073 }
2094 2074
2095 2075
2096 LocationSummary* 2076 LocationSummary*
2097 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 2077 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
2098 const intptr_t kNumInputs = 1; 2078 const intptr_t kNumInputs = 1;
(...skipping 14 matching lines...) Expand all
2113 // instantiator_reg is the instantiator AbstractTypeArguments object 2093 // instantiator_reg is the instantiator AbstractTypeArguments object
2114 // (or null). 2094 // (or null).
2115 ASSERT(!type_arguments().IsUninstantiatedIdentity() && 2095 ASSERT(!type_arguments().IsUninstantiatedIdentity() &&
2116 !type_arguments().CanShareInstantiatorTypeArguments( 2096 !type_arguments().CanShareInstantiatorTypeArguments(
2117 instantiator_class())); 2097 instantiator_class()));
2118 2098
2119 // If the instantiator is null and if the type argument vector 2099 // If the instantiator is null and if the type argument vector
2120 // instantiated from null becomes a vector of dynamic, then use null as 2100 // instantiated from null becomes a vector of dynamic, then use null as
2121 // the type arguments and do not pass the instantiator. 2101 // the type arguments and do not pass the instantiator.
2122 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); 2102 ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
2123 const Immediate& raw_null = 2103
2124 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2125 Label instantiator_not_null; 2104 Label instantiator_not_null;
2126 __ cmpq(instantiator_reg, raw_null); 2105 __ CompareObject(instantiator_reg, Object::Handle());
2127 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); 2106 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
2128 // Null was used in VisitExtractConstructorTypeArguments as the 2107 // Null was used in VisitExtractConstructorTypeArguments as the
2129 // instantiated type arguments, no proper instantiator needed. 2108 // instantiated type arguments, no proper instantiator needed.
2130 __ movq(instantiator_reg, 2109 __ movq(instantiator_reg,
2131 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 2110 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2132 __ Bind(&instantiator_not_null); 2111 __ Bind(&instantiator_not_null);
2133 // instantiator_reg: instantiator or kNoInstantiator. 2112 // instantiator_reg: instantiator or kNoInstantiator.
2134 } 2113 }
2135 2114
2136 2115
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 } 2171 }
2193 2172
2194 2173
2195 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2174 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2196 __ Bind(compiler->GetJumpLabel(this)); 2175 __ Bind(compiler->GetJumpLabel(this));
2197 compiler->AddExceptionHandler(catch_try_index(), 2176 compiler->AddExceptionHandler(catch_try_index(),
2198 try_index(), 2177 try_index(),
2199 compiler->assembler()->CodeSize(), 2178 compiler->assembler()->CodeSize(),
2200 catch_handler_types_, 2179 catch_handler_types_,
2201 needs_stacktrace()); 2180 needs_stacktrace());
2181
2182 // Restore the pool pointer.
2183 __ LoadPoolPointer(PP);
2184
2202 if (HasParallelMove()) { 2185 if (HasParallelMove()) {
2203 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 2186 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
2204 } 2187 }
2205 2188
2206 // Restore RSP from RBP as we are coming from a throw and the code for 2189 // Restore RSP from RBP as we are coming from a throw and the code for
2207 // popping arguments has not been run. 2190 // popping arguments has not been run.
2208 const intptr_t fp_sp_dist = 2191 const intptr_t fp_sp_dist =
2209 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; 2192 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
2210 ASSERT(fp_sp_dist <= 0); 2193 ASSERT(fp_sp_dist <= 0);
2211 __ leaq(RSP, Address(RBP, fp_sp_dist)); 2194 __ leaq(RSP, Address(RBP, fp_sp_dist));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 2255
2273 Register temp = locs()->temp(0).reg(); 2256 Register temp = locs()->temp(0).reg();
2274 // Generate stack overflow check. 2257 // Generate stack overflow check.
2275 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); 2258 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
2276 __ cmpq(RSP, Address(temp, 0)); 2259 __ cmpq(RSP, Address(temp, 0));
2277 __ j(BELOW_EQUAL, slow_path->entry_label()); 2260 __ j(BELOW_EQUAL, slow_path->entry_label());
2278 if (compiler->CanOSRFunction() && in_loop()) { 2261 if (compiler->CanOSRFunction() && in_loop()) {
2279 // In unoptimized code check the usage counter to trigger OSR at loop 2262 // In unoptimized code check the usage counter to trigger OSR at loop
2280 // stack checks. Use progressively higher thresholds for more deeply 2263 // stack checks. Use progressively higher thresholds for more deeply
2281 // nested loops to attempt to hit outer loops with OSR when possible. 2264 // nested loops to attempt to hit outer loops with OSR when possible.
2282 __ LoadObject(temp, compiler->parsed_function().function()); 2265 __ LoadObject(temp, compiler->parsed_function().function(), PP);
2283 intptr_t threshold = 2266 intptr_t threshold =
2284 FLAG_optimization_counter_threshold * (loop_depth() + 1); 2267 FLAG_optimization_counter_threshold * (loop_depth() + 1);
2285 __ cmpq(FieldAddress(temp, Function::usage_counter_offset()), 2268 __ cmpq(FieldAddress(temp, Function::usage_counter_offset()),
2286 Immediate(threshold)); 2269 Immediate(threshold));
2287 __ j(GREATER_EQUAL, slow_path->entry_label()); 2270 __ j(GREATER_EQUAL, slow_path->entry_label());
2288 } 2271 }
2289 __ Bind(slow_path->exit_label()); 2272 __ Bind(slow_path->exit_label());
2290 } 2273 }
2291 2274
2292 2275
(...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after
3719 __ movl(result, Address(RSP, 8)); 3702 __ movl(result, Address(RSP, 8));
3720 break; 3703 break;
3721 case MethodRecognizer::kUint32x4GetFlagW: 3704 case MethodRecognizer::kUint32x4GetFlagW:
3722 __ movl(result, Address(RSP, 12)); 3705 __ movl(result, Address(RSP, 12));
3723 break; 3706 break;
3724 default: UNREACHABLE(); 3707 default: UNREACHABLE();
3725 } 3708 }
3726 __ addq(RSP, Immediate(16)); 3709 __ addq(RSP, Immediate(16));
3727 __ testl(result, result); 3710 __ testl(result, result);
3728 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump); 3711 __ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
3729 __ LoadObject(result, Bool::False()); 3712 __ LoadObject(result, Bool::False(), PP);
3730 __ jmp(&done); 3713 __ jmp(&done);
3731 __ Bind(&non_zero); 3714 __ Bind(&non_zero);
3732 __ LoadObject(result, Bool::True()); 3715 __ LoadObject(result, Bool::True(), PP);
3733 __ Bind(&done); 3716 __ Bind(&done);
3734 } 3717 }
3735 3718
3736 3719
3737 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { 3720 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const {
3738 const intptr_t kNumInputs = 3; 3721 const intptr_t kNumInputs = 3;
3739 const intptr_t kNumTemps = 1; 3722 const intptr_t kNumTemps = 1;
3740 LocationSummary* summary = 3723 LocationSummary* summary =
3741 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3724 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3742 summary->set_in(0, Location::RequiresFpuRegister()); 3725 summary->set_in(0, Location::RequiresFpuRegister());
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
4240 // return double.NAN; 4223 // return double.NAN;
4241 // } 4224 // }
4242 XmmRegister base = locs()->in(0).fpu_reg(); 4225 XmmRegister base = locs()->in(0).fpu_reg();
4243 XmmRegister exp = locs()->in(1).fpu_reg(); 4226 XmmRegister exp = locs()->in(1).fpu_reg();
4244 XmmRegister result = locs()->out().fpu_reg(); 4227 XmmRegister result = locs()->out().fpu_reg();
4245 Register temp = locs()->temp(0).reg(); 4228 Register temp = locs()->temp(0).reg();
4246 XmmRegister zero_temp = locs()->temp(1).fpu_reg(); 4229 XmmRegister zero_temp = locs()->temp(1).fpu_reg();
4247 4230
4248 Label check_base_is_one; 4231 Label check_base_is_one;
4249 // Check if exponent is 0.0 -> return 1.0; 4232 // Check if exponent is 0.0 -> return 1.0;
4250 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); 4233 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP);
4251 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4234 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4252 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); 4235 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP);
4253 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4236 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4254 // 'result' contains 1.0. 4237 // 'result' contains 1.0.
4255 __ comisd(exp, zero_temp); 4238 __ comisd(exp, zero_temp);
4256 __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump); // NaN. 4239 __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump); // NaN.
4257 __ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0. 4240 __ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0.
4258 4241
4259 Label base_is_nan; 4242 Label base_is_nan;
4260 __ Bind(&check_base_is_one); 4243 __ Bind(&check_base_is_one);
4261 // Checks if base == 1.0. 4244 // Checks if base == 1.0.
4262 __ comisd(base, result); 4245 __ comisd(base, result);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4340 summary->AddTemp(Location::RequiresRegister()); 4323 summary->AddTemp(Location::RequiresRegister());
4341 } 4324 }
4342 return summary; 4325 return summary;
4343 } 4326 }
4344 4327
4345 4328
4346 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4329 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4347 if (IsNullCheck()) { 4330 if (IsNullCheck()) {
4348 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4331 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4349 kDeoptCheckClass); 4332 kDeoptCheckClass);
4350 const Immediate& raw_null = 4333 __ CompareObject(locs()->in(0).reg(),
4351 Immediate(reinterpret_cast<intptr_t>(Object::null())); 4334 Object::Handle());
4352 __ cmpq(locs()->in(0).reg(), raw_null);
4353 __ j(EQUAL, deopt); 4335 __ j(EQUAL, deopt);
4354 return; 4336 return;
4355 } 4337 }
4356 4338
4357 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || 4339 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
4358 (unary_checks().NumberOfChecks() > 1)); 4340 (unary_checks().NumberOfChecks() > 1));
4359 Register value = locs()->in(0).reg(); 4341 Register value = locs()->in(0).reg();
4360 Register temp = locs()->temp(0).reg(); 4342 Register temp = locs()->temp(0).reg();
4361 Label* deopt = compiler->AddDeoptStub(deopt_id(), 4343 Label* deopt = compiler->AddDeoptStub(deopt_id(),
4362 kDeoptCheckClass); 4344 kDeoptCheckClass);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 __ Bind(compiler->GetJumpLabel(this)); 4534 __ Bind(compiler->GetJumpLabel(this));
4553 if (!compiler->is_optimizing()) { 4535 if (!compiler->is_optimizing()) {
4554 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4536 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4555 deopt_id_, 4537 deopt_id_,
4556 Scanner::kDummyTokenIndex); 4538 Scanner::kDummyTokenIndex);
4557 // Add an edge counter. 4539 // Add an edge counter.
4558 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); 4540 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
4559 counter.SetAt(0, Smi::Handle(Smi::New(0))); 4541 counter.SetAt(0, Smi::Handle(Smi::New(0)));
4560 Label done; 4542 Label done;
4561 __ Comment("Edge counter"); 4543 __ Comment("Edge counter");
4562 __ LoadObject(RAX, counter); 4544 __ LoadObject(RAX, counter, PP);
4563 __ addq(FieldAddress(RAX, Array::element_offset(0)), 4545 __ addq(FieldAddress(RAX, Array::element_offset(0)),
4564 Immediate(Smi::RawValue(1))); 4546 Immediate(Smi::RawValue(1)));
4565 __ j(NO_OVERFLOW, &done); 4547 __ j(NO_OVERFLOW, &done);
4566 __ movq(FieldAddress(RAX, Array::element_offset(0)), 4548 __ movq(FieldAddress(RAX, Array::element_offset(0)),
4567 Immediate(Smi::RawValue(Smi::kMaxValue))); 4549 Immediate(Smi::RawValue(Smi::kMaxValue)));
4568 __ Bind(&done); 4550 __ Bind(&done);
4569 } 4551 }
4570 if (HasParallelMove()) { 4552 if (HasParallelMove()) {
4571 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4553 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4572 } 4554 }
(...skipping 10 matching lines...) Expand all
4583 // Add deoptimization descriptor for deoptimizing instructions that may 4565 // Add deoptimization descriptor for deoptimizing instructions that may
4584 // be inserted before this instruction. 4566 // be inserted before this instruction.
4585 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 4567 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
4586 GetDeoptId(), 4568 GetDeoptId(),
4587 0); // No token position. 4569 0); // No token position.
4588 // Add an edge counter. 4570 // Add an edge counter.
4589 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); 4571 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
4590 counter.SetAt(0, Smi::Handle(Smi::New(0))); 4572 counter.SetAt(0, Smi::Handle(Smi::New(0)));
4591 Label done; 4573 Label done;
4592 __ Comment("Edge counter"); 4574 __ Comment("Edge counter");
4593 __ LoadObject(RAX, counter); 4575 __ LoadObject(RAX, counter, PP);
4594 __ addq(FieldAddress(RAX, Array::element_offset(0)), 4576 __ addq(FieldAddress(RAX, Array::element_offset(0)),
4595 Immediate(Smi::RawValue(1))); 4577 Immediate(Smi::RawValue(1)));
4596 __ j(NO_OVERFLOW, &done); 4578 __ j(NO_OVERFLOW, &done);
4597 __ movq(FieldAddress(RAX, Array::element_offset(0)), 4579 __ movq(FieldAddress(RAX, Array::element_offset(0)),
4598 Immediate(Smi::RawValue(Smi::kMaxValue))); 4580 Immediate(Smi::RawValue(Smi::kMaxValue)));
4599 __ Bind(&done); 4581 __ Bind(&done);
4600 } 4582 }
4601 if (HasParallelMove()) { 4583 if (HasParallelMove()) {
4602 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 4584 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
4603 } 4585 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 // Special code for numbers (compare values instead of references.) 4648 // Special code for numbers (compare values instead of references.)
4667 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4649 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4668 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4650 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4669 Location left = locs()->in(0); 4651 Location left = locs()->in(0);
4670 Location right = locs()->in(1); 4652 Location right = locs()->in(1);
4671 if (left.IsConstant() && right.IsConstant()) { 4653 if (left.IsConstant() && right.IsConstant()) {
4672 // TODO(vegorov): should be eliminated earlier by constant propagation. 4654 // TODO(vegorov): should be eliminated earlier by constant propagation.
4673 const bool result = (kind() == Token::kEQ_STRICT) ? 4655 const bool result = (kind() == Token::kEQ_STRICT) ?
4674 left.constant().raw() == right.constant().raw() : 4656 left.constant().raw() == right.constant().raw() :
4675 left.constant().raw() != right.constant().raw(); 4657 left.constant().raw() != right.constant().raw();
4676 __ LoadObject(locs()->out().reg(), Bool::Get(result)); 4658 __ LoadObject(locs()->out().reg(), Bool::Get(result), PP);
4677 return; 4659 return;
4678 } 4660 }
4679 if (left.IsConstant()) { 4661 if (left.IsConstant()) {
4680 compiler->EmitEqualityRegConstCompare(right.reg(), 4662 compiler->EmitEqualityRegConstCompare(right.reg(),
4681 left.constant(), 4663 left.constant(),
4682 needs_number_check(), 4664 needs_number_check(),
4683 token_pos()); 4665 token_pos());
4684 } else if (right.IsConstant()) { 4666 } else if (right.IsConstant()) {
4685 compiler->EmitEqualityRegConstCompare(left.reg(), 4667 compiler->EmitEqualityRegConstCompare(left.reg(),
4686 right.constant(), 4668 right.constant(),
4687 needs_number_check(), 4669 needs_number_check(),
4688 token_pos()); 4670 token_pos());
4689 } else { 4671 } else {
4690 compiler->EmitEqualityRegRegCompare(left.reg(), 4672 compiler->EmitEqualityRegRegCompare(left.reg(),
4691 right.reg(), 4673 right.reg(),
4692 needs_number_check(), 4674 needs_number_check(),
4693 token_pos()); 4675 token_pos());
4694 } 4676 }
4695 4677
4696 Register result = locs()->out().reg(); 4678 Register result = locs()->out().reg();
4697 Label load_true, done; 4679 Label load_true, done;
4698 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 4680 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
4699 __ j(true_condition, &load_true, Assembler::kNearJump); 4681 __ j(true_condition, &load_true, Assembler::kNearJump);
4700 __ LoadObject(result, Bool::False()); 4682 __ LoadObject(result, Bool::False(), PP);
4701 __ jmp(&done, Assembler::kNearJump); 4683 __ jmp(&done, Assembler::kNearJump);
4702 __ Bind(&load_true); 4684 __ Bind(&load_true);
4703 __ LoadObject(result, Bool::True()); 4685 __ LoadObject(result, Bool::True(), PP);
4704 __ Bind(&done); 4686 __ Bind(&done);
4705 } 4687 }
4706 4688
4707 4689
4708 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 4690 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
4709 BranchInstr* branch) { 4691 BranchInstr* branch) {
4710 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 4692 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
4711 Location left = locs()->in(0); 4693 Location left = locs()->in(0);
4712 Location right = locs()->in(1); 4694 Location right = locs()->in(1);
4713 if (left.IsConstant() && right.IsConstant()) { 4695 if (left.IsConstant() && right.IsConstant()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4752 4734
4753 4735
4754 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4736 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4755 // The arguments to the stub include the closure, as does the arguments 4737 // The arguments to the stub include the closure, as does the arguments
4756 // descriptor. 4738 // descriptor.
4757 Register temp_reg = locs()->temp(0).reg(); 4739 Register temp_reg = locs()->temp(0).reg();
4758 int argument_count = ArgumentCount(); 4740 int argument_count = ArgumentCount();
4759 const Array& arguments_descriptor = 4741 const Array& arguments_descriptor =
4760 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 4742 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
4761 argument_names())); 4743 argument_names()));
4762 __ LoadObject(temp_reg, arguments_descriptor); 4744 __ LoadObject(temp_reg, arguments_descriptor, PP);
4763 ASSERT(temp_reg == R10); 4745 ASSERT(temp_reg == R10);
4764 compiler->GenerateDartCall(deopt_id(), 4746 compiler->GenerateDartCall(deopt_id(),
4765 token_pos(), 4747 token_pos(),
4766 &StubCode::CallClosureFunctionLabel(), 4748 &StubCode::CallClosureFunctionLabel(),
4767 PcDescriptors::kClosureCall, 4749 PcDescriptors::kClosureCall,
4768 locs()); 4750 locs());
4769 __ Drop(argument_count); 4751 __ Drop(argument_count);
4770 } 4752 }
4771 4753
4772 4754
4773 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 4755 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
4774 return LocationSummary::Make(1, 4756 return LocationSummary::Make(1,
4775 Location::RequiresRegister(), 4757 Location::RequiresRegister(),
4776 LocationSummary::kNoCall); 4758 LocationSummary::kNoCall);
4777 } 4759 }
4778 4760
4779 4761
4780 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4762 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4781 Register value = locs()->in(0).reg(); 4763 Register value = locs()->in(0).reg();
4782 Register result = locs()->out().reg(); 4764 Register result = locs()->out().reg();
4783 4765
4784 Label done; 4766 Label done;
4785 __ LoadObject(result, Bool::True()); 4767 __ LoadObject(result, Bool::True(), PP);
4786 __ CompareRegisters(result, value); 4768 __ CompareRegisters(result, value);
4787 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 4769 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
4788 __ LoadObject(result, Bool::False()); 4770 __ LoadObject(result, Bool::False(), PP);
4789 __ Bind(&done); 4771 __ Bind(&done);
4790 } 4772 }
4791 4773
4792 4774
4793 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const { 4775 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const {
4794 const intptr_t kNumInputs = 2; 4776 const intptr_t kNumInputs = 2;
4795 const intptr_t kNumTemps = 0; 4777 const intptr_t kNumTemps = 0;
4796 LocationSummary* locs = 4778 LocationSummary* locs =
4797 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4779 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4798 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister() 4780 locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4848 PcDescriptors::kOther, 4830 PcDescriptors::kOther,
4849 locs()); 4831 locs());
4850 __ Drop(2); // Discard type arguments and receiver. 4832 __ Drop(2); // Discard type arguments and receiver.
4851 } 4833 }
4852 4834
4853 } // namespace dart 4835 } // namespace dart
4854 4836
4855 #undef __ 4837 #undef __
4856 4838
4857 #endif // defined TARGET_ARCH_X64 4839 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/instructions_x64_test.cc ('k') | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698