Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_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 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 Register left = locs()->in(0).reg(); | 621 Register left = locs()->in(0).reg(); |
| 622 Register right = locs()->in(1).reg(); | 622 Register right = locs()->in(1).reg(); |
| 623 __ pushl(left); | 623 __ pushl(left); |
| 624 __ pushl(right); | 624 __ pushl(right); |
| 625 EmitEqualityAsInstanceCall(compiler, this); | 625 EmitEqualityAsInstanceCall(compiler, this); |
| 626 } | 626 } |
| 627 } | 627 } |
| 628 | 628 |
| 629 | 629 |
| 630 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 630 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 631 const intptr_t kNumInputs = 2; | |
| 631 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { | 632 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { |
| 632 const intptr_t kNumInputs = 2; | |
| 633 const intptr_t kNumTemps = 1; | 633 const intptr_t kNumTemps = 1; |
| 634 LocationSummary* summary = | 634 LocationSummary* summary = |
| 635 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 635 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 636 summary->set_in(0, Location::RequiresRegister()); | 636 summary->set_in(0, Location::RequiresRegister()); |
| 637 summary->set_in(1, Location::RequiresRegister()); | 637 summary->set_in(1, Location::RequiresRegister()); |
| 638 summary->set_out(Location::RequiresRegister()); | 638 summary->set_out(Location::RequiresRegister()); |
| 639 summary->set_temp(0, Location::RequiresRegister()); | 639 summary->set_temp(0, Location::RequiresRegister()); |
| 640 return summary; | 640 return summary; |
| 641 } | 641 } |
| 642 return MakeCallSummary(); | 642 const intptr_t kNumTemps = 0; |
| 643 LocationSummary* locs = | |
| 644 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | |
| 645 locs->set_in(0, Location::RegisterLocation(EAX)); | |
|
Kevin Millikin (Google)
2012/08/15 15:31:17
Maybe the code here should have a comment that the
Florian Schneider
2012/08/16 08:30:37
Done.
| |
| 646 locs->set_in(1, Location::RegisterLocation(ECX)); | |
| 647 locs->set_out(Location::RegisterLocation(EAX)); | |
| 648 return locs; | |
| 643 } | 649 } |
| 644 | 650 |
| 645 | 651 |
| 646 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 652 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 647 if (operands_class_id() == kSmiCid) { | 653 if (operands_class_id() == kSmiCid) { |
| 648 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, | 654 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, |
| 649 deopt_id(), token_pos(), try_index()); | 655 deopt_id(), token_pos(), try_index()); |
| 650 return; | 656 return; |
| 651 } | 657 } |
| 652 if (operands_class_id() == kDoubleCid) { | 658 if (operands_class_id() == kDoubleCid) { |
| 653 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, | 659 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, |
| 654 deopt_id(), token_pos(), try_index()); | 660 deopt_id(), token_pos(), try_index()); |
| 655 return; | 661 return; |
| 656 } | 662 } |
| 657 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 663 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 658 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 664 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 659 try_index(), | 665 try_index(), |
| 660 kDeoptRelationalOp); | 666 kDeoptRelationalOp); |
| 661 // Load receiver into EAX, class into EDI. | 667 // Push arguments for the call. |
| 668 // TODO(fschneider): Split this instruction into different types to avoid | |
| 669 // explicitly pushing arguments to the call here. | |
| 670 Register left = locs()->in(0).reg(); | |
| 671 Register right = locs()->in(1).reg(); | |
|
srdjan
2012/08/15 21:48:38
Left, right computation as well as pushing them c
Florian Schneider
2012/08/16 08:30:37
Done.
| |
| 672 __ pushl(left); | |
| 673 __ pushl(right); | |
| 674 | |
| 675 // Load class into EDI. | |
| 676 ASSERT((left != EDI) && (right != EDI)); | |
| 662 Label done; | 677 Label done; |
| 663 const intptr_t kNumArguments = 2; | 678 const intptr_t kNumArguments = 2; |
| 664 __ movl(EDI, Immediate(kSmiCid)); | 679 __ movl(EDI, Immediate(kSmiCid)); |
| 665 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); | 680 __ testl(left, Immediate(kSmiTagMask)); |
| 666 __ testl(EAX, Immediate(kSmiTagMask)); | |
| 667 __ j(ZERO, &done); | 681 __ j(ZERO, &done); |
| 668 __ LoadClassId(EDI, EAX); | 682 __ LoadClassId(EDI, left); |
| 669 __ Bind(&done); | 683 __ Bind(&done); |
| 670 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | 684 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), |
| 671 EDI, // Class id register. | 685 EDI, // Class id register. |
| 672 kNumArguments, | 686 kNumArguments, |
| 673 Array::Handle(), // No named arguments. | 687 Array::Handle(), // No named arguments. |
| 674 deopt, // Deoptimize target. | 688 deopt, // Deoptimize target. |
| 675 NULL, // Fallthrough when done. | 689 NULL, // Fallthrough when done. |
| 676 deopt_id(), | 690 deopt_id(), |
| 677 token_pos(), | 691 token_pos(), |
| 678 try_index(), | 692 try_index(), |
| 679 locs()->stack_bitmap()); | 693 locs()->stack_bitmap()); |
| 694 ASSERT(locs()->out().reg() == EAX); | |
| 680 return; | 695 return; |
| 681 } | 696 } |
| 697 // Push arguments for the call. | |
| 698 // TODO(fschneider): Split this instruction into different types to avoid | |
| 699 // explicitly pushing arguments to the call here. | |
| 700 Register left = locs()->in(0).reg(); | |
| 701 Register right = locs()->in(1).reg(); | |
| 702 __ pushl(left); | |
| 703 __ pushl(right); | |
| 704 | |
| 682 const String& function_name = | 705 const String& function_name = |
| 683 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 706 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 684 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 707 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 685 deopt_id(), | 708 deopt_id(), |
| 686 token_pos(), | 709 token_pos(), |
| 687 try_index()); | 710 try_index()); |
| 688 const intptr_t kNumArguments = 2; | 711 const intptr_t kNumArguments = 2; |
| 689 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 712 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 690 compiler->GenerateInstanceCall(deopt_id(), | 713 compiler->GenerateInstanceCall(deopt_id(), |
| 691 token_pos(), | 714 token_pos(), |
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2118 locs()->stack_bitmap()); | 2141 locs()->stack_bitmap()); |
| 2119 __ CompareObject(EAX, compiler->bool_true()); | 2142 __ CompareObject(EAX, compiler->bool_true()); |
| 2120 EmitBranchOnCondition(compiler, branch_condition); | 2143 EmitBranchOnCondition(compiler, branch_condition); |
| 2121 } | 2144 } |
| 2122 | 2145 |
| 2123 } // namespace dart | 2146 } // namespace dart |
| 2124 | 2147 |
| 2125 #undef __ | 2148 #undef __ |
| 2126 | 2149 |
| 2127 #endif // defined TARGET_ARCH_X64 | 2150 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |