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

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

Issue 10668034: Recognize leaf functions: skip stack check and populating the pc slot, store the pc slot lazily in … (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
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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 15 matching lines...) Expand all
26 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) { 26 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler) {
27 Assembler* assem = compiler->assembler(); 27 Assembler* assem = compiler->assembler();
28 #define __ assem-> 28 #define __ assem->
29 __ Comment("Deopt stub for id %d", deopt_id_); 29 __ Comment("Deopt stub for id %d", deopt_id_);
30 __ Bind(entry_label()); 30 __ Bind(entry_label());
31 for (intptr_t i = 0; i < registers_.length(); i++) { 31 for (intptr_t i = 0; i < registers_.length(); i++) {
32 if (registers_[i] != kNoRegister) { 32 if (registers_[i] != kNoRegister) {
33 __ pushq(registers_[i]); 33 __ pushq(registers_[i]);
34 } 34 }
35 } 35 }
36 if (compiler->IsLeaf()) {
37 Label L;
38 __ call(&L);
39 const intptr_t offset = assem->CodeSize();
40 __ Bind(&L);
41 __ popq(RAX);
42 __ subq(RAX,
43 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint));
44 __ movq(Address(RBP, -kWordSize), RAX);
45 }
36 __ movq(RAX, Immediate(Smi::RawValue(reason_))); 46 __ movq(RAX, Immediate(Smi::RawValue(reason_)));
37 __ call(&StubCode::DeoptimizeLabel()); 47 __ call(&StubCode::DeoptimizeLabel());
38 compiler->AddCurrentDescriptor(PcDescriptors::kOther, 48 compiler->AddCurrentDescriptor(PcDescriptors::kOther,
39 deopt_id_, 49 deopt_id_,
40 deopt_token_pos_, 50 deopt_token_pos_,
41 try_index_); 51 try_index_);
42 #undef __ 52 #undef __
43 } 53 }
44 54
45 55
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 // The NoSuchMethodFunction stub does not expect to see that area on the 768 // The NoSuchMethodFunction stub does not expect to see that area on the
759 // stack. 769 // stack.
760 __ addq(RSP, Immediate(StackSize() * kWordSize)); 770 __ addq(RSP, Immediate(StackSize() * kWordSize));
761 } 771 }
762 if (function.IsClosureFunction()) { 772 if (function.IsClosureFunction()) {
763 GenerateCallRuntime(AstNode::kNoId, 773 GenerateCallRuntime(AstNode::kNoId,
764 0, 774 0,
765 CatchClauseNode::kInvalidTryIndex, 775 CatchClauseNode::kInvalidTryIndex,
766 kClosureArgumentMismatchRuntimeEntry); 776 kClosureArgumentMismatchRuntimeEntry);
767 } else { 777 } else {
778 ASSERT(!IsLeaf());
768 // Invoke noSuchMethod function. 779 // Invoke noSuchMethod function.
769 const int kNumArgsChecked = 1; 780 const int kNumArgsChecked = 1;
770 ICData& ic_data = ICData::ZoneHandle(); 781 ICData& ic_data = ICData::ZoneHandle();
771 ic_data = ICData::New(function, 782 ic_data = ICData::New(function,
772 String::Handle(function.name()), 783 String::Handle(function.name()),
773 AstNode::kNoId, 784 AstNode::kNoId,
774 kNumArgsChecked); 785 kNumArgsChecked);
775 __ LoadObject(RBX, ic_data); 786 __ LoadObject(RBX, ic_data);
776 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. 787 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
777 // RBP : points to previous frame pointer. 788 // RBP : points to previous frame pointer.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 __ int3(); 889 __ int3();
879 __ jmp(&StubCode::FixCallersTargetLabel()); 890 __ jmp(&StubCode::FixCallersTargetLabel());
880 return; 891 return;
881 } 892 }
882 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 893 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
883 const Function& function = parsed_function().function(); 894 const Function& function = parsed_function().function();
884 895
885 const int parameter_count = function.num_fixed_parameters(); 896 const int parameter_count = function.num_fixed_parameters();
886 const int num_copied_params = parsed_function().copied_parameter_count(); 897 const int num_copied_params = parsed_function().copied_parameter_count();
887 const int local_count = parsed_function().stack_local_count(); 898 const int local_count = parsed_function().stack_local_count();
888 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 899 if (IsLeaf()) {
900 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
901 } else {
902 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
903 }
889 // We check the number of passed arguments when we have to copy them due to 904 // We check the number of passed arguments when we have to copy them due to
890 // the presence of optional named parameters. 905 // the presence of optional named parameters.
891 // No such checking code is generated if only fixed parameters are declared, 906 // No such checking code is generated if only fixed parameters are declared,
892 // unless we are debug mode or unless we are compiling a closure. 907 // unless we are debug mode or unless we are compiling a closure.
893 if (num_copied_params == 0) { 908 if (num_copied_params == 0) {
894 #ifdef DEBUG 909 #ifdef DEBUG
895 const bool check_arguments = true; 910 const bool check_arguments = true;
896 #else 911 #else
897 const bool check_arguments = function.IsClosureFunction(); 912 const bool check_arguments = function.IsClosureFunction();
898 #endif 913 #endif
(...skipping 22 matching lines...) Expand all
921 const Immediate raw_null = 936 const Immediate raw_null =
922 Immediate(reinterpret_cast<intptr_t>(Object::null())); 937 Immediate(reinterpret_cast<intptr_t>(Object::null()));
923 __ movq(RAX, raw_null); 938 __ movq(RAX, raw_null);
924 const int base = parsed_function().first_stack_local_index(); 939 const int base = parsed_function().first_stack_local_index();
925 for (int i = 0; i < local_count; ++i) { 940 for (int i = 0; i < local_count; ++i) {
926 // Subtract index i (locals lie at lower addresses than RBP). 941 // Subtract index i (locals lie at lower addresses than RBP).
927 __ movq(Address(RBP, (base - i) * kWordSize), RAX); 942 __ movq(Address(RBP, (base - i) * kWordSize), RAX);
928 } 943 }
929 } 944 }
930 945
931 // Generate stack overflow check. 946 if (!IsLeaf()) {
932 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address())); 947 // Generate stack overflow check.
933 __ cmpq(RSP, Address(RDI, 0)); 948 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address()));
934 Label no_stack_overflow; 949 __ cmpq(RSP, Address(RDI, 0));
935 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 950 Label no_stack_overflow;
936 GenerateCallRuntime(AstNode::kNoId, 951 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
937 function.token_pos(), 952 GenerateCallRuntime(AstNode::kNoId,
938 CatchClauseNode::kInvalidTryIndex, 953 function.token_pos(),
939 kStackOverflowRuntimeEntry); 954 CatchClauseNode::kInvalidTryIndex,
940 __ Bind(&no_stack_overflow); 955 kStackOverflowRuntimeEntry);
941 956 __ Bind(&no_stack_overflow);
957 }
942 if (FLAG_print_scopes) { 958 if (FLAG_print_scopes) {
943 // Print the function scope (again) after generating the prologue in order 959 // Print the function scope (again) after generating the prologue in order
944 // to see annotations such as allocation indices of locals. 960 // to see annotations such as allocation indices of locals.
945 if (FLAG_print_ast) { 961 if (FLAG_print_ast) {
946 // Second printing. 962 // Second printing.
947 OS::Print("Annotated "); 963 OS::Print("Annotated ");
948 } 964 }
949 AstPrinter::PrintFunctionScope(parsed_function()); 965 AstPrinter::PrintFunctionScope(parsed_function());
950 } 966 }
951 967
952 VisitBlocks(); 968 VisitBlocks();
953 969
954 __ int3(); 970 __ int3();
955 GenerateDeferredCode(); 971 GenerateDeferredCode();
956 // Emit function patching code. This will be swapped with the first 13 bytes 972 // Emit function patching code. This will be swapped with the first 13 bytes
957 // at entry point. 973 // at entry point.
958 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, 974 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
959 assembler()->CodeSize(), 975 assembler()->CodeSize(),
960 AstNode::kNoId, 976 AstNode::kNoId,
961 0, 977 0,
962 -1); 978 -1);
963 __ jmp(&StubCode::FixCallersTargetLabel()); 979 __ jmp(&StubCode::FixCallersTargetLabel());
964 } 980 }
965 981
966 982
967 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 983 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
968 intptr_t try_index, 984 intptr_t try_index,
969 const ExternalLabel* label, 985 const ExternalLabel* label,
970 PcDescriptors::Kind kind) { 986 PcDescriptors::Kind kind) {
987 ASSERT(!IsLeaf());
971 ASSERT(frame_register_allocator()->IsSpilled()); 988 ASSERT(frame_register_allocator()->IsSpilled());
972 __ call(label); 989 __ call(label);
973 AddCurrentDescriptor(kind, AstNode::kNoId, token_pos, try_index); 990 AddCurrentDescriptor(kind, AstNode::kNoId, token_pos, try_index);
974 } 991 }
975 992
976 993
977 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid, 994 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid,
978 intptr_t token_pos, 995 intptr_t token_pos,
979 intptr_t try_index, 996 intptr_t try_index,
980 const RuntimeEntry& entry) { 997 const RuntimeEntry& entry) {
998 ASSERT(!IsLeaf());
981 ASSERT(frame_register_allocator()->IsSpilled()); 999 ASSERT(frame_register_allocator()->IsSpilled());
982 __ CallRuntime(entry); 1000 __ CallRuntime(entry);
983 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_pos, try_index); 1001 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_pos, try_index);
984 } 1002 }
985 1003
986 1004
987 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1005 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
988 const ICData& ic_data, 1006 const ICData& ic_data,
989 const Array& arguments_descriptor, 1007 const Array& arguments_descriptor,
990 intptr_t argument_count) { 1008 intptr_t argument_count) {
1009 ASSERT(!IsLeaf());
991 __ LoadObject(RBX, ic_data); 1010 __ LoadObject(RBX, ic_data);
992 __ LoadObject(R10, arguments_descriptor); 1011 __ LoadObject(R10, arguments_descriptor);
993 1012
994 __ call(target_label); 1013 __ call(target_label);
995 const intptr_t descr_offset = assembler()->CodeSize(); 1014 const intptr_t descr_offset = assembler()->CodeSize();
996 __ Drop(argument_count); 1015 __ Drop(argument_count);
997 return descr_offset; 1016 return descr_offset;
998 } 1017 }
999 1018
1000 1019
1001 intptr_t FlowGraphCompiler::EmitStaticCall(const Function& function, 1020 intptr_t FlowGraphCompiler::EmitStaticCall(const Function& function,
1002 const Array& arguments_descriptor, 1021 const Array& arguments_descriptor,
1003 intptr_t argument_count) { 1022 intptr_t argument_count) {
1023 ASSERT(!IsLeaf());
1004 __ LoadObject(RBX, function); 1024 __ LoadObject(RBX, function);
1005 __ LoadObject(R10, arguments_descriptor); 1025 __ LoadObject(R10, arguments_descriptor);
1006 __ call(&StubCode::CallStaticFunctionLabel()); 1026 __ call(&StubCode::CallStaticFunctionLabel());
1007 const intptr_t descr_offset = assembler()->CodeSize(); 1027 const intptr_t descr_offset = assembler()->CodeSize();
1008 __ Drop(argument_count); 1028 __ Drop(argument_count);
1009 return descr_offset; 1029 return descr_offset;
1010 } 1030 }
1011 1031
1012 1032
1013 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label 1033 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 __ cvtsi2sd(result, temp); 1077 __ cvtsi2sd(result, temp);
1058 __ Bind(&done); 1078 __ Bind(&done);
1059 } 1079 }
1060 1080
1061 1081
1062 #undef __ 1082 #undef __
1063 1083
1064 } // namespace dart 1084 } // namespace dart
1065 1085
1066 #endif // defined TARGET_ARCH_X64 1086 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698