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 __ mov(r0, Operand(0)); | |
958 __ mov(r1, Operand(0)); | |
959 __ mov(r2, Operand(ExternalReference::isolate_address(isolate))); | |
960 __ mov(r5, Operand(find_handler)); | |
961 __ Call(r5); | |
962 | |
963 // Retrieve the handler context, SP and FP. | |
964 __ mov(ip, Operand(pending_handler_context_address)); | |
rmcilroy
2015/03/02 13:08:27
I don't think you should use ip here - it could be
Michael Starzinger
2015/03/02 14:21:17
Done. Thanks, got it.
| |
965 __ ldr(cp, MemOperand(ip)); | |
966 __ mov(ip, Operand(pending_handler_sp_address)); | |
967 __ ldr(sp, MemOperand(ip)); | |
968 __ mov(ip, Operand(pending_handler_fp_address)); | |
969 __ ldr(fp, MemOperand(ip)); | |
970 | |
971 // If the handler is a JS frame, restore the context to the frame. | |
972 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp | |
973 // or cp. | |
974 __ tst(cp, cp); | |
975 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); | |
976 | |
977 // Compute the handler entry address and jump to it. | |
978 ConstantPoolUnavailableScope constant_pool_unavailable(masm); | |
979 __ mov(r1, Operand(pending_handler_code_address)); | |
980 __ ldr(r1, MemOperand(r1)); | |
981 __ mov(r2, Operand(pending_handler_offset_address)); | |
982 __ ldr(r2, MemOperand(r2)); | |
983 if (FLAG_enable_ool_constant_pool) { | |
984 __ ldr(pp, FieldMemOperand(r1, Code::kConstantPoolOffset)); | |
985 } | |
986 __ add(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
987 __ add(pc, r1, r2); | |
988 } | |
989 | |
990 | |
940 void CEntryStub::Generate(MacroAssembler* masm) { | 991 void CEntryStub::Generate(MacroAssembler* masm) { |
941 // Called from JavaScript; parameters are on stack as if calling JS function. | 992 // Called from JavaScript; parameters are on stack as if calling JS function. |
942 // r0: number of arguments including receiver | 993 // r0: number of arguments including receiver |
943 // r1: pointer to builtin function | 994 // r1: pointer to builtin function |
944 // fp: frame pointer (restored after C call) | 995 // fp: frame pointer (restored after C call) |
945 // sp: stack pointer (restored as callee's sp after C call) | 996 // sp: stack pointer (restored as callee's sp after C call) |
946 // cp: current context (C callee-saved) | 997 // cp: current context (C callee-saved) |
947 | 998 |
948 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 999 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
949 | 1000 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 __ b(ne, &okay); | 1062 __ b(ne, &okay); |
1012 __ stop("The hole escaped"); | 1063 __ stop("The hole escaped"); |
1013 __ bind(&okay); | 1064 __ bind(&okay); |
1014 } | 1065 } |
1015 | 1066 |
1016 // Check result for exception sentinel. | 1067 // Check result for exception sentinel. |
1017 Label exception_returned; | 1068 Label exception_returned; |
1018 __ CompareRoot(r0, Heap::kExceptionRootIndex); | 1069 __ CompareRoot(r0, Heap::kExceptionRootIndex); |
1019 __ b(eq, &exception_returned); | 1070 __ b(eq, &exception_returned); |
1020 | 1071 |
1021 ExternalReference pending_exception_address( | |
1022 Isolate::kPendingExceptionAddress, isolate()); | |
1023 | |
1024 // Check that there is no pending exception, otherwise we | 1072 // Check that there is no pending exception, otherwise we |
1025 // should have returned the exception sentinel. | 1073 // should have returned the exception sentinel. |
1026 if (FLAG_debug_code) { | 1074 if (FLAG_debug_code) { |
1027 Label okay; | 1075 Label okay; |
1076 ExternalReference pending_exception_address( | |
1077 Isolate::kPendingExceptionAddress, isolate()); | |
1028 __ mov(r2, Operand(pending_exception_address)); | 1078 __ mov(r2, Operand(pending_exception_address)); |
1029 __ ldr(r2, MemOperand(r2)); | 1079 __ ldr(r2, MemOperand(r2)); |
1030 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1080 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
1031 // Cannot use check here as it attempts to generate call into runtime. | 1081 // Cannot use check here as it attempts to generate call into runtime. |
1032 __ b(eq, &okay); | 1082 __ b(eq, &okay); |
1033 __ stop("Unexpected pending exception"); | 1083 __ stop("Unexpected pending exception"); |
1034 __ bind(&okay); | 1084 __ bind(&okay); |
1035 } | 1085 } |
1036 | 1086 |
1037 // Exit C frame and return. | 1087 // Exit C frame and return. |
1038 // r0:r1: result | 1088 // r0:r1: result |
1039 // sp: stack pointer | 1089 // sp: stack pointer |
1040 // fp: frame pointer | 1090 // fp: frame pointer |
1041 // Callee-saved register r4 still holds argc. | 1091 // Callee-saved register r4 still holds argc. |
1042 __ LeaveExitFrame(save_doubles(), r4, true); | 1092 __ LeaveExitFrame(save_doubles(), r4, true); |
1043 __ mov(pc, lr); | 1093 __ mov(pc, lr); |
1044 | 1094 |
1045 // Handling of exception. | 1095 // Handling of exception. |
1046 __ bind(&exception_returned); | 1096 __ bind(&exception_returned); |
1047 | 1097 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 } | 1098 } |
1068 | 1099 |
1069 | 1100 |
1070 void JSEntryStub::Generate(MacroAssembler* masm) { | 1101 void JSEntryStub::Generate(MacroAssembler* masm) { |
1071 // r0: code entry | 1102 // r0: code entry |
1072 // r1: function | 1103 // r1: function |
1073 // r2: receiver | 1104 // r2: receiver |
1074 // r3: argc | 1105 // r3: argc |
1075 // [sp+0]: argv | 1106 // [sp+0]: argv |
1076 | 1107 |
(...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 | 2224 // 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. | 2225 // haven't created the exception yet. Handle that in the runtime system. |
2195 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2226 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2196 __ mov(r1, Operand(isolate()->factory()->the_hole_value())); | 2227 __ mov(r1, Operand(isolate()->factory()->the_hole_value())); |
2197 __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2228 __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2198 isolate()))); | 2229 isolate()))); |
2199 __ ldr(r0, MemOperand(r2, 0)); | 2230 __ ldr(r0, MemOperand(r2, 0)); |
2200 __ cmp(r0, r1); | 2231 __ cmp(r0, r1); |
2201 __ b(eq, &runtime); | 2232 __ b(eq, &runtime); |
2202 | 2233 |
2203 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. | 2234 // For exception, throw the exception again. |
2204 | 2235 __ EnterExitFrame(false); |
2205 // Check if the exception is a termination. If so, throw as uncatchable. | 2236 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 | 2237 |
2216 __ bind(&failure); | 2238 __ bind(&failure); |
2217 // For failure and exception return null. | 2239 // For failure and exception return null. |
2218 __ mov(r0, Operand(isolate()->factory()->null_value())); | 2240 __ mov(r0, Operand(isolate()->factory()->null_value())); |
2219 __ add(sp, sp, Operand(4 * kPointerSize)); | 2241 __ add(sp, sp, Operand(4 * kPointerSize)); |
2220 __ Ret(); | 2242 __ Ret(); |
2221 | 2243 |
2222 // Process the result from the native regexp code. | 2244 // Process the result from the native regexp code. |
2223 __ bind(&success); | 2245 __ bind(&success); |
2224 __ ldr(r1, | 2246 __ ldr(r1, |
(...skipping 2777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5002 kStackUnwindSpace, NULL, | 5024 kStackUnwindSpace, NULL, |
5003 MemOperand(fp, 6 * kPointerSize), NULL); | 5025 MemOperand(fp, 6 * kPointerSize), NULL); |
5004 } | 5026 } |
5005 | 5027 |
5006 | 5028 |
5007 #undef __ | 5029 #undef __ |
5008 | 5030 |
5009 } } // namespace v8::internal | 5031 } } // namespace v8::internal |
5010 | 5032 |
5011 #endif // V8_TARGET_ARCH_ARM | 5033 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |