OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1105 matching lines...) Loading... |
1116 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1116 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
1117 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1117 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
1118 } | 1118 } |
1119 | 1119 |
1120 | 1120 |
1121 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1121 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
1122 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1122 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
1123 } | 1123 } |
1124 | 1124 |
1125 | 1125 |
| 1126 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
| 1127 Register function_template_info, |
| 1128 Register scratch0, Register scratch1, |
| 1129 Register scratch2, |
| 1130 Label* receiver_check_failed) { |
| 1131 Register signature = scratch0; |
| 1132 Register map = scratch1; |
| 1133 Register constructor = scratch2; |
| 1134 |
| 1135 // If the receiver is not an object, jump to receiver_check_failed. |
| 1136 __ CompareObjectType(receiver, map, ip, FIRST_JS_OBJECT_TYPE); |
| 1137 __ b(lo, receiver_check_failed); |
| 1138 |
| 1139 // If there is no signature, return the holder. |
| 1140 __ ldr(signature, FieldMemOperand(function_template_info, |
| 1141 FunctionTemplateInfo::kSignatureOffset)); |
| 1142 __ CompareRoot(signature, Heap::kUndefinedValueRootIndex); |
| 1143 Label receiver_check_passed; |
| 1144 __ b(eq, &receiver_check_passed); |
| 1145 |
| 1146 // Walk the prototype chain. |
| 1147 Label prototype_loop_start; |
| 1148 __ bind(&prototype_loop_start); |
| 1149 |
| 1150 // End if the receiver is null or if it's a hidden type. |
| 1151 __ CompareRoot(receiver, Heap::kNullValueRootIndex); |
| 1152 __ b(eq, receiver_check_failed); |
| 1153 __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 1154 __ ldr(ip, FieldMemOperand(map, Map::kBitField3Offset)); |
| 1155 __ tst(ip, Operand(Map::IsHiddenPrototype::kMask)); |
| 1156 __ b(ne, receiver_check_failed); |
| 1157 |
| 1158 // Get the constructor, if any. |
| 1159 __ GetMapConstructor(constructor, map, ip, ip); |
| 1160 __ cmp(ip, Operand(JS_FUNCTION_TYPE)); |
| 1161 Label next_prototype; |
| 1162 __ b(ne, &next_prototype); |
| 1163 Register type = constructor; |
| 1164 __ ldr(type, |
| 1165 FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset)); |
| 1166 __ ldr(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset)); |
| 1167 |
| 1168 // Loop through the chain of inheriting function templates. |
| 1169 Label function_template_loop; |
| 1170 __ bind(&function_template_loop); |
| 1171 |
| 1172 // If the signatures match, we have a compatible receiver. |
| 1173 __ cmp(signature, type); |
| 1174 __ b(eq, &receiver_check_passed); |
| 1175 |
| 1176 // If the current type is not a FunctionTemplateInfo, load the next prototype |
| 1177 // in the chain. |
| 1178 __ JumpIfSmi(type, &next_prototype); |
| 1179 __ CompareObjectType(type, ip, ip, FUNCTION_TEMPLATE_INFO_TYPE); |
| 1180 |
| 1181 // Otherwise load the parent function template and iterate. |
| 1182 __ ldr(type, |
| 1183 FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset), |
| 1184 eq); |
| 1185 __ b(&function_template_loop, eq); |
| 1186 |
| 1187 // Load the next prototype and iterate. |
| 1188 __ bind(&next_prototype); |
| 1189 __ ldr(receiver, FieldMemOperand(map, Map::kPrototypeOffset)); |
| 1190 __ b(&prototype_loop_start); |
| 1191 |
| 1192 __ bind(&receiver_check_passed); |
| 1193 } |
| 1194 |
| 1195 |
| 1196 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
| 1197 // ----------- S t a t e ------------- |
| 1198 // -- r0 : number of arguments excluding receiver |
| 1199 // -- r1 : callee |
| 1200 // -- lr : return address |
| 1201 // -- sp[0] : last argument |
| 1202 // -- ... |
| 1203 // -- sp[4 * (argc - 1)] : first argument |
| 1204 // -- sp[4 * argc] : receiver |
| 1205 // ----------------------------------- |
| 1206 |
| 1207 // Load the receiver. |
| 1208 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1209 |
| 1210 // Update the receiver if this is a contextual call. |
| 1211 Label set_global_proxy, valid_receiver; |
| 1212 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
| 1213 __ b(eq, &set_global_proxy); |
| 1214 __ bind(&valid_receiver); |
| 1215 |
| 1216 // Load the FunctionTemplateInfo. |
| 1217 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1218 __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset)); |
| 1219 |
| 1220 // Do the compatible receiver check. |
| 1221 Label receiver_check_failed; |
| 1222 CompatibleReceiverCheck(masm, r2, r3, r4, r5, r6, &receiver_check_failed); |
| 1223 |
| 1224 // Get the callback offset from the FunctionTemplateInfo, and jump to the |
| 1225 // beginning of the code. |
| 1226 __ ldr(r4, FieldMemOperand(r3, FunctionTemplateInfo::kCallCodeOffset)); |
| 1227 __ ldr(r4, FieldMemOperand(r4, CallHandlerInfo::kFastHandlerOffset)); |
| 1228 __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1229 __ Jump(r4); |
| 1230 |
| 1231 __ bind(&set_global_proxy); |
| 1232 __ ldr(r2, GlobalObjectOperand()); |
| 1233 __ ldr(r2, FieldMemOperand(r2, JSGlobalObject::kGlobalProxyOffset)); |
| 1234 __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2)); |
| 1235 __ b(&valid_receiver); |
| 1236 |
| 1237 // Compatible receiver check failed: throw an Illegal Invocation exception. |
| 1238 __ bind(&receiver_check_failed); |
| 1239 // Drop the arguments (including the receiver) |
| 1240 __ add(r0, r0, Operand(1)); |
| 1241 __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2)); |
| 1242 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0, 1); |
| 1243 } |
| 1244 |
| 1245 |
1126 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1246 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1127 // Lookup the function in the JavaScript frame. | 1247 // Lookup the function in the JavaScript frame. |
1128 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1248 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1129 { | 1249 { |
1130 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 1250 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
1131 // Pass function as argument. | 1251 // Pass function as argument. |
1132 __ push(r0); | 1252 __ push(r0); |
1133 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 1253 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
1134 } | 1254 } |
1135 | 1255 |
(...skipping 702 matching lines...) Loading... |
1838 } | 1958 } |
1839 } | 1959 } |
1840 | 1960 |
1841 | 1961 |
1842 #undef __ | 1962 #undef __ |
1843 | 1963 |
1844 } // namespace internal | 1964 } // namespace internal |
1845 } // namespace v8 | 1965 } // namespace v8 |
1846 | 1966 |
1847 #endif // V8_TARGET_ARCH_ARM | 1967 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |