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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
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 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 isolate->set_fp_stubs_generated(true); | 1029 isolate->set_fp_stubs_generated(true); |
1030 } | 1030 } |
1031 | 1031 |
1032 | 1032 |
1033 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 1033 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
1034 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 1034 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
1035 stub.GetCode(); | 1035 stub.GetCode(); |
1036 } | 1036 } |
1037 | 1037 |
1038 | 1038 |
| 1039 static void ThrowPendingException(MacroAssembler* masm) { |
| 1040 Isolate* isolate = masm->isolate(); |
| 1041 |
| 1042 ExternalReference pending_handler_context_address( |
| 1043 Isolate::kPendingHandlerContextAddress, isolate); |
| 1044 ExternalReference pending_handler_code_address( |
| 1045 Isolate::kPendingHandlerCodeAddress, isolate); |
| 1046 ExternalReference pending_handler_offset_address( |
| 1047 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 1048 ExternalReference pending_handler_fp_address( |
| 1049 Isolate::kPendingHandlerFPAddress, isolate); |
| 1050 ExternalReference pending_handler_sp_address( |
| 1051 Isolate::kPendingHandlerSPAddress, isolate); |
| 1052 |
| 1053 // Ask the runtime for help to determine the handler. This will set v0 to |
| 1054 // contain the current pending exception, don't clobber it. |
| 1055 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 1056 { |
| 1057 FrameScope scope(masm, StackFrame::MANUAL); |
| 1058 __ PrepareCallCFunction(3, 0, a0); |
| 1059 __ mov(a0, zero_reg); |
| 1060 __ mov(a1, zero_reg); |
| 1061 __ li(a2, Operand(ExternalReference::isolate_address(isolate))); |
| 1062 __ CallCFunction(find_handler, 3); |
| 1063 } |
| 1064 |
| 1065 // Retrieve the handler context, SP and FP. |
| 1066 __ li(cp, Operand(pending_handler_context_address)); |
| 1067 __ lw(cp, MemOperand(cp)); |
| 1068 __ li(sp, Operand(pending_handler_sp_address)); |
| 1069 __ lw(sp, MemOperand(sp)); |
| 1070 __ li(fp, Operand(pending_handler_fp_address)); |
| 1071 __ lw(fp, MemOperand(fp)); |
| 1072 |
| 1073 // If the handler is a JS frame, restore the context to the frame. |
| 1074 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1075 // or cp. |
| 1076 Label zero; |
| 1077 __ Branch(&zero, eq, cp, Operand(zero_reg)); |
| 1078 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1079 __ bind(&zero); |
| 1080 |
| 1081 // Compute the handler entry address and jump to it. |
| 1082 __ li(a1, Operand(pending_handler_code_address)); |
| 1083 __ lw(a1, MemOperand(a1)); |
| 1084 __ li(a2, Operand(pending_handler_offset_address)); |
| 1085 __ lw(a2, MemOperand(a2)); |
| 1086 __ Addu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1087 __ Addu(t9, a1, a2); |
| 1088 __ Jump(t9); |
| 1089 } |
| 1090 |
| 1091 |
1039 void CEntryStub::Generate(MacroAssembler* masm) { | 1092 void CEntryStub::Generate(MacroAssembler* masm) { |
1040 // Called from JavaScript; parameters are on stack as if calling JS function | 1093 // Called from JavaScript; parameters are on stack as if calling JS function |
1041 // a0: number of arguments including receiver | 1094 // a0: number of arguments including receiver |
1042 // a1: pointer to builtin function | 1095 // a1: pointer to builtin function |
1043 // fp: frame pointer (restored after C call) | 1096 // fp: frame pointer (restored after C call) |
1044 // sp: stack pointer (restored as callee's sp after C call) | 1097 // sp: stack pointer (restored as callee's sp after C call) |
1045 // cp: current context (C callee-saved) | 1098 // cp: current context (C callee-saved) |
1046 | 1099 |
1047 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1100 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
1048 | 1101 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 __ Branch(&okay, ne, v0, Operand(t0)); | 1167 __ Branch(&okay, ne, v0, Operand(t0)); |
1115 __ stop("The hole escaped"); | 1168 __ stop("The hole escaped"); |
1116 __ bind(&okay); | 1169 __ bind(&okay); |
1117 } | 1170 } |
1118 | 1171 |
1119 // Check result for exception sentinel. | 1172 // Check result for exception sentinel. |
1120 Label exception_returned; | 1173 Label exception_returned; |
1121 __ LoadRoot(t0, Heap::kExceptionRootIndex); | 1174 __ LoadRoot(t0, Heap::kExceptionRootIndex); |
1122 __ Branch(&exception_returned, eq, t0, Operand(v0)); | 1175 __ Branch(&exception_returned, eq, t0, Operand(v0)); |
1123 | 1176 |
1124 ExternalReference pending_exception_address( | |
1125 Isolate::kPendingExceptionAddress, isolate()); | |
1126 | |
1127 // Check that there is no pending exception, otherwise we | 1177 // Check that there is no pending exception, otherwise we |
1128 // should have returned the exception sentinel. | 1178 // should have returned the exception sentinel. |
1129 if (FLAG_debug_code) { | 1179 if (FLAG_debug_code) { |
1130 Label okay; | 1180 Label okay; |
| 1181 ExternalReference pending_exception_address( |
| 1182 Isolate::kPendingExceptionAddress, isolate()); |
1131 __ li(a2, Operand(pending_exception_address)); | 1183 __ li(a2, Operand(pending_exception_address)); |
1132 __ lw(a2, MemOperand(a2)); | 1184 __ lw(a2, MemOperand(a2)); |
1133 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); | 1185 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
1134 // Cannot use check here as it attempts to generate call into runtime. | 1186 // Cannot use check here as it attempts to generate call into runtime. |
1135 __ Branch(&okay, eq, t0, Operand(a2)); | 1187 __ Branch(&okay, eq, t0, Operand(a2)); |
1136 __ stop("Unexpected pending exception"); | 1188 __ stop("Unexpected pending exception"); |
1137 __ bind(&okay); | 1189 __ bind(&okay); |
1138 } | 1190 } |
1139 | 1191 |
1140 // Exit C frame and return. | 1192 // Exit C frame and return. |
1141 // v0:v1: result | 1193 // v0:v1: result |
1142 // sp: stack pointer | 1194 // sp: stack pointer |
1143 // fp: frame pointer | 1195 // fp: frame pointer |
1144 // s0: still holds argc (callee-saved). | 1196 // s0: still holds argc (callee-saved). |
1145 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); | 1197 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); |
1146 | 1198 |
1147 // Handling of exception. | 1199 // Handling of exception. |
1148 __ bind(&exception_returned); | 1200 __ bind(&exception_returned); |
1149 | 1201 ThrowPendingException(masm); |
1150 // Retrieve the pending exception. | |
1151 __ li(a2, Operand(pending_exception_address)); | |
1152 __ lw(v0, MemOperand(a2)); | |
1153 | |
1154 // Clear the pending exception. | |
1155 __ li(a3, Operand(isolate()->factory()->the_hole_value())); | |
1156 __ sw(a3, MemOperand(a2)); | |
1157 | |
1158 // Special handling of termination exceptions which are uncatchable | |
1159 // by javascript code. | |
1160 Label throw_termination_exception; | |
1161 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex); | |
1162 __ Branch(&throw_termination_exception, eq, v0, Operand(t0)); | |
1163 | |
1164 // Handle normal exception. | |
1165 __ Throw(v0); | |
1166 | |
1167 __ bind(&throw_termination_exception); | |
1168 __ ThrowUncatchable(v0); | |
1169 } | 1202 } |
1170 | 1203 |
1171 | 1204 |
1172 void JSEntryStub::Generate(MacroAssembler* masm) { | 1205 void JSEntryStub::Generate(MacroAssembler* masm) { |
1173 Label invoke, handler_entry, exit; | 1206 Label invoke, handler_entry, exit; |
1174 Isolate* isolate = masm->isolate(); | 1207 Isolate* isolate = masm->isolate(); |
1175 | 1208 |
1176 // Registers: | 1209 // Registers: |
1177 // a0: entry address | 1210 // a0: entry address |
1178 // a1: function | 1211 // a1: function |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2331 // Result must now be exception. If there is no pending exception already a | 2364 // Result must now be exception. If there is no pending exception already a |
2332 // stack overflow (on the backtrack stack) was detected in RegExp code but | 2365 // stack overflow (on the backtrack stack) was detected in RegExp code but |
2333 // haven't created the exception yet. Handle that in the runtime system. | 2366 // haven't created the exception yet. Handle that in the runtime system. |
2334 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2367 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2335 __ li(a1, Operand(isolate()->factory()->the_hole_value())); | 2368 __ li(a1, Operand(isolate()->factory()->the_hole_value())); |
2336 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2369 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2337 isolate()))); | 2370 isolate()))); |
2338 __ lw(v0, MemOperand(a2, 0)); | 2371 __ lw(v0, MemOperand(a2, 0)); |
2339 __ Branch(&runtime, eq, v0, Operand(a1)); | 2372 __ Branch(&runtime, eq, v0, Operand(a1)); |
2340 | 2373 |
2341 __ sw(a1, MemOperand(a2, 0)); // Clear pending exception. | 2374 // For exception, throw the exception again. |
2342 | 2375 __ EnterExitFrame(false); |
2343 // Check if the exception is a termination. If so, throw as uncatchable. | 2376 ThrowPendingException(masm); |
2344 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); | |
2345 Label termination_exception; | |
2346 __ Branch(&termination_exception, eq, v0, Operand(a0)); | |
2347 | |
2348 __ Throw(v0); | |
2349 | |
2350 __ bind(&termination_exception); | |
2351 __ ThrowUncatchable(v0); | |
2352 | 2377 |
2353 __ bind(&failure); | 2378 __ bind(&failure); |
2354 // For failure and exception return null. | 2379 // For failure and exception return null. |
2355 __ li(v0, Operand(isolate()->factory()->null_value())); | 2380 __ li(v0, Operand(isolate()->factory()->null_value())); |
2356 __ DropAndRet(4); | 2381 __ DropAndRet(4); |
2357 | 2382 |
2358 // Process the result from the native regexp code. | 2383 // Process the result from the native regexp code. |
2359 __ bind(&success); | 2384 __ bind(&success); |
2360 __ lw(a1, | 2385 __ lw(a1, |
2361 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); | 2386 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); |
(...skipping 2879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5241 kStackUnwindSpace, kInvalidStackOffset, | 5266 kStackUnwindSpace, kInvalidStackOffset, |
5242 MemOperand(fp, 6 * kPointerSize), NULL); | 5267 MemOperand(fp, 6 * kPointerSize), NULL); |
5243 } | 5268 } |
5244 | 5269 |
5245 | 5270 |
5246 #undef __ | 5271 #undef __ |
5247 | 5272 |
5248 } } // namespace v8::internal | 5273 } } // namespace v8::internal |
5249 | 5274 |
5250 #endif // V8_TARGET_ARCH_MIPS | 5275 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |