| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 isolate->set_fp_stubs_generated(true); | 930 isolate->set_fp_stubs_generated(true); |
| 931 } | 931 } |
| 932 | 932 |
| 933 | 933 |
| 934 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 934 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
| 935 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 935 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
| 936 stub.GetCode(); | 936 stub.GetCode(); |
| 937 } | 937 } |
| 938 | 938 |
| 939 | 939 |
| 940 static void ThrowPendingException(MacroAssembler* masm) { |
| 941 Isolate* isolate = masm->isolate(); |
| 942 |
| 943 ExternalReference pending_handler_context_address( |
| 944 Isolate::kPendingHandlerContextAddress, isolate); |
| 945 ExternalReference pending_handler_code_address( |
| 946 Isolate::kPendingHandlerCodeAddress, isolate); |
| 947 ExternalReference pending_handler_offset_address( |
| 948 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 949 ExternalReference pending_handler_fp_address( |
| 950 Isolate::kPendingHandlerFPAddress, isolate); |
| 951 ExternalReference pending_handler_sp_address( |
| 952 Isolate::kPendingHandlerSPAddress, isolate); |
| 953 |
| 954 // Ask the runtime for help to determine the handler. This will set r0 to |
| 955 // contain the current pending exception, don't clobber it. |
| 956 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 957 { |
| 958 FrameScope scope(masm, StackFrame::MANUAL); |
| 959 __ PrepareCallCFunction(3, 0, r0); |
| 960 __ mov(r0, Operand(0)); |
| 961 __ mov(r1, Operand(0)); |
| 962 __ mov(r2, Operand(ExternalReference::isolate_address(isolate))); |
| 963 __ CallCFunction(find_handler, 3); |
| 964 } |
| 965 |
| 966 // Retrieve the handler context, SP and FP. |
| 967 __ mov(cp, Operand(pending_handler_context_address)); |
| 968 __ ldr(cp, MemOperand(cp)); |
| 969 __ mov(sp, Operand(pending_handler_sp_address)); |
| 970 __ ldr(sp, MemOperand(sp)); |
| 971 __ mov(fp, Operand(pending_handler_fp_address)); |
| 972 __ ldr(fp, MemOperand(fp)); |
| 973 |
| 974 // If the handler is a JS frame, restore the context to the frame. |
| 975 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 976 // or cp. |
| 977 __ cmp(cp, Operand(0)); |
| 978 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); |
| 979 |
| 980 // Compute the handler entry address and jump to it. |
| 981 ConstantPoolUnavailableScope constant_pool_unavailable(masm); |
| 982 __ mov(r1, Operand(pending_handler_code_address)); |
| 983 __ ldr(r1, MemOperand(r1)); |
| 984 __ mov(r2, Operand(pending_handler_offset_address)); |
| 985 __ ldr(r2, MemOperand(r2)); |
| 986 if (FLAG_enable_ool_constant_pool) { |
| 987 __ ldr(pp, FieldMemOperand(r1, Code::kConstantPoolOffset)); |
| 988 } |
| 989 __ add(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 990 __ add(pc, r1, r2); |
| 991 } |
| 992 |
| 993 |
| 940 void CEntryStub::Generate(MacroAssembler* masm) { | 994 void CEntryStub::Generate(MacroAssembler* masm) { |
| 941 // Called from JavaScript; parameters are on stack as if calling JS function. | 995 // Called from JavaScript; parameters are on stack as if calling JS function. |
| 942 // r0: number of arguments including receiver | 996 // r0: number of arguments including receiver |
| 943 // r1: pointer to builtin function | 997 // r1: pointer to builtin function |
| 944 // fp: frame pointer (restored after C call) | 998 // fp: frame pointer (restored after C call) |
| 945 // sp: stack pointer (restored as callee's sp after C call) | 999 // sp: stack pointer (restored as callee's sp after C call) |
| 946 // cp: current context (C callee-saved) | 1000 // cp: current context (C callee-saved) |
| 947 | 1001 |
| 948 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1002 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 949 | 1003 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 __ b(ne, &okay); | 1065 __ b(ne, &okay); |
| 1012 __ stop("The hole escaped"); | 1066 __ stop("The hole escaped"); |
| 1013 __ bind(&okay); | 1067 __ bind(&okay); |
| 1014 } | 1068 } |
| 1015 | 1069 |
| 1016 // Check result for exception sentinel. | 1070 // Check result for exception sentinel. |
| 1017 Label exception_returned; | 1071 Label exception_returned; |
| 1018 __ CompareRoot(r0, Heap::kExceptionRootIndex); | 1072 __ CompareRoot(r0, Heap::kExceptionRootIndex); |
| 1019 __ b(eq, &exception_returned); | 1073 __ b(eq, &exception_returned); |
| 1020 | 1074 |
| 1021 ExternalReference pending_exception_address( | |
| 1022 Isolate::kPendingExceptionAddress, isolate()); | |
| 1023 | |
| 1024 // Check that there is no pending exception, otherwise we | 1075 // Check that there is no pending exception, otherwise we |
| 1025 // should have returned the exception sentinel. | 1076 // should have returned the exception sentinel. |
| 1026 if (FLAG_debug_code) { | 1077 if (FLAG_debug_code) { |
| 1027 Label okay; | 1078 Label okay; |
| 1079 ExternalReference pending_exception_address( |
| 1080 Isolate::kPendingExceptionAddress, isolate()); |
| 1028 __ mov(r2, Operand(pending_exception_address)); | 1081 __ mov(r2, Operand(pending_exception_address)); |
| 1029 __ ldr(r2, MemOperand(r2)); | 1082 __ ldr(r2, MemOperand(r2)); |
| 1030 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1083 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
| 1031 // Cannot use check here as it attempts to generate call into runtime. | 1084 // Cannot use check here as it attempts to generate call into runtime. |
| 1032 __ b(eq, &okay); | 1085 __ b(eq, &okay); |
| 1033 __ stop("Unexpected pending exception"); | 1086 __ stop("Unexpected pending exception"); |
| 1034 __ bind(&okay); | 1087 __ bind(&okay); |
| 1035 } | 1088 } |
| 1036 | 1089 |
| 1037 // Exit C frame and return. | 1090 // Exit C frame and return. |
| 1038 // r0:r1: result | 1091 // r0:r1: result |
| 1039 // sp: stack pointer | 1092 // sp: stack pointer |
| 1040 // fp: frame pointer | 1093 // fp: frame pointer |
| 1041 // Callee-saved register r4 still holds argc. | 1094 // Callee-saved register r4 still holds argc. |
| 1042 __ LeaveExitFrame(save_doubles(), r4, true); | 1095 __ LeaveExitFrame(save_doubles(), r4, true); |
| 1043 __ mov(pc, lr); | 1096 __ mov(pc, lr); |
| 1044 | 1097 |
| 1045 // Handling of exception. | 1098 // Handling of exception. |
| 1046 __ bind(&exception_returned); | 1099 __ bind(&exception_returned); |
| 1047 | 1100 ThrowPendingException(masm); |
| 1048 // Retrieve the pending exception. | |
| 1049 __ mov(r2, Operand(pending_exception_address)); | |
| 1050 __ ldr(r0, MemOperand(r2)); | |
| 1051 | |
| 1052 // Clear the pending exception. | |
| 1053 __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); | |
| 1054 __ str(r3, MemOperand(r2)); | |
| 1055 | |
| 1056 // Special handling of termination exceptions which are uncatchable | |
| 1057 // by javascript code. | |
| 1058 Label throw_termination_exception; | |
| 1059 __ CompareRoot(r0, Heap::kTerminationExceptionRootIndex); | |
| 1060 __ b(eq, &throw_termination_exception); | |
| 1061 | |
| 1062 // Handle normal exception. | |
| 1063 __ Throw(r0); | |
| 1064 | |
| 1065 __ bind(&throw_termination_exception); | |
| 1066 __ ThrowUncatchable(r0); | |
| 1067 } | 1101 } |
| 1068 | 1102 |
| 1069 | 1103 |
| 1070 void JSEntryStub::Generate(MacroAssembler* masm) { | 1104 void JSEntryStub::Generate(MacroAssembler* masm) { |
| 1071 // r0: code entry | 1105 // r0: code entry |
| 1072 // r1: function | 1106 // r1: function |
| 1073 // r2: receiver | 1107 // r2: receiver |
| 1074 // r3: argc | 1108 // r3: argc |
| 1075 // [sp+0]: argv | 1109 // [sp+0]: argv |
| 1076 | 1110 |
| (...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2193 // stack overflow (on the backtrack stack) was detected in RegExp code but | 2227 // stack overflow (on the backtrack stack) was detected in RegExp code but |
| 2194 // haven't created the exception yet. Handle that in the runtime system. | 2228 // haven't created the exception yet. Handle that in the runtime system. |
| 2195 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2229 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
| 2196 __ mov(r1, Operand(isolate()->factory()->the_hole_value())); | 2230 __ mov(r1, Operand(isolate()->factory()->the_hole_value())); |
| 2197 __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2231 __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
| 2198 isolate()))); | 2232 isolate()))); |
| 2199 __ ldr(r0, MemOperand(r2, 0)); | 2233 __ ldr(r0, MemOperand(r2, 0)); |
| 2200 __ cmp(r0, r1); | 2234 __ cmp(r0, r1); |
| 2201 __ b(eq, &runtime); | 2235 __ b(eq, &runtime); |
| 2202 | 2236 |
| 2203 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. | 2237 // For exception, throw the exception again. |
| 2204 | 2238 __ EnterExitFrame(false); |
| 2205 // Check if the exception is a termination. If so, throw as uncatchable. | 2239 ThrowPendingException(masm); |
| 2206 __ CompareRoot(r0, Heap::kTerminationExceptionRootIndex); | |
| 2207 | |
| 2208 Label termination_exception; | |
| 2209 __ b(eq, &termination_exception); | |
| 2210 | |
| 2211 __ Throw(r0); | |
| 2212 | |
| 2213 __ bind(&termination_exception); | |
| 2214 __ ThrowUncatchable(r0); | |
| 2215 | 2240 |
| 2216 __ bind(&failure); | 2241 __ bind(&failure); |
| 2217 // For failure and exception return null. | 2242 // For failure and exception return null. |
| 2218 __ mov(r0, Operand(isolate()->factory()->null_value())); | 2243 __ mov(r0, Operand(isolate()->factory()->null_value())); |
| 2219 __ add(sp, sp, Operand(4 * kPointerSize)); | 2244 __ add(sp, sp, Operand(4 * kPointerSize)); |
| 2220 __ Ret(); | 2245 __ Ret(); |
| 2221 | 2246 |
| 2222 // Process the result from the native regexp code. | 2247 // Process the result from the native regexp code. |
| 2223 __ bind(&success); | 2248 __ bind(&success); |
| 2224 __ ldr(r1, | 2249 __ ldr(r1, |
| (...skipping 2777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5002 kStackUnwindSpace, NULL, | 5027 kStackUnwindSpace, NULL, |
| 5003 MemOperand(fp, 6 * kPointerSize), NULL); | 5028 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5004 } | 5029 } |
| 5005 | 5030 |
| 5006 | 5031 |
| 5007 #undef __ | 5032 #undef __ |
| 5008 | 5033 |
| 5009 } } // namespace v8::internal | 5034 } } // namespace v8::internal |
| 5010 | 5035 |
| 5011 #endif // V8_TARGET_ARCH_ARM | 5036 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |