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

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
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
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);
778 } 779 }
779 delete[] opt_param; 780 delete[] opt_param;
780 delete[] opt_param_position; 781 delete[] opt_param_position;
781 // Check that EDI now points to the null terminator in the array descriptor. 782 // Check that EDI now points to the null terminator in the array descriptor.
782 __ cmpl(Address(EDI, 0), raw_null); 783 __ cmpl(Address(EDI, 0), raw_null);
783 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 784 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
784 } else { 785 } else {
785 ASSERT(num_opt_pos_params > 0); 786 ASSERT(num_opt_pos_params > 0);
786 __ movl(ECX, 787 __ movl(ECX,
787 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset())); 788 FieldAddress(EDX, ArgumentsDescriptor::positional_count_offset()));
788 __ SmiUntag(ECX); 789 __ SmiUntag(ECX);
789 for (int i = 0; i < num_opt_pos_params; i++) { 790 for (int i = 0; i < num_opt_pos_params; i++) {
790 Label next_parameter; 791 Label next_parameter;
791 // Handle this optional positonal parameter only if k or fewer positional 792 // 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 793 // arguments have been passed, where k is param_pos, the position of this
793 // optional parameter in the formal parameter list. 794 // optional parameter in the formal parameter list.
794 const int param_pos = num_fixed_params + i; 795 const int param_pos = num_fixed_params + i;
795 __ cmpl(ECX, Immediate(param_pos)); 796 __ cmpl(ECX, Immediate(param_pos));
796 __ j(GREATER, &next_parameter, Assembler::kNearJump); 797 __ j(GREATER, &next_parameter, Assembler::kNearJump);
797 // Load RAX with default argument. 798 // Load EAX with default argument.
798 const Object& value = Object::ZoneHandle( 799 const Object& value = Object::ZoneHandle(
799 parsed_function().default_parameter_values().At(i)); 800 parsed_function().default_parameter_values().At(i));
800 __ LoadObject(EAX, value); 801 __ LoadObject(EAX, value);
801 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos]. 802 // Assign EAX to fp[kFirstLocalSlotIndex - param_pos].
802 // We do not use the final allocation index of the variable here, i.e. 803 // We do not use the final allocation index of the variable here, i.e.
803 // scope->VariableAt(i)->index(), because captured variables still need 804 // scope->VariableAt(i)->index(), because captured variables still need
804 // to be copied to the context that is not yet allocated. 805 // to be copied to the context that is not yet allocated.
805 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos; 806 const intptr_t computed_param_pos = kFirstLocalSlotIndex - param_pos;
806 const Address param_addr(EBP, (computed_param_pos * kWordSize)); 807 const Address param_addr(EBP, computed_param_pos * kWordSize);
807 __ movl(param_addr, EAX); 808 __ movl(param_addr, EAX);
808 __ Bind(&next_parameter); 809 __ Bind(&next_parameter);
809 } 810 }
810 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 811 __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
811 __ SmiUntag(EBX); 812 __ SmiUntag(EBX);
812 // Check that ECX equals EBX, i.e. no named arguments passed. 813 // Check that ECX equals EBX, i.e. no named arguments passed.
813 __ cmpl(ECX, EBX); 814 __ cmpl(ECX, EBX);
814 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 815 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
815 } 816 }
816 817
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // checked, otherwise noSuchMethod would not see their original values. 856 // checked, otherwise noSuchMethod would not see their original values.
856 // This step can be skipped in case we decide that formal parameters are 857 // This step can be skipped in case we decide that formal parameters are
857 // implicitly final, since garbage collecting the unmodified value is not 858 // implicitly final, since garbage collecting the unmodified value is not
858 // an issue anymore. 859 // an issue anymore.
859 860
860 // EDX : arguments descriptor array. 861 // EDX : arguments descriptor array.
861 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 862 __ movl(ECX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
862 __ SmiUntag(ECX); 863 __ SmiUntag(ECX);
863 Label null_args_loop, null_args_loop_condition; 864 Label null_args_loop, null_args_loop_condition;
864 __ jmp(&null_args_loop_condition, Assembler::kNearJump); 865 __ jmp(&null_args_loop_condition, Assembler::kNearJump);
865 const Address original_argument_addr(EBP, ECX, TIMES_4, 2 * kWordSize); 866 const Address original_argument_addr(
867 EBP, ECX, TIMES_4, kLastParamSlotIndex * kWordSize);
866 __ Bind(&null_args_loop); 868 __ Bind(&null_args_loop);
867 __ movl(original_argument_addr, raw_null); 869 __ movl(original_argument_addr, raw_null);
868 __ Bind(&null_args_loop_condition); 870 __ Bind(&null_args_loop_condition);
869 __ decl(ECX); 871 __ decl(ECX);
870 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump); 872 __ j(POSITIVE, &null_args_loop, Assembler::kNearJump);
871 } 873 }
872 874
873 875
874 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { 876 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
875 // TOS: return address. 877 // TOS: return address.
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 __ popl(ECX); 1717 __ popl(ECX);
1716 __ popl(EAX); 1718 __ popl(EAX);
1717 } 1719 }
1718 1720
1719 1721
1720 #undef __ 1722 #undef __
1721 1723
1722 } // namespace dart 1724 } // namespace dart
1723 1725
1724 #endif // defined TARGET_ARCH_IA32 1726 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698