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

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

Issue 1156593002: Cache current thread in a reserved register and use it in LoadIsolate (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address review comments. Created 5 years, 6 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
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 const int num_params = 757 const int num_params =
758 num_fixed_params + num_opt_pos_params + num_opt_named_params; 758 num_fixed_params + num_opt_pos_params + num_opt_named_params;
759 ASSERT(function.NumParameters() == num_params); 759 ASSERT(function.NumParameters() == num_params);
760 ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotFromFp); 760 ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotFromFp);
761 761
762 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args, 762 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
763 // where num_pos_args is the number of positional arguments passed in. 763 // where num_pos_args is the number of positional arguments passed in.
764 const int min_num_pos_args = num_fixed_params; 764 const int min_num_pos_args = num_fixed_params;
765 const int max_num_pos_args = num_fixed_params + num_opt_pos_params; 765 const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
766 766
767 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset())); 767 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
768 // Check that min_num_pos_args <= num_pos_args. 768 // Check that min_num_pos_args <= num_pos_args.
769 Label wrong_num_arguments; 769 Label wrong_num_arguments;
770 __ CompareImmediate(R8, Smi::RawValue(min_num_pos_args)); 770 __ CompareImmediate(R9, Smi::RawValue(min_num_pos_args));
771 __ b(&wrong_num_arguments, LT); 771 __ b(&wrong_num_arguments, LT);
772 // Check that num_pos_args <= max_num_pos_args. 772 // Check that num_pos_args <= max_num_pos_args.
773 __ CompareImmediate(R8, Smi::RawValue(max_num_pos_args)); 773 __ CompareImmediate(R9, Smi::RawValue(max_num_pos_args));
774 __ b(&wrong_num_arguments, GT); 774 __ b(&wrong_num_arguments, GT);
775 775
776 // Copy positional arguments. 776 // Copy positional arguments.
777 // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied 777 // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied
778 // to fp[kFirstLocalSlotFromFp - i]. 778 // to fp[kFirstLocalSlotFromFp - i].
779 779
780 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 780 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
781 // Since R7 and R8 are Smi, use LSL 1 instead of LSL 2. 781 // Since R7 and R9 are Smi, use LSL 1 instead of LSL 2.
782 // Let R7 point to the last passed positional argument, i.e. to 782 // Let R7 point to the last passed positional argument, i.e. to
783 // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)]. 783 // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)].
784 __ sub(R7, R7, Operand(R8)); 784 __ sub(R7, R7, Operand(R9));
785 __ add(R7, FP, Operand(R7, LSL, 1)); 785 __ add(R7, FP, Operand(R7, LSL, 1));
786 __ add(R7, R7, Operand((kParamEndSlotFromFp + 1) * kWordSize)); 786 __ add(R7, R7, Operand((kParamEndSlotFromFp + 1) * kWordSize));
787 787
788 // Let R6 point to the last copied positional argument, i.e. to 788 // Let R6 point to the last copied positional argument, i.e. to
789 // fp[kFirstLocalSlotFromFp - (num_pos_args - 1)]. 789 // fp[kFirstLocalSlotFromFp - (num_pos_args - 1)].
790 __ AddImmediate(R6, FP, (kFirstLocalSlotFromFp + 1) * kWordSize); 790 __ AddImmediate(R6, FP, (kFirstLocalSlotFromFp + 1) * kWordSize);
791 __ sub(R6, R6, Operand(R8, LSL, 1)); // R8 is a Smi. 791 __ sub(R6, R6, Operand(R9, LSL, 1)); // R9 is a Smi.
792 __ SmiUntag(R8); 792 __ SmiUntag(R9);
793 Label loop, loop_condition; 793 Label loop, loop_condition;
794 __ b(&loop_condition); 794 __ b(&loop_condition);
795 // We do not use the final allocation index of the variable here, i.e. 795 // We do not use the final allocation index of the variable here, i.e.
796 // scope->VariableAt(i)->index(), because captured variables still need 796 // scope->VariableAt(i)->index(), because captured variables still need
797 // to be copied to the context that is not yet allocated. 797 // to be copied to the context that is not yet allocated.
798 const Address argument_addr(R7, R8, LSL, 2); 798 const Address argument_addr(R7, R9, LSL, 2);
799 const Address copy_addr(R6, R8, LSL, 2); 799 const Address copy_addr(R6, R9, LSL, 2);
800 __ Bind(&loop); 800 __ Bind(&loop);
801 __ ldr(IP, argument_addr); 801 __ ldr(IP, argument_addr);
802 __ str(IP, copy_addr); 802 __ str(IP, copy_addr);
803 __ Bind(&loop_condition); 803 __ Bind(&loop_condition);
804 __ subs(R8, R8, Operand(1)); 804 __ subs(R9, R9, Operand(1));
805 __ b(&loop, PL); 805 __ b(&loop, PL);
806 806
807 // Copy or initialize optional named arguments. 807 // Copy or initialize optional named arguments.
808 Label all_arguments_processed; 808 Label all_arguments_processed;
809 #ifdef DEBUG 809 #ifdef DEBUG
810 const bool check_correct_named_args = true; 810 const bool check_correct_named_args = true;
811 #else 811 #else
812 const bool check_correct_named_args = function.IsClosureFunction(); 812 const bool check_correct_named_args = function.IsClosureFunction();
813 #endif 813 #endif
814 if (num_opt_named_params > 0) { 814 if (num_opt_named_params > 0) {
(...skipping 10 matching lines...) Expand all
825 ASSERT(result != 0); 825 ASSERT(result != 0);
826 if (result > 0) break; 826 if (result > 0) break;
827 opt_param[i + 1] = opt_param[i]; 827 opt_param[i + 1] = opt_param[i];
828 opt_param_position[i + 1] = opt_param_position[i]; 828 opt_param_position[i + 1] = opt_param_position[i];
829 } 829 }
830 opt_param[i + 1] = parameter; 830 opt_param[i + 1] = parameter;
831 opt_param_position[i + 1] = pos; 831 opt_param_position[i + 1] = pos;
832 } 832 }
833 // Generate code handling each optional parameter in alphabetical order. 833 // Generate code handling each optional parameter in alphabetical order.
834 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 834 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
835 __ ldr(R8, 835 __ ldr(R9,
836 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset())); 836 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
837 __ SmiUntag(R8); 837 __ SmiUntag(R9);
838 // Let R7 point to the first passed argument, i.e. to 838 // Let R7 point to the first passed argument, i.e. to
839 // fp[kParamEndSlotFromFp + num_args - 0]; num_args (R7) is Smi. 839 // fp[kParamEndSlotFromFp + num_args - 0]; num_args (R7) is Smi.
840 __ add(R7, FP, Operand(R7, LSL, 1)); 840 __ add(R7, FP, Operand(R7, LSL, 1));
841 __ AddImmediate(R7, R7, kParamEndSlotFromFp * kWordSize); 841 __ AddImmediate(R7, R7, kParamEndSlotFromFp * kWordSize);
842 // Let R6 point to the entry of the first named argument. 842 // Let R6 point to the entry of the first named argument.
843 __ add(R6, R4, Operand( 843 __ add(R6, R4, Operand(
844 ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag)); 844 ArgumentsDescriptor::first_named_entry_offset() - kHeapObjectTag));
845 for (int i = 0; i < num_opt_named_params; i++) { 845 for (int i = 0; i < num_opt_named_params; i++) {
846 Label load_default_value, assign_optional_parameter; 846 Label load_default_value, assign_optional_parameter;
847 const int param_pos = opt_param_position[i]; 847 const int param_pos = opt_param_position[i];
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 delete[] opt_param_position; 880 delete[] opt_param_position;
881 if (check_correct_named_args) { 881 if (check_correct_named_args) {
882 // Check that R6 now points to the null terminator in the arguments 882 // Check that R6 now points to the null terminator in the arguments
883 // descriptor. 883 // descriptor.
884 __ ldr(R5, Address(R6, 0)); 884 __ ldr(R5, Address(R6, 0));
885 __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null())); 885 __ CompareImmediate(R5, reinterpret_cast<int32_t>(Object::null()));
886 __ b(&all_arguments_processed, EQ); 886 __ b(&all_arguments_processed, EQ);
887 } 887 }
888 } else { 888 } else {
889 ASSERT(num_opt_pos_params > 0); 889 ASSERT(num_opt_pos_params > 0);
890 __ ldr(R8, 890 __ ldr(R9,
891 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset())); 891 FieldAddress(R4, ArgumentsDescriptor::positional_count_offset()));
892 __ SmiUntag(R8); 892 __ SmiUntag(R9);
893 for (int i = 0; i < num_opt_pos_params; i++) { 893 for (int i = 0; i < num_opt_pos_params; i++) {
894 Label next_parameter; 894 Label next_parameter;
895 // Handle this optional positional parameter only if k or fewer positional 895 // Handle this optional positional parameter only if k or fewer positional
896 // arguments have been passed, where k is param_pos, the position of this 896 // arguments have been passed, where k is param_pos, the position of this
897 // optional parameter in the formal parameter list. 897 // optional parameter in the formal parameter list.
898 const int param_pos = num_fixed_params + i; 898 const int param_pos = num_fixed_params + i;
899 __ CompareImmediate(R8, param_pos); 899 __ CompareImmediate(R9, param_pos);
900 __ b(&next_parameter, GT); 900 __ b(&next_parameter, GT);
901 // Load R5 with default argument. 901 // Load R5 with default argument.
902 const Object& value = Object::ZoneHandle( 902 const Object& value = Object::ZoneHandle(
903 parsed_function().default_parameter_values().At(i)); 903 parsed_function().default_parameter_values().At(i));
904 __ LoadObject(R5, value); 904 __ LoadObject(R5, value);
905 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos]. 905 // Assign R5 to fp[kFirstLocalSlotFromFp - param_pos].
906 // We do not use the final allocation index of the variable here, i.e. 906 // We do not use the final allocation index of the variable here, i.e.
907 // scope->VariableAt(i)->index(), because captured variables still need 907 // scope->VariableAt(i)->index(), because captured variables still need
908 // to be copied to the context that is not yet allocated. 908 // to be copied to the context that is not yet allocated.
909 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 909 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
910 const Address param_addr(FP, computed_param_pos * kWordSize); 910 const Address param_addr(FP, computed_param_pos * kWordSize);
911 __ str(R5, param_addr); 911 __ str(R5, param_addr);
912 __ Bind(&next_parameter); 912 __ Bind(&next_parameter);
913 } 913 }
914 if (check_correct_named_args) { 914 if (check_correct_named_args) {
915 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 915 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
916 __ SmiUntag(R7); 916 __ SmiUntag(R7);
917 // Check that R8 equals R7, i.e. no named arguments passed. 917 // Check that R9 equals R7, i.e. no named arguments passed.
918 __ cmp(R8, Operand(R7)); 918 __ cmp(R9, Operand(R7));
919 __ b(&all_arguments_processed, EQ); 919 __ b(&all_arguments_processed, EQ);
920 } 920 }
921 } 921 }
922 922
923 __ Bind(&wrong_num_arguments); 923 __ Bind(&wrong_num_arguments);
924 if (function.IsClosureFunction()) { 924 if (function.IsClosureFunction()) {
925 __ LeaveDartFrame(); // The arguments are still on the stack. 925 __ LeaveDartFrame(); // The arguments are still on the stack.
926 __ Branch(&isolate()->stub_code()->CallClosureNoSuchMethodLabel()); 926 __ Branch(&isolate()->stub_code()->CallClosureNoSuchMethodLabel());
927 // The noSuchMethod call may return to the caller, but not here. 927 // The noSuchMethod call may return to the caller, but not here.
928 } else if (check_correct_named_args) { 928 } else if (check_correct_named_args) {
929 __ Stop("Wrong arguments"); 929 __ Stop("Wrong arguments");
930 } 930 }
931 931
932 __ Bind(&all_arguments_processed); 932 __ Bind(&all_arguments_processed);
933 // Nullify originally passed arguments only after they have been copied and 933 // Nullify originally passed arguments only after they have been copied and
934 // checked, otherwise noSuchMethod would not see their original values. 934 // checked, otherwise noSuchMethod would not see their original values.
935 // This step can be skipped in case we decide that formal parameters are 935 // This step can be skipped in case we decide that formal parameters are
936 // implicitly final, since garbage collecting the unmodified value is not 936 // implicitly final, since garbage collecting the unmodified value is not
937 // an issue anymore. 937 // an issue anymore.
938 938
939 // R4 : arguments descriptor array. 939 // R4 : arguments descriptor array.
940 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 940 __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
941 __ SmiUntag(R8); 941 __ SmiUntag(R9);
942 __ add(R7, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize)); 942 __ add(R7, FP, Operand((kParamEndSlotFromFp + 1) * kWordSize));
943 const Address original_argument_addr(R7, R8, LSL, 2); 943 const Address original_argument_addr(R7, R9, LSL, 2);
944 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 944 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
945 Label null_args_loop, null_args_loop_condition; 945 Label null_args_loop, null_args_loop_condition;
946 __ b(&null_args_loop_condition); 946 __ b(&null_args_loop_condition);
947 __ Bind(&null_args_loop); 947 __ Bind(&null_args_loop);
948 __ str(IP, original_argument_addr); 948 __ str(IP, original_argument_addr);
949 __ Bind(&null_args_loop_condition); 949 __ Bind(&null_args_loop_condition);
950 __ subs(R8, R8, Operand(1)); 950 __ subs(R9, R9, Operand(1));
951 __ b(&null_args_loop, PL); 951 __ b(&null_args_loop, PL);
952 } 952 }
953 953
954 954
955 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { 955 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
956 // LR: return address. 956 // LR: return address.
957 // SP: receiver. 957 // SP: receiver.
958 // Sequence node has one return node, its input is load field node. 958 // Sequence node has one return node, its input is load field node.
959 __ Comment("Inlined Getter"); 959 __ Comment("Inlined Getter");
960 __ ldr(R0, Address(SP, 0 * kWordSize)); 960 __ ldr(R0, Address(SP, 0 * kWordSize));
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 DRegister dreg = EvenDRegisterOf(reg); 1857 DRegister dreg = EvenDRegisterOf(reg);
1858 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1858 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1859 } 1859 }
1860 1860
1861 1861
1862 #undef __ 1862 #undef __
1863 1863
1864 } // namespace dart 1864 } // namespace dart
1865 1865
1866 #endif // defined TARGET_ARCH_ARM 1866 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698