| 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_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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 __ Bind(&next_parameter); | 887 __ Bind(&next_parameter); |
| 888 } | 888 } |
| 889 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 889 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 890 __ SmiUntag(R7); | 890 __ SmiUntag(R7); |
| 891 // Check that R8 equals R7, i.e. no named arguments passed. | 891 // Check that R8 equals R7, i.e. no named arguments passed. |
| 892 __ cmp(R8, ShifterOperand(R7)); | 892 __ cmp(R8, ShifterOperand(R7)); |
| 893 __ b(&all_arguments_processed, EQ); | 893 __ b(&all_arguments_processed, EQ); |
| 894 } | 894 } |
| 895 | 895 |
| 896 __ Bind(&wrong_num_arguments); | 896 __ Bind(&wrong_num_arguments); |
| 897 if (StackSize() != 0) { | |
| 898 // We need to unwind the space we reserved for locals and copied parameters. | |
| 899 // The NoSuchMethodFunction stub does not expect to see that area on the | |
| 900 // stack. | |
| 901 __ AddImmediate(SP, StackSize() * kWordSize); | |
| 902 } | |
| 903 // The call below has an empty stackmap because we have just | |
| 904 // dropped the spill slots. | |
| 905 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | |
| 906 | |
| 907 // Invoke noSuchMethod function passing the original name of the function. | 897 // Invoke noSuchMethod function passing the original name of the function. |
| 908 // If the function is a closure function, use "call" as the original name. | 898 // If the function is a closure function, use "call" as the original name. |
| 909 const String& name = String::Handle( | 899 const String& name = String::Handle( |
| 910 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); | 900 function.IsClosureFunction() ? Symbols::Call().raw() : function.name()); |
| 911 const int kNumArgsChecked = 1; | 901 const int kNumArgsChecked = 1; |
| 912 const ICData& ic_data = ICData::ZoneHandle( | 902 const ICData& ic_data = ICData::ZoneHandle( |
| 913 ICData::New(function, name, Object::null_array(), | 903 ICData::New(function, name, Object::null_array(), |
| 914 Isolate::kNoDeoptId, kNumArgsChecked)); | 904 Isolate::kNoDeoptId, kNumArgsChecked)); |
| 915 __ LoadObject(R5, ic_data); | 905 __ LoadObject(R5, ic_data); |
| 916 // FP - 4 : saved PP, object pool pointer of caller. | 906 __ LeaveDartFrame(); // The arguments are still on the stack. |
| 917 // FP + 0 : previous frame pointer. | 907 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); |
| 918 // FP + 4 : return address. | 908 // The noSuchMethod call may return to the caller, but not here. |
| 919 // FP + 8 : PC marker, for easy identification of RawInstruction obj. | 909 __ bkpt(0); |
| 920 // FP + 12: last argument (arg n-1). | |
| 921 // SP + 0 : saved PP. | |
| 922 // SP + 16 + 4*(n-1) : first argument (arg 0). | |
| 923 // R5 : ic-data. | |
| 924 // R4 : arguments descriptor array. | |
| 925 __ BranchLink(&StubCode::CallNoSuchMethodFunctionLabel()); | |
| 926 // Emit descriptors in order to provide correct postion in stacktrace. | |
| 927 AddCurrentDescriptor(PcDescriptors::kOther, -1, function.token_pos()); | |
| 928 if (is_optimizing()) { | |
| 929 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | |
| 930 empty_stack_bitmap, | |
| 931 0); // No registers. | |
| 932 } | |
| 933 // The noSuchMethod call may return. | |
| 934 __ LeaveDartFrame(); | |
| 935 __ Ret(); | |
| 936 | 910 |
| 937 __ Bind(&all_arguments_processed); | 911 __ Bind(&all_arguments_processed); |
| 938 // Nullify originally passed arguments only after they have been copied and | 912 // Nullify originally passed arguments only after they have been copied and |
| 939 // checked, otherwise noSuchMethod would not see their original values. | 913 // checked, otherwise noSuchMethod would not see their original values. |
| 940 // This step can be skipped in case we decide that formal parameters are | 914 // This step can be skipped in case we decide that formal parameters are |
| 941 // implicitly final, since garbage collecting the unmodified value is not | 915 // implicitly final, since garbage collecting the unmodified value is not |
| 942 // an issue anymore. | 916 // an issue anymore. |
| 943 | 917 |
| 944 // R4 : arguments descriptor array. | 918 // R4 : arguments descriptor array. |
| 945 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 919 __ ldr(R8, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 Label correct_num_arguments, wrong_num_arguments; | 1051 Label correct_num_arguments, wrong_num_arguments; |
| 1078 __ ldr(R0, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 1052 __ ldr(R0, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 1079 __ CompareImmediate(R0, Smi::RawValue(num_fixed_params)); | 1053 __ CompareImmediate(R0, Smi::RawValue(num_fixed_params)); |
| 1080 __ b(&wrong_num_arguments, NE); | 1054 __ b(&wrong_num_arguments, NE); |
| 1081 __ ldr(R1, FieldAddress(R4, | 1055 __ ldr(R1, FieldAddress(R4, |
| 1082 ArgumentsDescriptor::positional_count_offset())); | 1056 ArgumentsDescriptor::positional_count_offset())); |
| 1083 __ cmp(R0, ShifterOperand(R1)); | 1057 __ cmp(R0, ShifterOperand(R1)); |
| 1084 __ b(&correct_num_arguments, EQ); | 1058 __ b(&correct_num_arguments, EQ); |
| 1085 __ Bind(&wrong_num_arguments); | 1059 __ Bind(&wrong_num_arguments); |
| 1086 if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) { | 1060 if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) { |
| 1087 if (StackSize() != 0) { | |
| 1088 // We need to unwind the space we reserved for locals and copied | |
| 1089 // parameters. The NoSuchMethodFunction stub does not expect to see | |
| 1090 // that area on the stack. | |
| 1091 __ AddImmediate(SP, StackSize() * kWordSize); | |
| 1092 } | |
| 1093 // The call below has an empty stackmap because we have just | |
| 1094 // dropped the spill slots. | |
| 1095 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder(); | |
| 1096 | |
| 1097 // Invoke noSuchMethod function passing the original function name. | 1061 // Invoke noSuchMethod function passing the original function name. |
| 1098 // For closure functions, use "call" as the original name. | 1062 // For closure functions, use "call" as the original name. |
| 1099 const String& name = | 1063 const String& name = |
| 1100 String::Handle(function.IsClosureFunction() | 1064 String::Handle(function.IsClosureFunction() |
| 1101 ? Symbols::Call().raw() | 1065 ? Symbols::Call().raw() |
| 1102 : function.name()); | 1066 : function.name()); |
| 1103 const int kNumArgsChecked = 1; | 1067 const int kNumArgsChecked = 1; |
| 1104 const ICData& ic_data = ICData::ZoneHandle( | 1068 const ICData& ic_data = ICData::ZoneHandle( |
| 1105 ICData::New(function, name, Object::null_array(), | 1069 ICData::New(function, name, Object::null_array(), |
| 1106 Isolate::kNoDeoptId, kNumArgsChecked)); | 1070 Isolate::kNoDeoptId, kNumArgsChecked)); |
| 1107 __ LoadObject(R5, ic_data); | 1071 __ LoadObject(R5, ic_data); |
| 1108 // FP - 4 : saved PP, object pool pointer of caller. | 1072 __ LeaveDartFrame(); // The arguments are still on the stack. |
| 1109 // FP + 0 : previous frame pointer. | 1073 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); |
| 1110 // FP + 4 : return address. | 1074 // The noSuchMethod call may return to the caller, but not here. |
| 1111 // FP + 8 : PC marker, for easy identification of RawInstruction obj. | 1075 __ bkpt(0); |
| 1112 // FP + 12: last argument (arg n-1). | |
| 1113 // SP + 0 : saved PP. | |
| 1114 // SP + 16 + 4*(n-1) : first argument (arg 0). | |
| 1115 // R5 : ic-data. | |
| 1116 // R4 : arguments descriptor array. | |
| 1117 __ BranchLink(&StubCode::CallNoSuchMethodFunctionLabel()); | |
| 1118 // Emit descriptors in order to provide correct postion in stacktrace. | |
| 1119 AddCurrentDescriptor(PcDescriptors::kOther, -1, function.token_pos()); | |
| 1120 if (is_optimizing()) { | |
| 1121 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), | |
| 1122 empty_stack_bitmap, | |
| 1123 0); // No registers. | |
| 1124 } | |
| 1125 // The noSuchMethod call may return. | |
| 1126 __ LeaveDartFrame(); | |
| 1127 __ Ret(); | |
| 1128 } else { | 1076 } else { |
| 1129 __ Stop("Wrong number of arguments"); | 1077 __ Stop("Wrong number of arguments"); |
| 1130 } | 1078 } |
| 1131 __ Bind(&correct_num_arguments); | 1079 __ Bind(&correct_num_arguments); |
| 1132 } | 1080 } |
| 1133 // The arguments descriptor is never saved in the absence of optional | 1081 // The arguments descriptor is never saved in the absence of optional |
| 1134 // parameters, since any argument definition test would always yield true. | 1082 // parameters, since any argument definition test would always yield true. |
| 1135 ASSERT(saved_args_desc_var == NULL); | 1083 ASSERT(saved_args_desc_var == NULL); |
| 1136 } else { | 1084 } else { |
| 1137 if (saved_args_desc_var != NULL) { | 1085 if (saved_args_desc_var != NULL) { |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1762 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
| 1815 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); | 1763 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); |
| 1816 } | 1764 } |
| 1817 | 1765 |
| 1818 | 1766 |
| 1819 #undef __ | 1767 #undef __ |
| 1820 | 1768 |
| 1821 } // namespace dart | 1769 } // namespace dart |
| 1822 | 1770 |
| 1823 #endif // defined TARGET_ARCH_ARM | 1771 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |