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

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

Issue 10704210: Fix problem of excessive attempts to optimize, fix excessive deoptimizations for load/store indexed… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 // TODO(srdjan): Replace the counting code with a type feedback 61 // TODO(srdjan): Replace the counting code with a type feedback
62 // collection and counting stub. 62 // collection and counting stub.
63 const Function& function = 63 const Function& function =
64 Function::ZoneHandle(compiler->parsed_function().function().raw()); 64 Function::ZoneHandle(compiler->parsed_function().function().raw());
65 __ LoadObject(temp, function); 65 __ LoadObject(temp, function);
66 __ incq(FieldAddress(temp, Function::usage_counter_offset())); 66 __ incq(FieldAddress(temp, Function::usage_counter_offset()));
67 if (FlowGraphCompiler::CanOptimize()) { 67 if (FlowGraphCompiler::CanOptimize()) {
68 // Do not optimize if usage count must be reported. 68 // Do not optimize if usage count must be reported.
69 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()), 69 __ cmpl(FieldAddress(temp, Function::usage_counter_offset()),
70 Immediate(FLAG_optimization_counter_threshold)); 70 Immediate(FLAG_optimization_counter_threshold));
71 Label not_yet_hot; 71 Label not_yet_hot, already_optimized;
72 __ j(LESS_EQUAL, &not_yet_hot, Assembler::kNearJump); 72 __ j(LESS, &not_yet_hot, Assembler::kNearJump);
73 __ j(GREATER, &already_optimized, Assembler::kNearJump);
73 __ pushq(result); // Preserve result. 74 __ pushq(result); // Preserve result.
74 __ pushq(temp); // Argument for runtime: function to optimize. 75 __ pushq(temp); // Argument for runtime: function to optimize.
75 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); 76 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
76 __ popq(temp); // Remove argument. 77 __ popq(temp); // Remove argument.
77 __ popq(result); // Restore result. 78 __ popq(result); // Restore result.
78 __ Bind(&not_yet_hot); 79 __ Bind(&not_yet_hot);
80 __ Bind(&already_optimized);
79 } 81 }
80 } 82 }
81 if (FLAG_trace_functions) { 83 if (FLAG_trace_functions) {
82 const Function& function = 84 const Function& function =
83 Function::ZoneHandle(compiler->parsed_function().function().raw()); 85 Function::ZoneHandle(compiler->parsed_function().function().raw());
84 __ LoadObject(temp, function); 86 __ LoadObject(temp, function);
85 __ pushq(result); // Preserve result. 87 __ pushq(result); // Preserve result.
86 __ pushq(temp); 88 __ pushq(temp);
87 compiler->GenerateCallRuntime(AstNode::kNoId, 89 compiler->GenerateCallRuntime(AstNode::kNoId,
88 0, 90 0,
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 572
571 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 573 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
572 if (operands_class_id() == kSmi) { 574 if (operands_class_id() == kSmi) {
573 EmitSmiRelationalOp(compiler, this); 575 EmitSmiRelationalOp(compiler, this);
574 return; 576 return;
575 } 577 }
576 if (operands_class_id() == kDouble) { 578 if (operands_class_id() == kDouble) {
577 EmitDoubleRelationalOp(compiler, this); 579 EmitDoubleRelationalOp(compiler, this);
578 return; 580 return;
579 } 581 }
582 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
583 Label* deopt = compiler->AddDeoptStub(cid(),
584 token_pos(),
585 try_index(),
586 kDeoptRelationalOp);
587 // Load receiver into RAX, class into RDI.
588 Label done;
589 const intptr_t kNumArguments = 2;
590 __ movq(RDI, Immediate(kSmi));
591 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
592 __ testq(RAX, Immediate(kSmiTagMask));
593 __ j(ZERO, &done);
594 __ LoadClassId(RDI, RAX);
595 __ Bind(&done);
596 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
597 RDI, // Class id register.
598 kNumArguments,
599 Array::Handle(), // No named arguments.
600 deopt, // Deoptimize target.
601 NULL, // Fallthrough when done.
602 cid(),
603 token_pos(),
604 try_index());
605 return;
606 }
580 const String& function_name = 607 const String& function_name =
581 String::ZoneHandle(String::NewSymbol(Token::Str(kind()))); 608 String::ZoneHandle(String::NewSymbol(Token::Str(kind())));
582 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 609 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
583 cid(), 610 cid(),
584 token_pos(), 611 token_pos(),
585 try_index()); 612 try_index());
586 const intptr_t kNumArguments = 2; 613 const intptr_t kNumArguments = 2;
587 const intptr_t kNumArgsChecked = 2; // Type-feedback. 614 const intptr_t kNumArgsChecked = 2; // Type-feedback.
588 compiler->GenerateInstanceCall(cid(), 615 compiler->GenerateInstanceCall(cid(),
589 token_pos(), 616 token_pos(),
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 } 685 }
659 } 686 }
660 687
661 688
662 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 689 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
663 LoadIndexedComp* comp) { 690 LoadIndexedComp* comp) {
664 Label* deopt = compiler->AddDeoptStub(comp->cid(), 691 Label* deopt = compiler->AddDeoptStub(comp->cid(),
665 comp->token_pos(), 692 comp->token_pos(),
666 comp->try_index(), 693 comp->try_index(),
667 kDeoptLoadIndexedPolymorphic); 694 kDeoptLoadIndexedPolymorphic);
668 if (comp->ic_data()->NumberOfChecks() == 0) { 695 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
669 __ jmp(deopt);
670 return;
671 }
672 ASSERT(comp->HasICData()); 696 ASSERT(comp->HasICData());
673 const ICData& ic_data = *comp->ic_data(); 697 const ICData& ic_data = *comp->ic_data();
674 ASSERT(ic_data.num_args_tested() == 1); 698 ASSERT(ic_data.num_args_tested() == 1);
675 // No indexed access on Smi. 699 // No indexed access on Smi.
676 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 700 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
677 // Load receiver into RAX. 701 // Load receiver into RAX.
678 const intptr_t kNumArguments = 2; 702 const intptr_t kNumArguments = 2;
679 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 703 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
680 __ testq(RAX, Immediate(kSmiTagMask)); 704 __ testq(RAX, Immediate(kSmiTagMask));
681 __ j(ZERO, deopt); 705 __ j(ZERO, deopt);
682 __ LoadClassId(RDI, RAX); 706 __ LoadClassId(RDI, RAX);
683 compiler->EmitTestAndCall(ic_data, 707 compiler->EmitTestAndCall(ic_data,
684 RDI, // Class id register. 708 RDI, // Class id register.
685 kNumArguments, 709 kNumArguments,
686 Array::Handle(), // No named arguments. 710 Array::Handle(), // No named arguments.
687 deopt, // Deoptimize target. 711 deopt, // Deoptimize target.
688 NULL, // Fallthrough when done. 712 NULL, // Fallthrough when done.
689 comp->cid(), 713 comp->cid(),
690 comp->token_pos(), 714 comp->token_pos(),
691 comp->try_index()); 715 comp->try_index());
692 } 716 }
693 717
694 718
695 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 719 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
696 if (receiver_type() == kIllegalObjectKind) { 720 if (receiver_type() == kIllegalObjectKind) {
697 if (HasICData()) { 721 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
698 EmitLoadIndexedPolymorphic(compiler, this); 722 EmitLoadIndexedPolymorphic(compiler, this);
699 } else { 723 } else {
700 compiler->EmitLoadIndexedGeneric(this); 724 compiler->EmitLoadIndexedGeneric(this);
701 } 725 }
702 ASSERT(locs()->out().reg() == RAX); 726 ASSERT(locs()->out().reg() == RAX);
703 return; 727 return;
704 } 728 }
705 729
706 Register receiver = locs()->in(0).reg(); 730 Register receiver = locs()->in(0).reg();
707 Register index = locs()->in(1).reg(); 731 Register index = locs()->in(1).reg();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 kNumArgsChecked); 820 kNumArgsChecked);
797 } 821 }
798 822
799 823
800 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 824 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
801 StoreIndexedComp* comp) { 825 StoreIndexedComp* comp) {
802 Label* deopt = compiler->AddDeoptStub(comp->cid(), 826 Label* deopt = compiler->AddDeoptStub(comp->cid(),
803 comp->token_pos(), 827 comp->token_pos(),
804 comp->try_index(), 828 comp->try_index(),
805 kDeoptStoreIndexedPolymorphic); 829 kDeoptStoreIndexedPolymorphic);
806 if (comp->ic_data()->NumberOfChecks() == 0) { 830 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
807 __ jmp(deopt);
808 return;
809 }
810 ASSERT(comp->HasICData()); 831 ASSERT(comp->HasICData());
811 const ICData& ic_data = *comp->ic_data(); 832 const ICData& ic_data = *comp->ic_data();
812 ASSERT(ic_data.num_args_tested() == 1); 833 ASSERT(ic_data.num_args_tested() == 1);
813 // No indexed access on Smi. 834 // No indexed access on Smi.
814 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 835 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
815 // Load receiver into RAX. 836 // Load receiver into RAX.
816 const intptr_t kNumArguments = 3; 837 const intptr_t kNumArguments = 3;
817 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 838 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
818 __ testq(RAX, Immediate(kSmiTagMask)); 839 __ testq(RAX, Immediate(kSmiTagMask));
819 __ j(ZERO, deopt); 840 __ j(ZERO, deopt);
820 __ LoadClassId(RDI, RAX); 841 __ LoadClassId(RDI, RAX);
821 compiler->EmitTestAndCall(ic_data, 842 compiler->EmitTestAndCall(ic_data,
822 RDI, // Class id register. 843 RDI, // Class id register.
823 kNumArguments, 844 kNumArguments,
824 Array::Handle(), // No named arguments. 845 Array::Handle(), // No named arguments.
825 deopt, // deoptimize label. 846 deopt, // deoptimize label.
826 NULL, // fallthrough when done. 847 NULL, // fallthrough when done.
827 comp->cid(), 848 comp->cid(),
828 comp->token_pos(), 849 comp->token_pos(),
829 comp->try_index()); 850 comp->try_index());
830 } 851 }
831 852
832 853
833 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 854 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
834 if (receiver_type() == kIllegalObjectKind) { 855 if (receiver_type() == kIllegalObjectKind) {
835 if (HasICData()) { 856 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
836 EmitStoreIndexedPolymorphic(compiler, this); 857 EmitStoreIndexedPolymorphic(compiler, this);
837 } else { 858 } else {
838 EmitStoreIndexedGeneric(compiler, this); 859 EmitStoreIndexedGeneric(compiler, this);
839 } 860 }
840 return; 861 return;
841 } 862 }
842 863
843 Register receiver = locs()->in(0).reg(); 864 Register receiver = locs()->in(0).reg();
844 Register index = locs()->in(1).reg(); 865 Register index = locs()->in(1).reg();
845 Register value = locs()->in(2).reg(); 866 Register value = locs()->in(2).reg();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 } 913 }
893 } 914 }
894 915
895 916
896 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { 917 LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
897 return MakeCallSummary(); 918 return MakeCallSummary();
898 } 919 }
899 920
900 921
901 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 922 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
902 const String& function_name = 923 Label* deopt = NULL;
903 String::ZoneHandle(Field::SetterSymbol(field_name())); 924 if (compiler->is_optimizing()) {
925 deopt = compiler->AddDeoptStub(cid(),
926 token_pos(),
927 try_index(),
928 kDeoptInstanceSetter);
929 }
930 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
931 // No index-setter on Smi's.
932 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmi);
933 // Load receiver into RAX.
934 const intptr_t kNumArguments = 2;
935 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
936 __ testq(RAX, Immediate(kSmiTagMask));
937 __ j(ZERO, deopt);
938 __ LoadClassId(RDI, RAX);
939 compiler->EmitTestAndCall(*ic_data(),
940 RDI, // Class id register.
941 kNumArguments,
942 Array::Handle(), // No named arguments.
943 deopt, // Deoptimize target.
944 NULL, // Fallthrough when done.
945 cid(),
946 token_pos(),
947 try_index());
904 948
905 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 949 } else if (compiler->is_optimizing()) {
906 cid(), 950 // Get some IC data then optimize again.
907 token_pos(), 951 __ jmp(deopt);
908 try_index()); 952 } else {
909 const intptr_t kArgumentCount = 2; 953 // Unoptimized code.
910 const intptr_t kCheckedArgumentCount = 1; 954 const String& function_name =
911 compiler->GenerateInstanceCall(cid(), 955 String::ZoneHandle(Field::SetterSymbol(field_name()));
912 token_pos(), 956
913 try_index(), 957 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
914 function_name, 958 cid(),
915 kArgumentCount, 959 token_pos(),
916 Array::ZoneHandle(), 960 try_index());
917 kCheckedArgumentCount); 961 const intptr_t kArgumentCount = 2;
962 const intptr_t kCheckedArgumentCount = 1;
963 compiler->GenerateInstanceCall(cid(),
964 token_pos(),
965 try_index(),
966 function_name,
967 kArgumentCount,
968 Array::ZoneHandle(),
969 kCheckedArgumentCount);
970 }
918 } 971 }
919 972
920 973
921 LocationSummary* StaticSetterComp::MakeLocationSummary() const { 974 LocationSummary* StaticSetterComp::MakeLocationSummary() const {
922 const intptr_t kNumInputs = 1; 975 const intptr_t kNumInputs = 1;
923 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); 976 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
924 } 977 }
925 978
926 979
927 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 980 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 } 2032 }
1980 __ Bind(&done); 2033 __ Bind(&done);
1981 } 2034 }
1982 2035
1983 2036
1984 } // namespace dart 2037 } // namespace dart
1985 2038
1986 #undef __ 2039 #undef __
1987 2040
1988 #endif // defined TARGET_ARCH_X64 2041 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698