| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 | 1015 |
| 1016 | 1016 |
| 1017 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 1017 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
| 1018 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 1018 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
| 1019 stub.GetCode(); | 1019 stub.GetCode(); |
| 1020 CEntryStub stub_fp(isolate, 1, kSaveFPRegs); | 1020 CEntryStub stub_fp(isolate, 1, kSaveFPRegs); |
| 1021 stub_fp.GetCode(); | 1021 stub_fp.GetCode(); |
| 1022 } | 1022 } |
| 1023 | 1023 |
| 1024 | 1024 |
| 1025 static void ThrowPendingException(MacroAssembler* masm, Register scratch1, | |
| 1026 Register scratch2) { | |
| 1027 Isolate* isolate = masm->isolate(); | |
| 1028 | |
| 1029 ExternalReference pending_handler_context_address( | |
| 1030 Isolate::kPendingHandlerContextAddress, isolate); | |
| 1031 ExternalReference pending_handler_code_address( | |
| 1032 Isolate::kPendingHandlerCodeAddress, isolate); | |
| 1033 ExternalReference pending_handler_offset_address( | |
| 1034 Isolate::kPendingHandlerOffsetAddress, isolate); | |
| 1035 ExternalReference pending_handler_fp_address( | |
| 1036 Isolate::kPendingHandlerFPAddress, isolate); | |
| 1037 ExternalReference pending_handler_sp_address( | |
| 1038 Isolate::kPendingHandlerSPAddress, isolate); | |
| 1039 | |
| 1040 // Ask the runtime for help to determine the handler. This will set x0 to | |
| 1041 // contain the current pending exception, don't clobber it. | |
| 1042 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); | |
| 1043 DCHECK(csp.Is(masm->StackPointer())); | |
| 1044 { | |
| 1045 FrameScope scope(masm, StackFrame::MANUAL); | |
| 1046 __ Mov(x0, 0); // argc. | |
| 1047 __ Mov(x1, 0); // argv. | |
| 1048 __ Mov(x2, ExternalReference::isolate_address(isolate)); | |
| 1049 __ CallCFunction(find_handler, 3); | |
| 1050 } | |
| 1051 | |
| 1052 // We didn't execute a return case, so the stack frame hasn't been updated | |
| 1053 // (except for the return address slot). However, we don't need to initialize | |
| 1054 // jssp because the throw method will immediately overwrite it when it | |
| 1055 // unwinds the stack. | |
| 1056 __ SetStackPointer(jssp); | |
| 1057 | |
| 1058 // Retrieve the handler context, SP and FP. | |
| 1059 __ Mov(cp, Operand(pending_handler_context_address)); | |
| 1060 __ Ldr(cp, MemOperand(cp)); | |
| 1061 __ Mov(jssp, Operand(pending_handler_sp_address)); | |
| 1062 __ Ldr(jssp, MemOperand(jssp)); | |
| 1063 __ Mov(fp, Operand(pending_handler_fp_address)); | |
| 1064 __ Ldr(fp, MemOperand(fp)); | |
| 1065 | |
| 1066 // If the handler is a JS frame, restore the context to the frame. | |
| 1067 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp | |
| 1068 // or cp. | |
| 1069 Label not_js_frame; | |
| 1070 __ Cbz(cp, ¬_js_frame); | |
| 1071 __ Str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
| 1072 __ Bind(¬_js_frame); | |
| 1073 | |
| 1074 // Compute the handler entry address and jump to it. | |
| 1075 __ Mov(scratch1, Operand(pending_handler_code_address)); | |
| 1076 __ Ldr(scratch1, MemOperand(scratch1)); | |
| 1077 __ Mov(scratch2, Operand(pending_handler_offset_address)); | |
| 1078 __ Ldr(scratch2, MemOperand(scratch2)); | |
| 1079 __ Add(scratch1, scratch1, Code::kHeaderSize - kHeapObjectTag); | |
| 1080 __ Add(scratch1, scratch1, scratch2); | |
| 1081 __ Br(scratch1); | |
| 1082 } | |
| 1083 | |
| 1084 | |
| 1085 void CEntryStub::Generate(MacroAssembler* masm) { | 1025 void CEntryStub::Generate(MacroAssembler* masm) { |
| 1086 // The Abort mechanism relies on CallRuntime, which in turn relies on | 1026 // The Abort mechanism relies on CallRuntime, which in turn relies on |
| 1087 // CEntryStub, so until this stub has been generated, we have to use a | 1027 // CEntryStub, so until this stub has been generated, we have to use a |
| 1088 // fall-back Abort mechanism. | 1028 // fall-back Abort mechanism. |
| 1089 // | 1029 // |
| 1090 // Note that this stub must be generated before any use of Abort. | 1030 // Note that this stub must be generated before any use of Abort. |
| 1091 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); | 1031 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); |
| 1092 | 1032 |
| 1093 ASM_LOCATION("CEntryStub::Generate entry"); | 1033 ASM_LOCATION("CEntryStub::Generate entry"); |
| 1094 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1034 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 __ Drop(x11); | 1181 __ Drop(x11); |
| 1242 __ AssertFPCRState(); | 1182 __ AssertFPCRState(); |
| 1243 __ Ret(); | 1183 __ Ret(); |
| 1244 | 1184 |
| 1245 // The stack pointer is still csp if we aren't returning, and the frame | 1185 // The stack pointer is still csp if we aren't returning, and the frame |
| 1246 // hasn't changed (except for the return address). | 1186 // hasn't changed (except for the return address). |
| 1247 __ SetStackPointer(csp); | 1187 __ SetStackPointer(csp); |
| 1248 | 1188 |
| 1249 // Handling of exception. | 1189 // Handling of exception. |
| 1250 __ Bind(&exception_returned); | 1190 __ Bind(&exception_returned); |
| 1251 ThrowPendingException(masm, x10, x11); | 1191 |
| 1192 ExternalReference pending_handler_context_address( |
| 1193 Isolate::kPendingHandlerContextAddress, isolate()); |
| 1194 ExternalReference pending_handler_code_address( |
| 1195 Isolate::kPendingHandlerCodeAddress, isolate()); |
| 1196 ExternalReference pending_handler_offset_address( |
| 1197 Isolate::kPendingHandlerOffsetAddress, isolate()); |
| 1198 ExternalReference pending_handler_fp_address( |
| 1199 Isolate::kPendingHandlerFPAddress, isolate()); |
| 1200 ExternalReference pending_handler_sp_address( |
| 1201 Isolate::kPendingHandlerSPAddress, isolate()); |
| 1202 |
| 1203 // Ask the runtime for help to determine the handler. This will set x0 to |
| 1204 // contain the current pending exception, don't clobber it. |
| 1205 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate()); |
| 1206 DCHECK(csp.Is(masm->StackPointer())); |
| 1207 { |
| 1208 FrameScope scope(masm, StackFrame::MANUAL); |
| 1209 __ Mov(x0, 0); // argc. |
| 1210 __ Mov(x1, 0); // argv. |
| 1211 __ Mov(x2, ExternalReference::isolate_address(isolate())); |
| 1212 __ CallCFunction(find_handler, 3); |
| 1213 } |
| 1214 |
| 1215 // We didn't execute a return case, so the stack frame hasn't been updated |
| 1216 // (except for the return address slot). However, we don't need to initialize |
| 1217 // jssp because the throw method will immediately overwrite it when it |
| 1218 // unwinds the stack. |
| 1219 __ SetStackPointer(jssp); |
| 1220 |
| 1221 // Retrieve the handler context, SP and FP. |
| 1222 __ Mov(cp, Operand(pending_handler_context_address)); |
| 1223 __ Ldr(cp, MemOperand(cp)); |
| 1224 __ Mov(jssp, Operand(pending_handler_sp_address)); |
| 1225 __ Ldr(jssp, MemOperand(jssp)); |
| 1226 __ Mov(fp, Operand(pending_handler_fp_address)); |
| 1227 __ Ldr(fp, MemOperand(fp)); |
| 1228 |
| 1229 // If the handler is a JS frame, restore the context to the frame. |
| 1230 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1231 // or cp. |
| 1232 Label not_js_frame; |
| 1233 __ Cbz(cp, ¬_js_frame); |
| 1234 __ Str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1235 __ Bind(¬_js_frame); |
| 1236 |
| 1237 // Compute the handler entry address and jump to it. |
| 1238 __ Mov(x10, Operand(pending_handler_code_address)); |
| 1239 __ Ldr(x10, MemOperand(x10)); |
| 1240 __ Mov(x11, Operand(pending_handler_offset_address)); |
| 1241 __ Ldr(x11, MemOperand(x11)); |
| 1242 __ Add(x10, x10, Code::kHeaderSize - kHeapObjectTag); |
| 1243 __ Add(x10, x10, x11); |
| 1244 __ Br(x10); |
| 1252 } | 1245 } |
| 1253 | 1246 |
| 1254 | 1247 |
| 1255 // This is the entry point from C++. 5 arguments are provided in x0-x4. | 1248 // This is the entry point from C++. 5 arguments are provided in x0-x4. |
| 1256 // See use of the CALL_GENERATED_CODE macro for example in src/execution.cc. | 1249 // See use of the CALL_GENERATED_CODE macro for example in src/execution.cc. |
| 1257 // Input: | 1250 // Input: |
| 1258 // x0: code entry. | 1251 // x0: code entry. |
| 1259 // x1: function. | 1252 // x1: function. |
| 1260 // x2: receiver. | 1253 // x2: receiver. |
| 1261 // x3: argc. | 1254 // x3: argc. |
| (...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2675 // If there is no pending exception, handle that in the runtime system. | 2668 // If there is no pending exception, handle that in the runtime system. |
| 2676 __ Mov(x10, Operand(isolate()->factory()->the_hole_value())); | 2669 __ Mov(x10, Operand(isolate()->factory()->the_hole_value())); |
| 2677 __ Mov(x11, | 2670 __ Mov(x11, |
| 2678 Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2671 Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 2679 isolate()))); | 2672 isolate()))); |
| 2680 __ Ldr(exception_value, MemOperand(x11)); | 2673 __ Ldr(exception_value, MemOperand(x11)); |
| 2681 __ Cmp(x10, exception_value); | 2674 __ Cmp(x10, exception_value); |
| 2682 __ B(eq, &runtime); | 2675 __ B(eq, &runtime); |
| 2683 | 2676 |
| 2684 // For exception, throw the exception again. | 2677 // For exception, throw the exception again. |
| 2685 __ EnterExitFrame(false, x10); | 2678 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4, 1); |
| 2686 ThrowPendingException(masm, x10, x11); | |
| 2687 | 2679 |
| 2688 __ Bind(&failure); | 2680 __ Bind(&failure); |
| 2689 __ Mov(x0, Operand(isolate()->factory()->null_value())); | 2681 __ Mov(x0, Operand(isolate()->factory()->null_value())); |
| 2690 __ PopCPURegList(used_callee_saved_registers); | 2682 __ PopCPURegList(used_callee_saved_registers); |
| 2691 // Drop the 4 arguments of the stub from the stack. | 2683 // Drop the 4 arguments of the stub from the stack. |
| 2692 __ Drop(4); | 2684 __ Drop(4); |
| 2693 __ Ret(); | 2685 __ Ret(); |
| 2694 | 2686 |
| 2695 __ Bind(&runtime); | 2687 __ Bind(&runtime); |
| 2696 __ PopCPURegList(used_callee_saved_registers); | 2688 __ PopCPURegList(used_callee_saved_registers); |
| (...skipping 3048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5745 kStackUnwindSpace, NULL, spill_offset, | 5737 kStackUnwindSpace, NULL, spill_offset, |
| 5746 MemOperand(fp, 6 * kPointerSize), NULL); | 5738 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5747 } | 5739 } |
| 5748 | 5740 |
| 5749 | 5741 |
| 5750 #undef __ | 5742 #undef __ |
| 5751 | 5743 |
| 5752 } } // namespace v8::internal | 5744 } } // namespace v8::internal |
| 5753 | 5745 |
| 5754 #endif // V8_TARGET_ARCH_ARM64 | 5746 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |