| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |