| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 opt_param_position[i + 1] = opt_param_position[i]; | 727 opt_param_position[i + 1] = opt_param_position[i]; |
| 728 } | 728 } |
| 729 opt_param[i + 1] = parameter; | 729 opt_param[i + 1] = parameter; |
| 730 opt_param_position[i + 1] = pos; | 730 opt_param_position[i + 1] = pos; |
| 731 } | 731 } |
| 732 // Generate code handling each optional parameter in alphabetical order. | 732 // Generate code handling each optional parameter in alphabetical order. |
| 733 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 733 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 734 __ movq(RCX, | 734 __ movq(RCX, |
| 735 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset())); | 735 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset())); |
| 736 __ SmiUntag(RCX); | 736 __ SmiUntag(RCX); |
| 737 // Let RBX point to the first passed argument, i.e. to fp[1 + argc - 0]. | 737 // Let RBX point to the first passed argument, i.e. to |
| 738 __ leaq(RBX, Address(RBP, RBX, TIMES_4, kWordSize)); // RBX is Smi. | 738 // fp[kLastParamSlotIndex + num_args - 1]; num_args (RBX) is Smi. |
| 739 __ leaq(RBX, |
| 740 Address(RBP, RBX, TIMES_4, (kLastParamSlotIndex - 1) * kWordSize)); |
| 739 // Let RDI point to the entry of the first named argument. | 741 // Let RDI point to the entry of the first named argument. |
| 740 __ leaq(RDI, | 742 __ leaq(RDI, |
| 741 FieldAddress(R10, ArgumentsDescriptor::first_named_entry_offset())); | 743 FieldAddress(R10, ArgumentsDescriptor::first_named_entry_offset())); |
| 742 for (int i = 0; i < num_opt_named_params; i++) { | 744 for (int i = 0; i < num_opt_named_params; i++) { |
| 743 Label load_default_value, assign_optional_parameter, next_parameter; | 745 Label load_default_value, assign_optional_parameter; |
| 744 const int param_pos = opt_param_position[i]; | 746 const int param_pos = opt_param_position[i]; |
| 745 // Check if this named parameter was passed in. | 747 // Check if this named parameter was passed in. |
| 746 // Load RAX with the name of the argument. | 748 // Load RAX with the name of the argument. |
| 747 __ movq(RAX, Address(RDI, ArgumentsDescriptor::name_offset())); | 749 __ movq(RAX, Address(RDI, ArgumentsDescriptor::name_offset())); |
| 748 ASSERT(opt_param[i]->name().IsSymbol()); | 750 ASSERT(opt_param[i]->name().IsSymbol()); |
| 749 __ CompareObject(RAX, opt_param[i]->name()); | 751 __ CompareObject(RAX, opt_param[i]->name()); |
| 750 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); | 752 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); |
| 751 // Load RAX with passed-in argument at provided arg_pos, i.e. at | 753 // Load RAX with passed-in argument at provided arg_pos, i.e. at |
| 752 // fp[1 + argc - arg_pos]. | 754 // fp[kLastParamSlotIndex + num_args - 1 - arg_pos]. |
| 753 __ movq(RAX, Address(RDI, ArgumentsDescriptor::position_offset())); | 755 __ movq(RAX, Address(RDI, ArgumentsDescriptor::position_offset())); |
| 754 // RAX is arg_pos as Smi. | 756 // RAX is arg_pos as Smi. |
| 755 // Point to next named entry. | 757 // Point to next named entry. |
| 756 __ addq(RDI, Immediate(ArgumentsDescriptor::named_entry_size())); | 758 __ addq(RDI, Immediate(ArgumentsDescriptor::named_entry_size())); |
| 757 __ negq(RAX); | 759 __ negq(RAX); |
| 758 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi. | 760 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi. |
| 759 __ movq(RAX, argument_addr); | 761 __ movq(RAX, argument_addr); |
| 760 __ jmp(&assign_optional_parameter, Assembler::kNearJump); | 762 __ jmp(&assign_optional_parameter, Assembler::kNearJump); |
| 761 __ Bind(&load_default_value); | 763 __ Bind(&load_default_value); |
| 762 // Load RAX with default argument. | 764 // Load RAX with default argument. |
| 763 const Object& value = Object::ZoneHandle( | 765 const Object& value = Object::ZoneHandle( |
| 764 parsed_function().default_parameter_values().At( | 766 parsed_function().default_parameter_values().At( |
| 765 param_pos - num_fixed_params)); | 767 param_pos - num_fixed_params)); |
| 766 __ LoadObject(RAX, value); | 768 __ LoadObject(RAX, value); |
| 767 __ Bind(&assign_optional_parameter); | 769 __ Bind(&assign_optional_parameter); |
| 768 // Assign RAX to fp[kFirstLocalSlotIndex - param_pos]. | 770 // Assign RAX to fp[kFirstLocalSlotIndex - param_pos]. |
| 769 // We do not use the final allocation index of the variable here, i.e. | 771 // We do not use the final allocation index of the variable here, i.e. |
| 770 // scope->VariableAt(i)->index(), because captured variables still need | 772 // scope->VariableAt(i)->index(), because captured variables still need |
| 771 // to be copied to the context that is not yet allocated. | 773 // to be copied to the context that is not yet allocated. |
| 772 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; | 774 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; |
| 773 const Address param_addr(RBP, (computed_param_pos * kWordSize)); | 775 const Address param_addr(RBP, computed_param_pos * kWordSize); |
| 774 __ movq(param_addr, RAX); | 776 __ movq(param_addr, RAX); |
| 775 __ Bind(&next_parameter); | |
| 776 } | 777 } |
| 777 delete[] opt_param; | 778 delete[] opt_param; |
| 778 delete[] opt_param_position; | 779 delete[] opt_param_position; |
| 779 // Check that RDI now points to the null terminator in the array descriptor. | 780 // Check that RDI now points to the null terminator in the array descriptor. |
| 780 __ cmpq(Address(RDI, 0), raw_null); | 781 __ cmpq(Address(RDI, 0), raw_null); |
| 781 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 782 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
| 782 } else { | 783 } else { |
| 783 ASSERT(num_opt_pos_params > 0); | 784 ASSERT(num_opt_pos_params > 0); |
| 784 __ movq(RCX, | 785 __ movq(RCX, |
| 785 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset())); | 786 FieldAddress(R10, ArgumentsDescriptor::positional_count_offset())); |
| 786 __ SmiUntag(RCX); | 787 __ SmiUntag(RCX); |
| 787 for (int i = 0; i < num_opt_pos_params; i++) { | 788 for (int i = 0; i < num_opt_pos_params; i++) { |
| 788 Label next_parameter; | 789 Label next_parameter; |
| 789 // Handle this optional positonal parameter only if k or fewer positional | 790 // Handle this optional positional parameter only if k or fewer positional |
| 790 // arguments have been passed, where k is param_pos, the position of this | 791 // arguments have been passed, where k is param_pos, the position of this |
| 791 // optional parameter in the formal parameter list. | 792 // optional parameter in the formal parameter list. |
| 792 const int param_pos = num_fixed_params + i; | 793 const int param_pos = num_fixed_params + i; |
| 793 __ cmpq(RCX, Immediate(param_pos)); | 794 __ cmpq(RCX, Immediate(param_pos)); |
| 794 __ j(GREATER, &next_parameter, Assembler::kNearJump); | 795 __ j(GREATER, &next_parameter, Assembler::kNearJump); |
| 795 // Load RAX with default argument. | 796 // Load RAX with default argument. |
| 796 const Object& value = Object::ZoneHandle( | 797 const Object& value = Object::ZoneHandle( |
| 797 parsed_function().default_parameter_values().At(i)); | 798 parsed_function().default_parameter_values().At(i)); |
| 798 __ LoadObject(RAX, value); | 799 __ LoadObject(RAX, value); |
| 799 // Assign RAX to fp[kFirstLocalSlotIndex - param_pos]. | 800 // Assign RAX to fp[kFirstLocalSlotIndex - param_pos]. |
| 800 // We do not use the final allocation index of the variable here, i.e. | 801 // We do not use the final allocation index of the variable here, i.e. |
| 801 // scope->VariableAt(i)->index(), because captured variables still need | 802 // scope->VariableAt(i)->index(), because captured variables still need |
| 802 // to be copied to the context that is not yet allocated. | 803 // to be copied to the context that is not yet allocated. |
| 803 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; | 804 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; |
| 804 const Address param_addr(RBP, (computed_param_pos * kWordSize)); | 805 const Address param_addr(RBP, computed_param_pos * kWordSize); |
| 805 __ movq(param_addr, RAX); | 806 __ movq(param_addr, RAX); |
| 806 __ Bind(&next_parameter); | 807 __ Bind(&next_parameter); |
| 807 } | 808 } |
| 808 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 809 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 809 __ SmiUntag(RBX); | 810 __ SmiUntag(RBX); |
| 810 // Check that RCX equals RBX, i.e. no named arguments passed. | 811 // Check that RCX equals RBX, i.e. no named arguments passed. |
| 811 __ cmpq(RCX, RBX); | 812 __ cmpq(RCX, RBX); |
| 812 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); | 813 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); |
| 813 } | 814 } |
| 814 | 815 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 // checked, otherwise noSuchMethod would not see their original values. | 854 // checked, otherwise noSuchMethod would not see their original values. |
| 854 // This step can be skipped in case we decide that formal parameters are | 855 // This step can be skipped in case we decide that formal parameters are |
| 855 // implicitly final, since garbage collecting the unmodified value is not | 856 // implicitly final, since garbage collecting the unmodified value is not |
| 856 // an issue anymore. | 857 // an issue anymore. |
| 857 | 858 |
| 858 // R10 : arguments descriptor array. | 859 // R10 : arguments descriptor array. |
| 859 __ movq(RCX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 860 __ movq(RCX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 860 __ SmiUntag(RCX); | 861 __ SmiUntag(RCX); |
| 861 Label null_args_loop, null_args_loop_condition; | 862 Label null_args_loop, null_args_loop_condition; |
| 862 __ jmp(&null_args_loop_condition, Assembler::kNearJump); | 863 __ jmp(&null_args_loop_condition, Assembler::kNearJump); |
| 863 const Address original_argument_addr(RBP, RCX, TIMES_8, 2 * kWordSize); | 864 const Address original_argument_addr( |
| 865 RBP, RCX, TIMES_8, kLastParamSlotIndex * kWordSize); |
| 864 __ Bind(&null_args_loop); | 866 __ Bind(&null_args_loop); |
| 865 __ movq(original_argument_addr, raw_null); | 867 __ movq(original_argument_addr, raw_null); |
| 866 __ Bind(&null_args_loop_condition); | 868 __ Bind(&null_args_loop_condition); |
| 867 __ decq(RCX); | 869 __ decq(RCX); |
| 868 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); | 870 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); |
| 869 } | 871 } |
| 870 | 872 |
| 871 | 873 |
| 872 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { | 874 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { |
| 873 // TOS: return address. | 875 // TOS: return address. |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1691 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1690 __ Exchange(mem1, mem2); | 1692 __ Exchange(mem1, mem2); |
| 1691 } | 1693 } |
| 1692 | 1694 |
| 1693 | 1695 |
| 1694 #undef __ | 1696 #undef __ |
| 1695 | 1697 |
| 1696 } // namespace dart | 1698 } // namespace dart |
| 1697 | 1699 |
| 1698 #endif // defined TARGET_ARCH_X64 | 1700 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |