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