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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.cc

Issue 12663024: Implement optional parameter handling in ARM vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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) 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_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 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 opt_param_position[i + 1] = opt_param_position[i]; 729 opt_param_position[i + 1] = opt_param_position[i];
730 } 730 }
731 opt_param[i + 1] = parameter; 731 opt_param[i + 1] = parameter;
732 opt_param_position[i + 1] = pos; 732 opt_param_position[i + 1] = pos;
733 } 733 }
734 // Generate code handling each optional parameter in alphabetical order. 734 // Generate code handling each optional parameter in alphabetical order.
735 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 735 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
736 __ movl(ECX, 736 __ movl(ECX,
737 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); 737 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset()));
738 __ SmiUntag(ECX); 738 __ SmiUntag(ECX);
739 // Let EBX point to the first passed argument, i.e. to fp[1 + argc - 0]. 739 // Let EBX point to the first passed argument, i.e. to
740 __ leal(EBX, Address(EBP, EBX, TIMES_2, kWordSize)); // EBX is Smi. 740 // fp[kLastParamSlotIndex + num_args - 1 - 0]; num_args (EBX) is Smi.
741 __ leal(EBX,
742 Address(EBP, EBX, TIMES_2, (kLastParamSlotIndex - 1) * kWordSize));
741 // Let EDI point to the entry of the first named argument. 743 // Let EDI point to the entry of the first named argument.
742 __ leal(EDI, 744 __ leal(EDI,
743 FieldAddress(EDX, ArgumentsDescriptor::first_named_entry_offset())); 745 FieldAddress(EDX, ArgumentsDescriptor::first_named_entry_offset()));
744 for (int i = 0; i < num_opt_named_params; i++) { 746 for (int i = 0; i < num_opt_named_params; i++) {
745 Label load_default_value, assign_optional_parameter, next_parameter; 747 Label load_default_value, assign_optional_parameter, next_parameter;
746 const int param_pos = opt_param_position[i]; 748 const int param_pos = opt_param_position[i];
747 // Check if this named parameter was passed in. 749 // Check if this named parameter was passed in.
748 // Load EAX with the name of the argument. 750 // Load EAX with the name of the argument.
749 __ movl(EAX, Address(EDI, ArgumentsDescriptor::name_offset())); 751 __ movl(EAX, Address(EDI, ArgumentsDescriptor::name_offset()));
750 ASSERT(opt_param[i]->name().IsSymbol()); 752 ASSERT(opt_param[i]->name().IsSymbol());
751 __ CompareObject(EAX, opt_param[i]->name()); 753 __ CompareObject(EAX, opt_param[i]->name());
752 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump); 754 __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump);
753 // Load EAX with passed-in argument at provided arg_pos, i.e. at 755 // Load EAX with passed-in argument at provided arg_pos, i.e. at
754 // fp[1 + argc - arg_pos]. 756 // fp[kLastParamSlotIndex + num_args - 1 - arg_pos].
755 __ movl(EAX, Address(EDI, ArgumentsDescriptor::position_offset())); 757 __ movl(EAX, Address(EDI, ArgumentsDescriptor::position_offset()));
756 // EAX is arg_pos as Smi. 758 // EAX is arg_pos as Smi.
757 // Point to next named entry. 759 // Point to next named entry.
758 __ addl(EDI, Immediate(ArgumentsDescriptor::named_entry_size())); 760 __ addl(EDI, Immediate(ArgumentsDescriptor::named_entry_size()));
759 __ negl(EAX); 761 __ negl(EAX);
760 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi. 762 Address argument_addr(EBX, EAX, TIMES_2, 0); // EAX is a negative Smi.
761 __ movl(EAX, argument_addr); 763 __ movl(EAX, argument_addr);
762 __ jmp(&assign_optional_parameter, Assembler::kNearJump); 764 __ jmp(&assign_optional_parameter, Assembler::kNearJump);
763 __ Bind(&load_default_value); 765 __ Bind(&load_default_value);
764 // Load EAX with default argument. 766 // Load EAX with default argument.
765 const Object& value = Object::ZoneHandle( 767 const Object& value = Object::ZoneHandle(
766 parsed_function().default_parameter_values().At( 768 parsed_function().default_parameter_values().At(
767 param_pos - num_fixed_params)); 769 param_pos - num_fixed_params));
768 __ LoadObject(EAX, value); 770 __ LoadObject(EAX, value);
769 __ Bind(&assign_optional_parameter); 771 __ Bind(&assign_optional_parameter);
770 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. 772 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos].
771 // We do not use the final allocation index of the variable here, i.e. 773 // We do not use the final allocation index of the variable here, i.e.
772 // scope->VariableAt(i)->index(), because captured variables still need 774 // scope->VariableAt(i)->index(), because captured variables still need
773 // to be copied to the context that is not yet allocated. 775 // to be copied to the context that is not yet allocated.
774 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; 776 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
775 const Address param_addr(EBP, (computed_param_pos * kWordSize)); 777 const Address param_addr(EBP, computed_param_pos * kWordSize);
776 __ movl(param_addr, EAX); 778 __ movl(param_addr, EAX);
777 __ Bind(&next_parameter); 779 __ Bind(&next_parameter);
778 } 780 }
779 delete[] opt_param; 781 delete[] opt_param;
780 delete[] opt_param_position; 782 delete[] opt_param_position;
781 // Check that EDI now points to the null terminator in the array descriptor. 783 // Check that EDI now points to the null terminator in the array descriptor.
782 __ cmpl(Address(EDI, 0), raw_null); 784 __ cmpl(Address(EDI, 0), raw_null);
783 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 785 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
784 } else { 786 } else {
785 ASSERT(num_opt_pos_params > 0); 787 ASSERT(num_opt_pos_params > 0);
786 __ movl(ECX, 788 __ movl(ECX,
787 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); 789 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset()));
788 __ SmiUntag(ECX); 790 __ SmiUntag(ECX);
789 for (int i = 0; i < num_opt_pos_params; i++) { 791 for (int i = 0; i < num_opt_pos_params; i++) {
790 Label next_parameter; 792 Label next_parameter;
791 // Handle this optional positonal parameter only if k or fewer positional 793 // Handle this optional positional parameter only if k or fewer positional
792 // arguments have been passed, where k is param_pos, the position of this 794 // arguments have been passed, where k is param_pos, the position of this
793 // optional parameter in the formal parameter list. 795 // optional parameter in the formal parameter list.
794 const int param_pos = num_fixed_params + i; 796 const int param_pos = num_fixed_params + i;
795 __ cmpl(ECX, Immediate(param_pos)); 797 __ cmpl(ECX, Immediate(param_pos));
796 __ j(GREATER, &next_parameter, Assembler::kNearJump); 798 __ j(GREATER, &next_parameter, Assembler::kNearJump);
797 // Load RAX with default argument. 799 // Load EAX with default argument.
798 const Object& value = Object::ZoneHandle( 800 const Object& value = Object::ZoneHandle(
799 parsed_function().default_parameter_values().At(i)); 801 parsed_function().default_parameter_values().At(i));
800 __ LoadObject(EAX, value); 802 __ LoadObject(EAX, value);
801 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. 803 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos].
802 // We do not use the final allocation index of the variable here, i.e. 804 // We do not use the final allocation index of the variable here, i.e.
803 // scope->VariableAt(i)->index(), because captured variables still need 805 // scope->VariableAt(i)->index(), because captured variables still need
804 // to be copied to the context that is not yet allocated. 806 // to be copied to the context that is not yet allocated.
805 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; 807 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
806 const Address param_addr(EBP, (computed_param_pos * kWordSize)); 808 const Address param_addr(EBP, computed_param_pos * kWordSize);
807 __ movl(param_addr, EAX); 809 __ movl(param_addr, EAX);
808 __ Bind(&next_parameter); 810 __ Bind(&next_parameter);
809 } 811 }
810 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 812 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
811 __ SmiUntag(EBX); 813 __ SmiUntag(EBX);
812 // Check that ECX equals EBX, i.e. no named arguments passed. 814 // Check that ECX equals EBX, i.e. no named arguments passed.
813 __ cmpl(ECX, EBX); 815 __ cmpl(ECX, EBX);
814 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 816 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
815 } 817 }
816 818
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // checked, otherwise noSuchMethod would not see their original values. 857 // checked, otherwise noSuchMethod would not see their original values.
856 // This step can be skipped in case we decide that formal parameters are 858 // This step can be skipped in case we decide that formal parameters are
857 // implicitly final, since garbage collecting the unmodified value is not 859 // implicitly final, since garbage collecting the unmodified value is not
858 // an issue anymore. 860 // an issue anymore.
859 861
860 // EDX : arguments descriptor array. 862 // EDX : arguments descriptor array.
861 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 863 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
862 __ SmiUntag(ECX); 864 __ SmiUntag(ECX);
863 Label null_args_loop, null_args_loop_condition; 865 Label null_args_loop, null_args_loop_condition;
864 __ jmp(&null_args_loop_condition, Assembler::kNearJump); 866 __ jmp(&null_args_loop_condition, Assembler::kNearJump);
865 const Address original_argument_addr(EBP, ECX, TIMES_4, 2 * kWordSize); 867 const Address original_argument_addr(
868 EBP, ECX, TIMES_4, kLastParamSlotIndex * kWordSize);
866 __ Bind(&null_args_loop); 869 __ Bind(&null_args_loop);
867 __ movl(original_argument_addr, raw_null); 870 __ movl(original_argument_addr, raw_null);
868 __ Bind(&null_args_loop_condition); 871 __ Bind(&null_args_loop_condition);
869 __ decl(ECX); 872 __ decl(ECX);
870 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); 873 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump);
871 } 874 }
872 875
873 876
874 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { 877 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
875 // TOS: return address. 878 // TOS: return address.
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 __ popl(ECX); 1717 __ popl(ECX);
1715 __ popl(EAX); 1718 __ popl(EAX);
1716 } 1719 }
1717 1720
1718 1721
1719 #undef __ 1722 #undef __
1720 1723
1721 } // namespace dart 1724 } // namespace dart
1722 1725
1723 #endif // defined TARGET_ARCH_IA32 1726 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698