OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1096 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
1097 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1097 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
1098 } | 1098 } |
1099 | 1099 |
1100 | 1100 |
1101 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1101 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
1102 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1102 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
1103 } | 1103 } |
1104 | 1104 |
1105 | 1105 |
| 1106 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
| 1107 Register function_template_info, |
| 1108 Register scratch0, Register scratch1, |
| 1109 Register scratch2, |
| 1110 Label* receiver_check_failed) { |
| 1111 Register signature = scratch0; |
| 1112 Register map = scratch1; |
| 1113 Register constructor = scratch2; |
| 1114 |
| 1115 // If the receiver is not an object, jump to receiver_check_failed. |
| 1116 __ CompareObjectType(receiver, map, x16, FIRST_JS_OBJECT_TYPE); |
| 1117 __ B(lo, receiver_check_failed); |
| 1118 |
| 1119 // If there is no signature, return the holder. |
| 1120 __ Ldr(signature, FieldMemOperand(function_template_info, |
| 1121 FunctionTemplateInfo::kSignatureOffset)); |
| 1122 __ CompareRoot(signature, Heap::kUndefinedValueRootIndex); |
| 1123 Label receiver_check_passed; |
| 1124 __ B(eq, &receiver_check_passed); |
| 1125 |
| 1126 // Walk the prototype chain. |
| 1127 Label prototype_loop_start; |
| 1128 __ Bind(&prototype_loop_start); |
| 1129 |
| 1130 // End if the receiver is null or if it's a hidden type. |
| 1131 __ CompareRoot(receiver, Heap::kNullValueRootIndex); |
| 1132 __ B(eq, receiver_check_failed); |
| 1133 __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 1134 __ Ldr(x16, FieldMemOperand(map, Map::kBitField3Offset)); |
| 1135 __ Tst(x16, Operand(Map::IsHiddenPrototype::kMask)); |
| 1136 __ B(ne, receiver_check_failed); |
| 1137 |
| 1138 // Get the constructor, if any |
| 1139 __ GetMapConstructor(constructor, map, x16, x16); |
| 1140 __ cmp(x16, Operand(JS_FUNCTION_TYPE)); |
| 1141 Label next_prototype; |
| 1142 __ B(ne, &next_prototype); |
| 1143 Register type = constructor; |
| 1144 __ Ldr(type, |
| 1145 FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset)); |
| 1146 __ Ldr(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset)); |
| 1147 |
| 1148 // Loop through the chain of inheriting function templates. |
| 1149 Label function_template_loop; |
| 1150 __ Bind(&function_template_loop); |
| 1151 |
| 1152 // If the signatures match, we have a compatible receiver. |
| 1153 __ Cmp(signature, type); |
| 1154 __ B(eq, &receiver_check_passed); |
| 1155 |
| 1156 // If the current type is not a FunctionTemplateInfo, load the next prototype |
| 1157 // in the chain. |
| 1158 __ JumpIfSmi(type, &next_prototype); |
| 1159 __ CompareObjectType(type, x16, x17, FUNCTION_TEMPLATE_INFO_TYPE); |
| 1160 __ B(ne, &next_prototype); |
| 1161 |
| 1162 // Otherwise load the parent function template and iterate. |
| 1163 __ Ldr(type, |
| 1164 FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset)); |
| 1165 __ B(&function_template_loop); |
| 1166 |
| 1167 // Load the next prototype and iterate. |
| 1168 __ Bind(&next_prototype); |
| 1169 __ Ldr(receiver, FieldMemOperand(map, Map::kPrototypeOffset)); |
| 1170 __ B(&prototype_loop_start); |
| 1171 |
| 1172 __ Bind(&receiver_check_passed); |
| 1173 } |
| 1174 |
| 1175 |
| 1176 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
| 1177 // ----------- S t a t e ------------- |
| 1178 // -- x0 : number of arguments excluding receiver |
| 1179 // -- x1 : callee |
| 1180 // -- lr : return address |
| 1181 // -- sp[0] : last argument |
| 1182 // -- ... |
| 1183 // -- sp[8 * (argc - 1)] : first argument |
| 1184 // -- sp[8 * argc] : receiver |
| 1185 // ----------------------------------- |
| 1186 |
| 1187 // Load the receiver. |
| 1188 __ Ldr(x2, MemOperand(jssp, x0, LSL, kPointerSizeLog2)); |
| 1189 |
| 1190 // Update the receiver if this is a contextual call. |
| 1191 Label set_global_proxy, valid_receiver; |
| 1192 __ CompareRoot(x2, Heap::kUndefinedValueRootIndex); |
| 1193 __ B(eq, &set_global_proxy); |
| 1194 __ Bind(&valid_receiver); |
| 1195 |
| 1196 // Load the FunctionTemplateInfo. |
| 1197 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 1198 __ Ldr(x3, FieldMemOperand(x3, SharedFunctionInfo::kFunctionDataOffset)); |
| 1199 |
| 1200 // Do the compatible receiver check. |
| 1201 Label receiver_check_failed; |
| 1202 CompatibleReceiverCheck(masm, x2, x3, x4, x5, x6, &receiver_check_failed); |
| 1203 |
| 1204 // Get the callback offset from the FunctionTemplateInfo, and jump to the |
| 1205 // beginning of the code. |
| 1206 __ Ldr(x4, FieldMemOperand(x3, FunctionTemplateInfo::kCallCodeOffset)); |
| 1207 __ Ldr(x4, FieldMemOperand(x4, CallHandlerInfo::kFastHandlerOffset)); |
| 1208 __ Add(x4, x4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1209 __ Jump(x4); |
| 1210 |
| 1211 __ Bind(&set_global_proxy); |
| 1212 __ Ldr(x2, GlobalObjectMemOperand()); |
| 1213 __ Ldr(x2, FieldMemOperand(x2, JSGlobalObject::kGlobalProxyOffset)); |
| 1214 __ Str(x2, MemOperand(jssp, x0, LSL, kPointerSizeLog2)); |
| 1215 __ B(&valid_receiver); |
| 1216 |
| 1217 // Compatible receiver check failed: throw an Illegal Invocation exception. |
| 1218 __ Bind(&receiver_check_failed); |
| 1219 // Drop the arguments (including the receiver) |
| 1220 __ add(x0, x0, Operand(1)); |
| 1221 __ Drop(x0); |
| 1222 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0, 1); |
| 1223 } |
| 1224 |
| 1225 |
1106 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1226 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1107 // Lookup the function in the JavaScript frame. | 1227 // Lookup the function in the JavaScript frame. |
1108 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1228 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
1109 { | 1229 { |
1110 FrameScope scope(masm, StackFrame::INTERNAL); | 1230 FrameScope scope(masm, StackFrame::INTERNAL); |
1111 // Pass function as argument. | 1231 // Pass function as argument. |
1112 __ Push(x0); | 1232 __ Push(x0); |
1113 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 1233 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
1114 } | 1234 } |
1115 | 1235 |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 } | 2044 } |
1925 } | 2045 } |
1926 | 2046 |
1927 | 2047 |
1928 #undef __ | 2048 #undef __ |
1929 | 2049 |
1930 } // namespace internal | 2050 } // namespace internal |
1931 } // namespace v8 | 2051 } // namespace v8 |
1932 | 2052 |
1933 #endif // V8_TARGET_ARCH_ARM | 2053 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |