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 |