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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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_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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 frame_register_allocator()->AllocateRegisters(instr); 658 frame_register_allocator()->AllocateRegisters(instr);
659 659
660 // TODO(vegorov): adjust assertion when we start removing comparison from the 660 // TODO(vegorov): adjust assertion when we start removing comparison from the
661 // graph when it is merged with a branch. 661 // graph when it is merged with a branch.
662 ASSERT(locs->is_call() || 662 ASSERT(locs->is_call() ||
663 (locs->input_count() == instr->InputCount())); 663 (locs->input_count() == instr->InputCount()));
664 } 664 }
665 665
666 666
667 void FlowGraphCompiler::CopyParameters() { 667 void FlowGraphCompiler::CopyParameters() {
668 __ Comment("Copy parameters");
668 const Function& function = parsed_function().function(); 669 const Function& function = parsed_function().function();
669 const bool is_native_instance_closure = 670 const bool is_native_instance_closure =
670 function.is_native() && function.IsImplicitInstanceClosureFunction(); 671 function.is_native() && function.IsImplicitInstanceClosureFunction();
671 LocalScope* scope = parsed_function().node_sequence()->scope(); 672 LocalScope* scope = parsed_function().node_sequence()->scope();
672 const int num_fixed_params = function.num_fixed_parameters(); 673 const int num_fixed_params = function.num_fixed_parameters();
673 const int num_opt_params = function.num_optional_parameters(); 674 const int num_opt_params = function.num_optional_parameters();
674 int implicit_this_param_pos = is_native_instance_closure ? -1 : 0; 675 int implicit_this_param_pos = is_native_instance_closure ? -1 : 0;
675 ASSERT(parsed_function().first_parameter_index() == 676 ASSERT(parsed_function().first_parameter_index() ==
676 ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos); 677 ParsedFunction::kFirstLocalSlotIndex + implicit_this_param_pos);
677 // Copy positional arguments. 678 // Copy positional arguments.
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 __ int3(); 934 __ int3();
934 __ jmp(&StubCode::FixCallersTargetLabel()); 935 __ jmp(&StubCode::FixCallersTargetLabel());
935 return; 936 return;
936 } 937 }
937 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 938 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
938 const Function& function = parsed_function().function(); 939 const Function& function = parsed_function().function();
939 940
940 const int parameter_count = function.num_fixed_parameters(); 941 const int parameter_count = function.num_fixed_parameters();
941 const int num_copied_params = parsed_function().copied_parameter_count(); 942 const int num_copied_params = parsed_function().copied_parameter_count();
942 const int local_count = parsed_function().stack_local_count(); 943 const int local_count = parsed_function().stack_local_count();
944 __ Comment("Enter frame");
943 if (IsLeaf()) { 945 if (IsLeaf()) {
944 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 946 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
945 } else { 947 } else {
946 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 948 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
947 } 949 }
948 // We check the number of passed arguments when we have to copy them due to 950 // We check the number of passed arguments when we have to copy them due to
949 // the presence of optional named parameters. 951 // the presence of optional named parameters.
950 // No such checking code is generated if only fixed parameters are declared, 952 // No such checking code is generated if only fixed parameters are declared,
951 // unless we are debug mode or unless we are compiling a closure. 953 // unless we are debug mode or unless we are compiling a closure.
952 if (num_copied_params == 0) { 954 if (num_copied_params == 0) {
953 #ifdef DEBUG 955 #ifdef DEBUG
954 const bool check_arguments = true; 956 const bool check_arguments = true;
955 #else 957 #else
956 const bool check_arguments = function.IsClosureFunction(); 958 const bool check_arguments = function.IsClosureFunction();
957 #endif 959 #endif
958 if (check_arguments) { 960 if (check_arguments) {
961 __ Comment("Check argument count");
959 // Check that num_fixed <= argc <= num_params. 962 // Check that num_fixed <= argc <= num_params.
960 Label argc_in_range; 963 Label argc_in_range;
961 // Total number of args is the first Smi in args descriptor array (EDX). 964 // Total number of args is the first Smi in args descriptor array (EDX).
962 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 965 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
963 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); 966 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count)));
964 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 967 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
965 if (function.IsClosureFunction()) { 968 if (function.IsClosureFunction()) {
966 GenerateCallRuntime(Isolate::kNoDeoptId, 969 GenerateCallRuntime(Isolate::kNoDeoptId,
967 function.token_pos(), 970 function.token_pos(),
968 CatchClauseNode::kInvalidTryIndex, 971 CatchClauseNode::kInvalidTryIndex,
(...skipping 10 matching lines...) Expand all
979 // TODO(vegorov): introduce stack maps and stop initializing all spill slots 982 // TODO(vegorov): introduce stack maps and stop initializing all spill slots
980 // with null. 983 // with null.
981 const intptr_t stack_slot_count = 984 const intptr_t stack_slot_count =
982 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count() 985 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count()
983 : local_count; 986 : local_count;
984 987
985 const intptr_t slot_base = parsed_function().first_stack_local_index(); 988 const intptr_t slot_base = parsed_function().first_stack_local_index();
986 989
987 // Initialize (non-argument) stack allocated locals to null. 990 // Initialize (non-argument) stack allocated locals to null.
988 if (stack_slot_count > 0) { 991 if (stack_slot_count > 0) {
992 __ Comment("Initialize spill slots");
989 const Immediate raw_null = 993 const Immediate raw_null =
990 Immediate(reinterpret_cast<intptr_t>(Object::null())); 994 Immediate(reinterpret_cast<intptr_t>(Object::null()));
991 __ movl(EAX, raw_null); 995 __ movl(EAX, raw_null);
992 for (intptr_t i = 0; i < stack_slot_count; ++i) { 996 for (intptr_t i = 0; i < stack_slot_count; ++i) {
993 // Subtract index i (locals lie at lower addresses than EBP). 997 // Subtract index i (locals lie at lower addresses than EBP).
994 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); 998 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
995 } 999 }
996 } 1000 }
997 1001
998 if (!IsLeaf()) {
999 // Generate stack overflow check.
1000 __ cmpl(ESP,
1001 Address::Absolute(Isolate::Current()->stack_limit_address()));
1002 Label no_stack_overflow;
1003 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1004 GenerateCallRuntime(Isolate::kNoDeoptId,
1005 function.token_pos(),
1006 CatchClauseNode::kInvalidTryIndex,
1007 kStackOverflowRuntimeEntry);
1008 __ Bind(&no_stack_overflow);
1009 }
1010 if (FLAG_print_scopes) { 1002 if (FLAG_print_scopes) {
1011 // Print the function scope (again) after generating the prologue in order 1003 // Print the function scope (again) after generating the prologue in order
1012 // to see annotations such as allocation indices of locals. 1004 // to see annotations such as allocation indices of locals.
1013 if (FLAG_print_ast) { 1005 if (FLAG_print_ast) {
1014 // Second printing. 1006 // Second printing.
1015 OS::Print("Annotated "); 1007 OS::Print("Annotated ");
1016 } 1008 }
1017 AstPrinter::PrintFunctionScope(parsed_function()); 1009 AstPrinter::PrintFunctionScope(parsed_function());
1018 } 1010 }
1019 1011
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 __ popl(ECX); 1251 __ popl(ECX);
1260 __ popl(EAX); 1252 __ popl(EAX);
1261 } 1253 }
1262 1254
1263 1255
1264 #undef __ 1256 #undef __
1265 1257
1266 } // namespace dart 1258 } // namespace dart
1267 1259
1268 #endif // defined TARGET_ARCH_IA32 1260 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698