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

Side by Side Diff: runtime/vm/intermediate_language_x64.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/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 308 }
309 309
310 310
311 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 311 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
312 EqualityCompareComp* comp, 312 EqualityCompareComp* comp,
313 Register left, 313 Register left,
314 Register right) { 314 Register right) {
315 ASSERT(comp->HasICData()); 315 ASSERT(comp->HasICData());
316 const ICData& ic_data = *comp->ic_data(); 316 const ICData& ic_data = *comp->ic_data();
317 ASSERT(ic_data.NumberOfChecks() > 0); 317 ASSERT(ic_data.NumberOfChecks() > 0);
318 ASSERT(ic_data.num_args_tested() == 1);
318 Label* deopt = compiler->AddDeoptStub(comp->cid(), 319 Label* deopt = compiler->AddDeoptStub(comp->cid(),
319 comp->token_index(), 320 comp->token_index(),
320 comp->try_index(), 321 comp->try_index(),
321 kDeoptEquality); 322 kDeoptEquality);
322 __ testq(left, Immediate(kSmiTagMask)); 323 __ testq(left, Immediate(kSmiTagMask));
323 Register temp = comp->locs()->temp(0).reg(); 324 Register temp = comp->locs()->temp(0).reg();
324 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 325 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
325 Label done, load_class_id; 326 Label done, load_class_id;
326 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 327 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
327 __ movq(temp, Immediate(kSmi)); 328 __ movq(temp, Immediate(kSmi));
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 return locs; 645 return locs;
645 } else if (receiver_type() == kArray || receiver_type() == kImmutableArray) { 646 } else if (receiver_type() == kArray || receiver_type() == kImmutableArray) {
646 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); 647 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
647 } else { 648 } else {
648 ASSERT(receiver_type() == kIllegalObjectKind); 649 ASSERT(receiver_type() == kIllegalObjectKind);
649 return MakeCallSummary(); 650 return MakeCallSummary();
650 } 651 }
651 } 652 }
652 653
653 654
655 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
656 LoadIndexedComp* comp) {
657 Label* deopt = compiler->AddDeoptStub(comp->cid(),
658 comp->token_index(),
659 comp->try_index(),
660 kDeoptLoadIndexedPolymorphic);
661 if (comp->ic_data()->NumberOfChecks() == 0) {
662 __ jmp(deopt);
663 return;
664 }
665 ASSERT(comp->HasICData());
666 const ICData& ic_data = *comp->ic_data();
667 ASSERT(ic_data.num_args_tested() == 1);
668 // No indexed access on Smi.
669 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
670 // Load receiver into RAX.
671 const intptr_t kNumArguments = 2;
672 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
673 __ testq(RAX, Immediate(kSmiTagMask));
674 __ j(ZERO, deopt);
675 Label done;
676 __ LoadClassId(RDI, RAX);
677 compiler->EmitTestAndCall(ic_data,
678 RDI, // Class id register.
679 kNumArguments,
680 Array::Handle(), // No named arguments.
681 deopt, &done, // Labels.
682 comp->cid(),
683 comp->token_index(),
684 comp->try_index());
685 __ Bind(&done);
686 }
687
688
689
654 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 690 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
655 if (receiver_type() == kIllegalObjectKind) { 691 if (receiver_type() == kIllegalObjectKind) {
656 compiler->EmitLoadIndexedGeneric(this); 692 if (HasICData()) {
693 EmitLoadIndexedPolymorphic(compiler, this);
694 } else {
695 compiler->EmitLoadIndexedGeneric(this);
696 }
657 ASSERT(locs()->out().reg() == RAX); 697 ASSERT(locs()->out().reg() == RAX);
658 return; 698 return;
659 } 699 }
660 700
661 Register receiver = locs()->in(0).reg(); 701 Register receiver = locs()->in(0).reg();
662 Register index = locs()->in(1).reg(); 702 Register index = locs()->in(1).reg();
663 Register result = locs()->out().reg(); 703 Register result = locs()->out().reg();
664 704
665 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 705 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ?
666 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 706 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 comp->token_index(), 781 comp->token_index(),
742 comp->try_index()); 782 comp->try_index());
743 783
744 const intptr_t kNumArguments = 3; 784 const intptr_t kNumArguments = 3;
745 const intptr_t kNumArgsChecked = 1; // Type-feedback. 785 const intptr_t kNumArgsChecked = 1; // Type-feedback.
746 compiler->GenerateInstanceCall(comp->cid(), 786 compiler->GenerateInstanceCall(comp->cid(),
747 comp->token_index(), 787 comp->token_index(),
748 comp->try_index(), 788 comp->try_index(),
749 function_name, 789 function_name,
750 kNumArguments, 790 kNumArguments,
751 Array::ZoneHandle(), // No optional arguments. 791 Array::ZoneHandle(), // No names arguments.
752 kNumArgsChecked); 792 kNumArgsChecked);
753 } 793 }
754 794
755 795
796 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
797 StoreIndexedComp* comp) {
798 Label* deopt = compiler->AddDeoptStub(comp->cid(),
799 comp->token_index(),
800 comp->try_index(),
801 kDeoptStoreIndexedPolymorphic);
802 if (comp->ic_data()->NumberOfChecks() == 0) {
803 __ jmp(deopt);
804 return;
805 }
806 ASSERT(comp->HasICData());
807 const ICData& ic_data = *comp->ic_data();
808 ASSERT(ic_data.num_args_tested() == 1);
809 // No indexed access on Smi.
810 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
811 // Load receiver into RAX.
812 const intptr_t kNumArguments = 3;
813 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
814 __ testq(RAX, Immediate(kSmiTagMask));
815 __ j(ZERO, deopt);
816 Label done;
817 __ LoadClassId(RDI, RAX);
818 compiler->EmitTestAndCall(ic_data,
819 RDI, // Class id register.
820 kNumArguments,
821 Array::Handle(), // No named arguments.
822 deopt, &done, // Labels.
823 comp->cid(),
824 comp->token_index(),
825 comp->try_index());
826 __ Bind(&done);
827 }
828
829
756 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 830 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
757 if (receiver_type() == kIllegalObjectKind) { 831 if (receiver_type() == kIllegalObjectKind) {
758 EmitStoreIndexedGeneric(compiler, this); 832 if (HasICData()) {
833 EmitStoreIndexedPolymorphic(compiler, this);
834 } else {
835 EmitStoreIndexedGeneric(compiler, this);
836 }
759 return; 837 return;
760 } 838 }
761 839
762 Register receiver = locs()->in(0).reg(); 840 Register receiver = locs()->in(0).reg();
763 Register index = locs()->in(1).reg(); 841 Register index = locs()->in(1).reg();
764 Register value = locs()->in(2).reg(); 842 Register value = locs()->in(2).reg();
765 843
766 const Class& receiver_class = 844 const Class& receiver_class =
767 Class::ZoneHandle(Isolate::Current()->class_table()->At( 845 Class::ZoneHandle(Isolate::Current()->class_table()->At(
768 receiver_type())); 846 receiver_type()));
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 } 1845 }
1768 1846
1769 1847
1770 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1848 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1771 return MakeCallSummary(); 1849 return MakeCallSummary();
1772 } 1850 }
1773 1851
1774 1852
1775 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1853 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1776 ASSERT(instance_call()->VerifyComputation()); 1854 ASSERT(instance_call()->VerifyComputation());
1777 ASSERT(HasICData());
1778 ASSERT(ic_data()->num_args_tested() == 1);
1779 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1855 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1780 instance_call()->token_index(), 1856 instance_call()->token_index(),
1781 instance_call()->try_index(), 1857 instance_call()->try_index(),
1782 kDeoptPolymorphicInstanceCallTestFail); 1858 kDeoptPolymorphicInstanceCallTestFail);
1859 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1860 __ jmp(deopt);
1861 return;
1862 }
1863 ASSERT(HasICData());
1864 ASSERT(ic_data()->num_args_tested() == 1);
1783 Label handle_smi; 1865 Label handle_smi;
1784 Label* is_smi_label = 1866 Label* is_smi_label =
1785 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1867 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1786 // Load receiver into RAX. 1868 // Load receiver into RAX.
1787 __ movq(RAX, 1869 __ movq(RAX,
1788 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1870 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1789 __ testq(RAX, Immediate(kSmiTagMask)); 1871 __ testq(RAX, Immediate(kSmiTagMask));
1790 __ j(ZERO, is_smi_label); 1872 __ j(ZERO, is_smi_label);
1791 Label done; 1873 Label done;
1792 __ LoadClassId(RDI, RAX); 1874 __ LoadClassId(RDI, RAX);
1793 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); i++) { 1875 compiler->EmitTestAndCall(*ic_data(),
1794 Label next_test; 1876 RDI, // Class id register.
1795 __ cmpq(RDI, Immediate(ic_data()->GetReceiverClassIdAt(i))); 1877 instance_call()->ArgumentCount(),
1796 __ j(NOT_EQUAL, &next_test); 1878 instance_call()->argument_names(),
1797 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(i)); 1879 deopt, &done, // Labels.
1798 compiler->GenerateStaticCall(instance_call()->cid(), 1880 instance_call()->cid(),
1799 instance_call()->token_index(), 1881 instance_call()->token_index(),
1800 instance_call()->try_index(), 1882 instance_call()->try_index());
1801 target,
1802 instance_call()->ArgumentCount(),
1803 instance_call()->argument_names());
1804 __ jmp(&done);
1805 __ Bind(&next_test);
1806 }
1807 __ jmp(deopt);
1808 if (is_smi_label == &handle_smi) { 1883 if (is_smi_label == &handle_smi) {
1809 __ Bind(&handle_smi); 1884 __ Bind(&handle_smi);
1810 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1885 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1811 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1886 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1812 compiler->GenerateStaticCall(instance_call()->cid(), 1887 compiler->GenerateStaticCall(instance_call()->cid(),
1813 instance_call()->token_index(), 1888 instance_call()->token_index(),
1814 instance_call()->try_index(), 1889 instance_call()->try_index(),
1815 target, 1890 target,
1816 instance_call()->ArgumentCount(), 1891 instance_call()->ArgumentCount(),
1817 instance_call()->argument_names()); 1892 instance_call()->argument_names());
1818 } 1893 }
1819 __ Bind(&done); 1894 __ Bind(&done);
1820 } 1895 }
1821 1896
1822 } // namespace dart 1897 } // namespace dart
1823 1898
1824 #undef __ 1899 #undef __
1825 1900
1826 #endif // defined TARGET_ARCH_X64 1901 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698