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

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

Issue 10572050: Removing more IC calls in optimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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/flow_graph_optimizer.cc ('k') | runtime/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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 299 }
300 300
301 301
302 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 302 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
303 EqualityCompareComp* comp, 303 EqualityCompareComp* comp,
304 Register left, 304 Register left,
305 Register right) { 305 Register right) {
306 ASSERT(comp->HasICData()); 306 ASSERT(comp->HasICData());
307 const ICData& ic_data = *comp->ic_data(); 307 const ICData& ic_data = *comp->ic_data();
308 ASSERT(ic_data.NumberOfChecks() > 0); 308 ASSERT(ic_data.NumberOfChecks() > 0);
309 ASSERT(ic_data.num_args_tested() == 1);
309 Label* deopt = compiler->AddDeoptStub(comp->cid(), 310 Label* deopt = compiler->AddDeoptStub(comp->cid(),
310 comp->token_index(), 311 comp->token_index(),
311 comp->try_index(), 312 comp->try_index(),
312 kDeoptEquality); 313 kDeoptEquality);
313 __ testl(left, Immediate(kSmiTagMask)); 314 __ testl(left, Immediate(kSmiTagMask));
314 Register temp = comp->locs()->temp(0).reg(); 315 Register temp = comp->locs()->temp(0).reg();
315 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 316 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
316 Label done, load_class_id; 317 Label done, load_class_id;
317 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 318 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
318 __ movl(temp, Immediate(kSmi)); 319 __ movl(temp, Immediate(kSmi));
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 locs->set_temp(0, Location::RequiresRegister()); 631 locs->set_temp(0, Location::RequiresRegister());
631 locs->set_out(Location::RequiresRegister()); 632 locs->set_out(Location::RequiresRegister());
632 return locs; 633 return locs;
633 } else { 634 } else {
634 ASSERT(receiver_type() == kIllegalObjectKind); 635 ASSERT(receiver_type() == kIllegalObjectKind);
635 return MakeCallSummary(); 636 return MakeCallSummary();
636 } 637 }
637 } 638 }
638 639
639 640
641 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
642 LoadIndexedComp* comp) {
643 Label* deopt = compiler->AddDeoptStub(comp->cid(),
644 comp->token_index(),
645 comp->try_index(),
646 kDeoptLoadIndexedPolymorphic);
647 if (comp->ic_data()->NumberOfChecks() == 0) {
648 __ jmp(deopt);
649 return;
650 }
651 ASSERT(comp->HasICData());
652 const ICData& ic_data = *comp->ic_data();
653 ASSERT(ic_data.num_args_tested() == 1);
654 // No indexed access on Smi.
655 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
656 // Load receiver into EAX.
657 const intptr_t kNumArguments = 2;
658 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
659 __ testl(EAX, Immediate(kSmiTagMask));
660 __ j(ZERO, deopt);
661 Label done;
662 __ LoadClassId(EDI, EAX);
663 compiler->EmitTestAndCall(ic_data,
664 EDI, // Class id register.
665 kNumArguments,
666 Array::Handle(), // No named arguments.
667 deopt, &done, // Labels.
668 comp->cid(),
669 comp->token_index(),
670 comp->try_index());
671 __ Bind(&done);
672 }
673
640 674
641 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 675 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
642 if (receiver_type() == kIllegalObjectKind) { 676 if (receiver_type() == kIllegalObjectKind) {
643 compiler->EmitLoadIndexedGeneric(this); 677 if (HasICData()) {
678 EmitLoadIndexedPolymorphic(compiler, this);
679 } else {
680 compiler->EmitLoadIndexedGeneric(this);
681 }
644 ASSERT(locs()->out().reg() == EAX); 682 ASSERT(locs()->out().reg() == EAX);
645 return; 683 return;
646 } 684 }
647 Register receiver = locs()->in(0).reg(); 685 Register receiver = locs()->in(0).reg();
648 Register index = locs()->in(1).reg(); 686 Register index = locs()->in(1).reg();
649 Register result = locs()->out().reg(); 687 Register result = locs()->out().reg();
650 Register temp = locs()->temp(0).reg(); 688 Register temp = locs()->temp(0).reg();
651 689
652 const Class& receiver_class = 690 const Class& receiver_class =
653 Class::ZoneHandle(Isolate::Current()->class_table()->At( 691 Class::ZoneHandle(Isolate::Current()->class_table()->At(
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 locs->set_temp(0, Location::RequiresRegister()); 750 locs->set_temp(0, Location::RequiresRegister());
713 locs->set_out(Location::NoLocation()); 751 locs->set_out(Location::NoLocation());
714 return locs; 752 return locs;
715 } else { 753 } else {
716 ASSERT(receiver_type() == kIllegalObjectKind); 754 ASSERT(receiver_type() == kIllegalObjectKind);
717 return MakeCallSummary(); 755 return MakeCallSummary();
718 } 756 }
719 } 757 }
720 758
721 759
722
723 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, 760 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
724 StoreIndexedComp* comp) { 761 StoreIndexedComp* comp) {
725 const String& function_name = 762 const String& function_name =
726 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 763 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
727 764
728 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 765 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
729 comp->cid(), 766 comp->cid(),
730 comp->token_index(), 767 comp->token_index(),
731 comp->try_index()); 768 comp->try_index());
732 769
733 const intptr_t kNumArguments = 3; 770 const intptr_t kNumArguments = 3;
734 const intptr_t kNumArgsChecked = 1; // Type-feedback. 771 const intptr_t kNumArgsChecked = 1; // Type-feedback.
735 compiler->GenerateInstanceCall(comp->cid(), 772 compiler->GenerateInstanceCall(comp->cid(),
736 comp->token_index(), 773 comp->token_index(),
737 comp->try_index(), 774 comp->try_index(),
738 function_name, 775 function_name,
739 kNumArguments, 776 kNumArguments,
740 Array::ZoneHandle(), // No optional arguments. 777 Array::ZoneHandle(), // No named args.
741 kNumArgsChecked); 778 kNumArgsChecked);
742 } 779 }
743 780
744 781
782 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
783 StoreIndexedComp* comp) {
784 Label* deopt = compiler->AddDeoptStub(comp->cid(),
785 comp->token_index(),
786 comp->try_index(),
787 kDeoptStoreIndexedPolymorphic);
788 if (comp->ic_data()->NumberOfChecks() == 0) {
789 __ jmp(deopt);
790 return;
791 }
792 ASSERT(comp->HasICData());
793 const ICData& ic_data = *comp->ic_data();
794 ASSERT(ic_data.num_args_tested() == 1);
795 // No indexed access on Smi.
796 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
797 // Load receiver into EAX.
798 const intptr_t kNumArguments = 3;
799 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
800 __ testl(EAX, Immediate(kSmiTagMask));
801 __ j(ZERO, deopt);
802 Label done;
803 __ LoadClassId(EDI, EAX);
804 compiler->EmitTestAndCall(ic_data,
805 EDI, // Class id register.
806 kNumArguments,
807 Array::Handle(), // No named arguments.
808 deopt, &done, // Labels.
809 comp->cid(),
810 comp->token_index(),
811 comp->try_index());
812 __ Bind(&done);
813 }
814
815
745 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 816 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
746 if (receiver_type() == kIllegalObjectKind) { 817 if (receiver_type() == kIllegalObjectKind) {
747 EmitStoreIndexedGeneric(compiler, this); 818 if (HasICData()) {
819 EmitStoreIndexedPolymorphic(compiler, this);
820 } else {
821 EmitStoreIndexedGeneric(compiler, this);
822 }
748 return; 823 return;
749 } 824 }
750 825
751 Register receiver = locs()->in(0).reg(); 826 Register receiver = locs()->in(0).reg();
752 Register index = locs()->in(1).reg(); 827 Register index = locs()->in(1).reg();
753 Register value = locs()->in(2).reg(); 828 Register value = locs()->in(2).reg();
754 Register temp = locs()->temp(0).reg(); 829 Register temp = locs()->temp(0).reg();
755 830
756 Label* deopt = compiler->AddDeoptStub(cid(), 831 Label* deopt = compiler->AddDeoptStub(cid(),
757 token_index(), 832 token_index(),
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 } 1828 }
1754 1829
1755 1830
1756 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1831 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1757 return MakeCallSummary(); 1832 return MakeCallSummary();
1758 } 1833 }
1759 1834
1760 1835
1761 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1836 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1762 ASSERT(instance_call()->VerifyComputation()); 1837 ASSERT(instance_call()->VerifyComputation());
1763 ASSERT(HasICData());
1764 ASSERT(ic_data()->num_args_tested() == 1);
1765 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1838 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1766 instance_call()->token_index(), 1839 instance_call()->token_index(),
1767 instance_call()->try_index(), 1840 instance_call()->try_index(),
1768 kDeoptPolymorphicInstanceCallTestFail); 1841 kDeoptPolymorphicInstanceCallTestFail);
1842 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1843 __ jmp(deopt);
1844 return;
1845 }
1846 ASSERT(HasICData());
1847 ASSERT(ic_data()->num_args_tested() == 1);
1769 Label handle_smi; 1848 Label handle_smi;
1770 Label* is_smi_label = 1849 Label* is_smi_label =
1771 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1850 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1772 1851
1773 // Load receiver into EAX. 1852 // Load receiver into EAX.
1774 __ movl(EAX, 1853 __ movl(EAX,
1775 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1854 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1776 __ testl(EAX, Immediate(kSmiTagMask)); 1855 __ testl(EAX, Immediate(kSmiTagMask));
1777 __ j(ZERO, is_smi_label); 1856 __ j(ZERO, is_smi_label);
1778 Label done; 1857 Label done;
1779 __ LoadClassId(EDI, EAX); 1858 __ LoadClassId(EDI, EAX);
1780 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); i++) { 1859 compiler->EmitTestAndCall(*ic_data(),
1781 Label next_test; 1860 EDI, // Class id register.
1782 __ cmpl(EDI, Immediate(ic_data()->GetReceiverClassIdAt(i))); 1861 instance_call()->ArgumentCount(),
1783 __ j(NOT_EQUAL, &next_test); 1862 instance_call()->argument_names(),
1784 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(i)); 1863 deopt, &done, // Labels.
1785 compiler->GenerateStaticCall(instance_call()->cid(), 1864 instance_call()->cid(),
1786 instance_call()->token_index(), 1865 instance_call()->token_index(),
1787 instance_call()->try_index(), 1866 instance_call()->try_index());
1788 target,
1789 instance_call()->ArgumentCount(),
1790 instance_call()->argument_names());
1791 __ jmp(&done);
1792 __ Bind(&next_test);
1793 }
1794 __ jmp(deopt);
1795 if (is_smi_label == &handle_smi) { 1867 if (is_smi_label == &handle_smi) {
1796 __ Bind(&handle_smi); 1868 __ Bind(&handle_smi);
1797 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1869 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1798 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1870 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1799 compiler->GenerateStaticCall(instance_call()->cid(), 1871 compiler->GenerateStaticCall(instance_call()->cid(),
1800 instance_call()->token_index(), 1872 instance_call()->token_index(),
1801 instance_call()->try_index(), 1873 instance_call()->try_index(),
1802 target, 1874 target,
1803 instance_call()->ArgumentCount(), 1875 instance_call()->ArgumentCount(),
1804 instance_call()->argument_names()); 1876 instance_call()->argument_names());
1805 } 1877 }
1806 __ Bind(&done); 1878 __ Bind(&done);
1807 } 1879 }
1808 1880
1809 1881
1810 } // namespace dart 1882 } // namespace dart
1811 1883
1812 #undef __ 1884 #undef __
1813 1885
1814 #endif // defined TARGET_ARCH_X64 1886 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698