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