| 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 const Register& target = x23; |
| 1043 __ Mov(x0, 0); // argc. |
| 1044 __ Mov(x1, 0); // argv. |
| 1045 __ Mov(x2, ExternalReference::isolate_address(isolate)); |
| 1046 __ Mov(target, find_handler); |
| 1047 __ Blr(target); |
| 1048 |
| 1049 // We didn't execute a return case, so the stack frame hasn't been updated |
| 1050 // (except for the return address slot). However, we don't need to initialize |
| 1051 // jssp because the throw method will immediately overwrite it when it |
| 1052 // unwinds the stack. |
| 1053 __ SetStackPointer(jssp); |
| 1054 |
| 1055 // Retrieve the handler context, SP and FP. |
| 1056 __ Mov(cp, Operand(pending_handler_context_address)); |
| 1057 __ Ldr(cp, MemOperand(cp)); |
| 1058 __ Mov(jssp, Operand(pending_handler_sp_address)); |
| 1059 __ Ldr(jssp, MemOperand(jssp)); |
| 1060 __ Mov(fp, Operand(pending_handler_fp_address)); |
| 1061 __ Ldr(fp, MemOperand(fp)); |
| 1062 |
| 1063 // If the handler is a JS frame, restore the context to the frame. |
| 1064 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1065 // or cp. |
| 1066 Label not_js_frame; |
| 1067 __ Cbz(cp, ¬_js_frame); |
| 1068 __ Str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1069 __ Bind(¬_js_frame); |
| 1070 |
| 1071 // Compute the handler entry address and jump to it. |
| 1072 __ Mov(scratch1, Operand(pending_handler_code_address)); |
| 1073 __ Ldr(scratch1, MemOperand(scratch1)); |
| 1074 __ Mov(scratch2, Operand(pending_handler_offset_address)); |
| 1075 __ Ldr(scratch2, MemOperand(scratch2)); |
| 1076 __ Add(scratch1, scratch1, Code::kHeaderSize - kHeapObjectTag); |
| 1077 __ Add(scratch1, scratch1, scratch2); |
| 1078 __ Br(scratch1); |
| 1079 } |
| 1080 |
| 1081 |
| 1024 void CEntryStub::Generate(MacroAssembler* masm) { | 1082 void CEntryStub::Generate(MacroAssembler* masm) { |
| 1025 // The Abort mechanism relies on CallRuntime, which in turn relies on | 1083 // 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 | 1084 // CEntryStub, so until this stub has been generated, we have to use a |
| 1027 // fall-back Abort mechanism. | 1085 // fall-back Abort mechanism. |
| 1028 // | 1086 // |
| 1029 // Note that this stub must be generated before any use of Abort. | 1087 // Note that this stub must be generated before any use of Abort. |
| 1030 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); | 1088 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); |
| 1031 | 1089 |
| 1032 ASM_LOCATION("CEntryStub::Generate entry"); | 1090 ASM_LOCATION("CEntryStub::Generate entry"); |
| 1033 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1091 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 __ Drop(x11); | 1238 __ Drop(x11); |
| 1181 __ AssertFPCRState(); | 1239 __ AssertFPCRState(); |
| 1182 __ Ret(); | 1240 __ Ret(); |
| 1183 | 1241 |
| 1184 // The stack pointer is still csp if we aren't returning, and the frame | 1242 // The stack pointer is still csp if we aren't returning, and the frame |
| 1185 // hasn't changed (except for the return address). | 1243 // hasn't changed (except for the return address). |
| 1186 __ SetStackPointer(csp); | 1244 __ SetStackPointer(csp); |
| 1187 | 1245 |
| 1188 // Handling of exception. | 1246 // Handling of exception. |
| 1189 __ Bind(&exception_returned); | 1247 __ Bind(&exception_returned); |
| 1190 | 1248 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 } | 1249 } |
| 1233 | 1250 |
| 1234 | 1251 |
| 1235 // This is the entry point from C++. 5 arguments are provided in x0-x4. | 1252 // 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. | 1253 // See use of the CALL_GENERATED_CODE macro for example in src/execution.cc. |
| 1237 // Input: | 1254 // Input: |
| 1238 // x0: code entry. | 1255 // x0: code entry. |
| 1239 // x1: function. | 1256 // x1: function. |
| 1240 // x2: receiver. | 1257 // x2: receiver. |
| 1241 // x3: argc. | 1258 // 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. | 2671 // in the RegExp code but no exception has been created yet. |
| 2655 // If there is no pending exception, handle that in the runtime system. | 2672 // If there is no pending exception, handle that in the runtime system. |
| 2656 __ Mov(x10, Operand(isolate()->factory()->the_hole_value())); | 2673 __ Mov(x10, Operand(isolate()->factory()->the_hole_value())); |
| 2657 __ Mov(x11, | 2674 __ Mov(x11, |
| 2658 Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2675 Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 2659 isolate()))); | 2676 isolate()))); |
| 2660 __ Ldr(exception_value, MemOperand(x11)); | 2677 __ Ldr(exception_value, MemOperand(x11)); |
| 2661 __ Cmp(x10, exception_value); | 2678 __ Cmp(x10, exception_value); |
| 2662 __ B(eq, &runtime); | 2679 __ B(eq, &runtime); |
| 2663 | 2680 |
| 2664 __ Str(x10, MemOperand(x11)); // Clear pending exception. | 2681 // For exception, throw the exception again. |
| 2665 | 2682 __ EnterExitFrame(false, x10); |
| 2666 // Check if the exception is a termination. If so, throw as uncatchable. | 2683 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 | 2684 |
| 2677 __ Bind(&failure); | 2685 __ Bind(&failure); |
| 2678 __ Mov(x0, Operand(isolate()->factory()->null_value())); | 2686 __ Mov(x0, Operand(isolate()->factory()->null_value())); |
| 2679 __ PopCPURegList(used_callee_saved_registers); | 2687 __ PopCPURegList(used_callee_saved_registers); |
| 2680 // Drop the 4 arguments of the stub from the stack. | 2688 // Drop the 4 arguments of the stub from the stack. |
| 2681 __ Drop(4); | 2689 __ Drop(4); |
| 2682 __ Ret(); | 2690 __ Ret(); |
| 2683 | 2691 |
| 2684 __ Bind(&runtime); | 2692 __ Bind(&runtime); |
| 2685 __ PopCPURegList(used_callee_saved_registers); | 2693 __ PopCPURegList(used_callee_saved_registers); |
| (...skipping 2795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5481 kStackUnwindSpace, NULL, spill_offset, | 5489 kStackUnwindSpace, NULL, spill_offset, |
| 5482 MemOperand(fp, 6 * kPointerSize), NULL); | 5490 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5483 } | 5491 } |
| 5484 | 5492 |
| 5485 | 5493 |
| 5486 #undef __ | 5494 #undef __ |
| 5487 | 5495 |
| 5488 } } // namespace v8::internal | 5496 } } // namespace v8::internal |
| 5489 | 5497 |
| 5490 #endif // V8_TARGET_ARCH_ARM64 | 5498 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |