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

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

Issue 10855019: Add a function's initial stack check to the IL instruction stream. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 frame_register_allocator()->AllocateRegisters(instr); 639 frame_register_allocator()->AllocateRegisters(instr);
640 640
641 // TODO(vegorov): adjust assertion when we start removing comparison from the 641 // TODO(vegorov): adjust assertion when we start removing comparison from the
642 // graph when it is merged with a branch. 642 // graph when it is merged with a branch.
643 ASSERT(locs->is_call() || 643 ASSERT(locs->is_call() ||
644 (locs->input_count() == instr->InputCount())); 644 (locs->input_count() == instr->InputCount()));
645 } 645 }
646 646
647 647
648 void FlowGraphCompiler::CopyParameters() { 648 void FlowGraphCompiler::CopyParameters() {
649 __ Comment("Copy parameters");
649 const Function& function = parsed_function().function(); 650 const Function& function = parsed_function().function();
650 const bool is_native_instance_closure = 651 const bool is_native_instance_closure =
651 function.is_native() && function.IsImplicitInstanceClosureFunction(); 652 function.is_native() && function.IsImplicitInstanceClosureFunction();
652 LocalScope* scope = parsed_function().node_sequence()->scope(); 653 LocalScope* scope = parsed_function().node_sequence()->scope();
653 const int num_fixed_params = function.num_fixed_parameters(); 654 const int num_fixed_params = function.num_fixed_parameters();
654 const int num_opt_params = function.num_optional_parameters(); 655 const int num_opt_params = function.num_optional_parameters();
655 int implicit_this_param_pos = is_native_instance_closure ? -1 : 0; 656 int implicit_this_param_pos = is_native_instance_closure ? -1 : 0;
656 ASSERT(parsed_function().first_parameter_index() == 657 ASSERT(parsed_function().first_parameter_index() ==
657 ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos); 658 ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos);
658 // Copy positional arguments. 659 // Copy positional arguments.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 __ int3(); 918 __ int3();
918 __ jmp(&StubCode::FixCallersTargetLabel()); 919 __ jmp(&StubCode::FixCallersTargetLabel());
919 return; 920 return;
920 } 921 }
921 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 922 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
922 const Function& function = parsed_function().function(); 923 const Function& function = parsed_function().function();
923 924
924 const int parameter_count = function.num_fixed_parameters(); 925 const int parameter_count = function.num_fixed_parameters();
925 const int num_copied_params = parsed_function().copied_parameter_count(); 926 const int num_copied_params = parsed_function().copied_parameter_count();
926 const int local_count = parsed_function().stack_local_count(); 927 const int local_count = parsed_function().stack_local_count();
928 __ Comment("Enter frame");
927 if (IsLeaf()) { 929 if (IsLeaf()) {
928 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 930 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
929 } else { 931 } else {
930 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 932 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
931 } 933 }
932 // We check the number of passed arguments when we have to copy them due to 934 // We check the number of passed arguments when we have to copy them due to
933 // the presence of optional named parameters. 935 // the presence of optional named parameters.
934 // No such checking code is generated if only fixed parameters are declared, 936 // No such checking code is generated if only fixed parameters are declared,
935 // unless we are debug mode or unless we are compiling a closure. 937 // unless we are debug mode or unless we are compiling a closure.
936 if (num_copied_params == 0) { 938 if (num_copied_params == 0) {
937 #ifdef DEBUG 939 #ifdef DEBUG
938 const bool check_arguments = true; 940 const bool check_arguments = true;
939 #else 941 #else
940 const bool check_arguments = function.IsClosureFunction(); 942 const bool check_arguments = function.IsClosureFunction();
941 #endif 943 #endif
942 if (check_arguments) { 944 if (check_arguments) {
945 __ Comment("Check argument count");
943 // Check that num_fixed <= argc <= num_params. 946 // Check that num_fixed <= argc <= num_params.
944 Label argc_in_range; 947 Label argc_in_range;
945 // Total number of args is the first Smi in args descriptor array (R10). 948 // Total number of args is the first Smi in args descriptor array (R10).
946 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 949 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
947 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); 950 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count)));
948 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 951 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
949 if (function.IsClosureFunction()) { 952 if (function.IsClosureFunction()) {
950 GenerateCallRuntime(Isolate::kNoDeoptId, 953 GenerateCallRuntime(Isolate::kNoDeoptId,
951 function.token_pos(), 954 function.token_pos(),
952 CatchClauseNode::kInvalidTryIndex, 955 CatchClauseNode::kInvalidTryIndex,
(...skipping 10 matching lines...) Expand all
963 // TODO(vegorov): introduce stack maps and stop initializing all spill slots 966 // TODO(vegorov): introduce stack maps and stop initializing all spill slots
964 // with null. 967 // with null.
965 const intptr_t stack_slot_count = 968 const intptr_t stack_slot_count =
966 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count() 969 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count()
967 : local_count; 970 : local_count;
968 971
969 const intptr_t slot_base = parsed_function().first_stack_local_index(); 972 const intptr_t slot_base = parsed_function().first_stack_local_index();
970 973
971 // Initialize (non-argument) stack allocated locals to null. 974 // Initialize (non-argument) stack allocated locals to null.
972 if (stack_slot_count > 0) { 975 if (stack_slot_count > 0) {
976 __ Comment("Initialize spill slots");
973 const Immediate raw_null = 977 const Immediate raw_null =
974 Immediate(reinterpret_cast<intptr_t>(Object::null())); 978 Immediate(reinterpret_cast<intptr_t>(Object::null()));
975 __ movq(RAX, raw_null); 979 __ movq(RAX, raw_null);
976 for (intptr_t i = 0; i < stack_slot_count; ++i) { 980 for (intptr_t i = 0; i < stack_slot_count; ++i) {
977 // Subtract index i (locals lie at lower addresses than RBP). 981 // Subtract index i (locals lie at lower addresses than RBP).
978 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX); 982 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
979 } 983 }
980 } 984 }
981 985
982 if (!IsLeaf()) {
983 // Generate stack overflow check.
984 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address()));
985 __ cmpq(RSP, Address(RDI, 0));
986 Label no_stack_overflow;
987 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
988 GenerateCallRuntime(Isolate::kNoDeoptId,
989 function.token_pos(),
990 CatchClauseNode::kInvalidTryIndex,
991 kStackOverflowRuntimeEntry);
992 __ Bind(&no_stack_overflow);
993 }
994 if (FLAG_print_scopes) { 986 if (FLAG_print_scopes) {
995 // Print the function scope (again) after generating the prologue in order 987 // Print the function scope (again) after generating the prologue in order
996 // to see annotations such as allocation indices of locals. 988 // to see annotations such as allocation indices of locals.
997 if (FLAG_print_ast) { 989 if (FLAG_print_ast) {
998 // Second printing. 990 // Second printing.
999 OS::Print("Annotated "); 991 OS::Print("Annotated ");
1000 } 992 }
1001 AstPrinter::PrintFunctionScope(parsed_function()); 993 AstPrinter::PrintFunctionScope(parsed_function());
1002 } 994 }
1003 995
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1213 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1222 __ Exchange(mem1, mem2); 1214 __ Exchange(mem1, mem2);
1223 } 1215 }
1224 1216
1225 1217
1226 #undef __ 1218 #undef __
1227 1219
1228 } // namespace dart 1220 } // namespace dart
1229 1221
1230 #endif // defined TARGET_ARCH_X64 1222 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_builder.cc ('K') | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698