| 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" |
| 11 #include "vm/ast_printer.h" | 11 #include "vm/ast_printer.h" |
| 12 #include "vm/il_printer.h" | 12 #include "vm/il_printer.h" |
| 13 #include "vm/locations.h" | 13 #include "vm/locations.h" |
| 14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 15 #include "vm/parser.h" | 15 #include "vm/parser.h" |
| 16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 18 | 18 |
| 19 namespace dart { | 19 namespace dart { |
| 20 | 20 |
| 21 DECLARE_FLAG(bool, print_ast); | 21 DECLARE_FLAG(bool, print_ast); |
| 22 DECLARE_FLAG(bool, print_scopes); | 22 DECLARE_FLAG(bool, print_scopes); |
| 23 DECLARE_FLAG(bool, reject_named_argument_as_positional); | |
| 24 DECLARE_FLAG(bool, trace_functions); | 23 DECLARE_FLAG(bool, trace_functions); |
| 25 DECLARE_FLAG(bool, use_sse41); | 24 DECLARE_FLAG(bool, use_sse41); |
| 26 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); | 25 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); |
| 27 | 26 |
| 28 | 27 |
| 29 FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid, | 28 FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid, |
| 30 Register array, | 29 Register array, |
| 31 Register index) { | 30 Register index) { |
| 32 // Note that index is Smi, i.e, times 2. | 31 // Note that index is Smi, i.e, times 2. |
| 33 ASSERT(kSmiTagShift == 1); | 32 ASSERT(kSmiTagShift == 1); |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 const Address argument_addr(RBX, RCX, TIMES_8, 0); | 690 const Address argument_addr(RBX, RCX, TIMES_8, 0); |
| 692 const Address copy_addr(RDI, RCX, TIMES_8, 0); | 691 const Address copy_addr(RDI, RCX, TIMES_8, 0); |
| 693 __ Bind(&loop); | 692 __ Bind(&loop); |
| 694 __ movq(RAX, argument_addr); | 693 __ movq(RAX, argument_addr); |
| 695 __ movq(copy_addr, RAX); | 694 __ movq(copy_addr, RAX); |
| 696 __ Bind(&loop_condition); | 695 __ Bind(&loop_condition); |
| 697 __ decq(RCX); | 696 __ decq(RCX); |
| 698 __ j(POSITIVE, &loop, Assembler::kNearJump); | 697 __ j(POSITIVE, &loop, Assembler::kNearJump); |
| 699 | 698 |
| 700 // Copy or initialize optional named arguments. | 699 // Copy or initialize optional named arguments. |
| 701 | |
| 702 if (!FLAG_reject_named_argument_as_positional) { | |
| 703 // Treat optional positional parameters as optional named parameters. | |
| 704 num_opt_named_params += num_opt_pos_params; | |
| 705 } | |
| 706 const Immediate raw_null = | 700 const Immediate raw_null = |
| 707 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 701 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 708 Label all_arguments_processed; | 702 Label all_arguments_processed; |
| 709 if (num_opt_named_params > 0) { | 703 if (num_opt_named_params > 0) { |
| 710 // Start by alphabetically sorting the names of the optional parameters. | 704 // Start by alphabetically sorting the names of the optional parameters. |
| 711 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; | 705 LocalVariable** opt_param = new LocalVariable*[num_opt_named_params]; |
| 712 int* opt_param_position = new int[num_opt_named_params]; | 706 int* opt_param_position = new int[num_opt_named_params]; |
| 713 for (int pos = num_fixed_params; pos < num_params; pos++) { | 707 for (int pos = num_fixed_params; pos < num_params; pos++) { |
| 714 LocalVariable* parameter = scope->VariableAt(pos); | 708 LocalVariable* parameter = scope->VariableAt(pos); |
| 715 const String& opt_param_name = parameter->name(); | 709 const String& opt_param_name = parameter->name(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 731 // Number of positional args is the second Smi in descriptor array (R10). | 725 // Number of positional args is the second Smi in descriptor array (R10). |
| 732 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); | 726 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); |
| 733 __ SmiUntag(RCX); | 727 __ SmiUntag(RCX); |
| 734 // Let RBX point to the first passed argument, i.e. to fp[1 + argc - 0]. | 728 // Let RBX point to the first passed argument, i.e. to fp[1 + argc - 0]. |
| 735 __ leaq(RBX, Address(RBP, RBX, TIMES_4, kWordSize)); // RBX is Smi. | 729 __ leaq(RBX, Address(RBP, RBX, TIMES_4, kWordSize)); // RBX is Smi. |
| 736 // Let EDI point to the name/pos pair of the first named argument. | 730 // Let EDI point to the name/pos pair of the first named argument. |
| 737 __ leaq(RDI, FieldAddress(R10, Array::data_offset() + (2 * kWordSize))); | 731 __ leaq(RDI, FieldAddress(R10, Array::data_offset() + (2 * kWordSize))); |
| 738 for (int i = 0; i < num_opt_named_params; i++) { | 732 for (int i = 0; i < num_opt_named_params; i++) { |
| 739 Label load_default_value, assign_optional_parameter, next_parameter; | 733 Label load_default_value, assign_optional_parameter, next_parameter; |
| 740 const int param_pos = opt_param_position[i]; | 734 const int param_pos = opt_param_position[i]; |
| 741 if (!FLAG_reject_named_argument_as_positional) { | |
| 742 // Handle this optional parameter only if k or fewer positional | |
| 743 // arguments have been passed, where k is the position of this optional | |
| 744 // parameter in the formal parameter list. | |
| 745 __ cmpq(RCX, Immediate(param_pos)); | |
| 746 __ j(GREATER, &next_parameter, Assembler::kNearJump); | |
| 747 } | |
| 748 // Check if this named parameter was passed in. | 735 // Check if this named parameter was passed in. |
| 749 __ movq(RAX, Address(RDI, 0)); // Load RAX with the name of the argument. | 736 __ movq(RAX, Address(RDI, 0)); // Load RAX with the name of the argument. |
| 750 ASSERT(opt_param[i]->name().IsSymbol()); | 737 ASSERT(opt_param[i]->name().IsSymbol()); |
| 751 __ CompareObject(RAX, opt_param[i]->name()); | 738 __ CompareObject(RAX, opt_param[i]->name()); |
| 752 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); | 739 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); |
| 753 // Load RAX with passed-in argument at provided arg_pos, i.e. at | 740 // Load RAX with passed-in argument at provided arg_pos, i.e. at |
| 754 // fp[1 + argc - arg_pos]. | 741 // fp[1 + argc - arg_pos]. |
| 755 __ movq(RAX, Address(RDI, kWordSize)); // RAX is arg_pos as Smi. | 742 __ movq(RAX, Address(RDI, kWordSize)); // RAX is arg_pos as Smi. |
| 756 __ addq(RDI, Immediate(2 * kWordSize)); // Point to next name/pos pair. | 743 __ addq(RDI, Immediate(2 * kWordSize)); // Point to next name/pos pair. |
| 757 __ negq(RAX); | 744 __ negq(RAX); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 774 const Address param_addr(RBP, (computed_param_pos * kWordSize)); | 761 const Address param_addr(RBP, (computed_param_pos * kWordSize)); |
| 775 __ movq(param_addr, RAX); | 762 __ movq(param_addr, RAX); |
| 776 __ Bind(&next_parameter); | 763 __ Bind(&next_parameter); |
| 777 } | 764 } |
| 778 delete[] opt_param; | 765 delete[] opt_param; |
| 779 delete[] opt_param_position; | 766 delete[] opt_param_position; |
| 780 // Check that RDI now points to the null terminator in the array descriptor. | 767 // Check that RDI now points to the null terminator in the array descriptor. |
| 781 __ cmpq(Address(RDI, 0), raw_null); | 768 __ cmpq(Address(RDI, 0), raw_null); |
| 782 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 769 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
| 783 } else if (num_opt_pos_params > 0) { | 770 } else if (num_opt_pos_params > 0) { |
| 784 ASSERT(FLAG_reject_named_argument_as_positional); | |
| 785 // Number of positional args is the second Smi in descriptor array (R10). | 771 // Number of positional args is the second Smi in descriptor array (R10). |
| 786 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); | 772 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); |
| 787 __ SmiUntag(RCX); | 773 __ SmiUntag(RCX); |
| 788 for (int i = 0; i < num_opt_pos_params; i++) { | 774 for (int i = 0; i < num_opt_pos_params; i++) { |
| 789 Label next_parameter; | 775 Label next_parameter; |
| 790 // Handle this optional positonal parameter only if k or fewer positional | 776 // Handle this optional positonal parameter only if k or fewer positional |
| 791 // arguments have been passed, where k is param_pos, the position of this | 777 // arguments have been passed, where k is param_pos, the position of this |
| 792 // optional parameter in the formal parameter list. | 778 // optional parameter in the formal parameter list. |
| 793 const int param_pos = num_fixed_params + i; | 779 const int param_pos = num_fixed_params + i; |
| 794 __ cmpq(RCX, Immediate(param_pos)); | 780 __ cmpq(RCX, Immediate(param_pos)); |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1363 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1378 __ Exchange(mem1, mem2); | 1364 __ Exchange(mem1, mem2); |
| 1379 } | 1365 } |
| 1380 | 1366 |
| 1381 | 1367 |
| 1382 #undef __ | 1368 #undef __ |
| 1383 | 1369 |
| 1384 } // namespace dart | 1370 } // namespace dart |
| 1385 | 1371 |
| 1386 #endif // defined TARGET_ARCH_X64 | 1372 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |