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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
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 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 isolate->set_fp_stubs_generated(true); | 1025 isolate->set_fp_stubs_generated(true); |
1026 } | 1026 } |
1027 | 1027 |
1028 | 1028 |
1029 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 1029 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
1030 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 1030 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
1031 stub.GetCode(); | 1031 stub.GetCode(); |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
| 1035 static void ThrowPendingException(MacroAssembler* masm) { |
| 1036 Isolate* isolate = masm->isolate(); |
| 1037 |
| 1038 ExternalReference pending_handler_context_address( |
| 1039 Isolate::kPendingHandlerContextAddress, isolate); |
| 1040 ExternalReference pending_handler_code_address( |
| 1041 Isolate::kPendingHandlerCodeAddress, isolate); |
| 1042 ExternalReference pending_handler_offset_address( |
| 1043 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 1044 ExternalReference pending_handler_fp_address( |
| 1045 Isolate::kPendingHandlerFPAddress, isolate); |
| 1046 ExternalReference pending_handler_sp_address( |
| 1047 Isolate::kPendingHandlerSPAddress, isolate); |
| 1048 |
| 1049 // Ask the runtime for help to determine the handler. This will set v0 to |
| 1050 // contain the current pending exception, don't clobber it. |
| 1051 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 1052 { |
| 1053 FrameScope scope(masm, StackFrame::MANUAL); |
| 1054 __ PrepareCallCFunction(3, 0, a0); |
| 1055 __ mov(a0, zero_reg); |
| 1056 __ mov(a1, zero_reg); |
| 1057 __ li(a2, Operand(ExternalReference::isolate_address(isolate))); |
| 1058 __ CallCFunction(find_handler, 3); |
| 1059 } |
| 1060 |
| 1061 // Retrieve the handler context, SP and FP. |
| 1062 __ li(cp, Operand(pending_handler_context_address)); |
| 1063 __ ld(cp, MemOperand(cp)); |
| 1064 __ li(sp, Operand(pending_handler_sp_address)); |
| 1065 __ ld(sp, MemOperand(sp)); |
| 1066 __ li(fp, Operand(pending_handler_fp_address)); |
| 1067 __ ld(fp, MemOperand(fp)); |
| 1068 |
| 1069 // If the handler is a JS frame, restore the context to the frame. |
| 1070 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1071 // or cp. |
| 1072 Label zero; |
| 1073 __ Branch(&zero, eq, cp, Operand(zero_reg)); |
| 1074 __ sd(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1075 __ bind(&zero); |
| 1076 |
| 1077 // Compute the handler entry address and jump to it. |
| 1078 __ li(a1, Operand(pending_handler_code_address)); |
| 1079 __ ld(a1, MemOperand(a1)); |
| 1080 __ li(a2, Operand(pending_handler_offset_address)); |
| 1081 __ ld(a2, MemOperand(a2)); |
| 1082 __ Daddu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1083 __ Daddu(t9, a1, a2); |
| 1084 __ Jump(t9); |
| 1085 } |
| 1086 |
| 1087 |
1035 void CEntryStub::Generate(MacroAssembler* masm) { | 1088 void CEntryStub::Generate(MacroAssembler* masm) { |
1036 // Called from JavaScript; parameters are on stack as if calling JS function | 1089 // Called from JavaScript; parameters are on stack as if calling JS function |
1037 // a0: number of arguments including receiver | 1090 // a0: number of arguments including receiver |
1038 // a1: pointer to builtin function | 1091 // a1: pointer to builtin function |
1039 // fp: frame pointer (restored after C call) | 1092 // fp: frame pointer (restored after C call) |
1040 // sp: stack pointer (restored as callee's sp after C call) | 1093 // sp: stack pointer (restored as callee's sp after C call) |
1041 // cp: current context (C callee-saved) | 1094 // cp: current context (C callee-saved) |
1042 | 1095 |
1043 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1096 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
1044 | 1097 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 __ Branch(&okay, ne, v0, Operand(a4)); | 1162 __ Branch(&okay, ne, v0, Operand(a4)); |
1110 __ stop("The hole escaped"); | 1163 __ stop("The hole escaped"); |
1111 __ bind(&okay); | 1164 __ bind(&okay); |
1112 } | 1165 } |
1113 | 1166 |
1114 // Check result for exception sentinel. | 1167 // Check result for exception sentinel. |
1115 Label exception_returned; | 1168 Label exception_returned; |
1116 __ LoadRoot(a4, Heap::kExceptionRootIndex); | 1169 __ LoadRoot(a4, Heap::kExceptionRootIndex); |
1117 __ Branch(&exception_returned, eq, a4, Operand(v0)); | 1170 __ Branch(&exception_returned, eq, a4, Operand(v0)); |
1118 | 1171 |
1119 ExternalReference pending_exception_address( | |
1120 Isolate::kPendingExceptionAddress, isolate()); | |
1121 | |
1122 // Check that there is no pending exception, otherwise we | 1172 // Check that there is no pending exception, otherwise we |
1123 // should have returned the exception sentinel. | 1173 // should have returned the exception sentinel. |
1124 if (FLAG_debug_code) { | 1174 if (FLAG_debug_code) { |
1125 Label okay; | 1175 Label okay; |
| 1176 ExternalReference pending_exception_address( |
| 1177 Isolate::kPendingExceptionAddress, isolate()); |
1126 __ li(a2, Operand(pending_exception_address)); | 1178 __ li(a2, Operand(pending_exception_address)); |
1127 __ ld(a2, MemOperand(a2)); | 1179 __ ld(a2, MemOperand(a2)); |
1128 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); | 1180 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); |
1129 // Cannot use check here as it attempts to generate call into runtime. | 1181 // Cannot use check here as it attempts to generate call into runtime. |
1130 __ Branch(&okay, eq, a4, Operand(a2)); | 1182 __ Branch(&okay, eq, a4, Operand(a2)); |
1131 __ stop("Unexpected pending exception"); | 1183 __ stop("Unexpected pending exception"); |
1132 __ bind(&okay); | 1184 __ bind(&okay); |
1133 } | 1185 } |
1134 | 1186 |
1135 // Exit C frame and return. | 1187 // Exit C frame and return. |
1136 // v0:v1: result | 1188 // v0:v1: result |
1137 // sp: stack pointer | 1189 // sp: stack pointer |
1138 // fp: frame pointer | 1190 // fp: frame pointer |
1139 // s0: still holds argc (callee-saved). | 1191 // s0: still holds argc (callee-saved). |
1140 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); | 1192 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); |
1141 | 1193 |
1142 // Handling of exception. | 1194 // Handling of exception. |
1143 __ bind(&exception_returned); | 1195 __ bind(&exception_returned); |
1144 | 1196 ThrowPendingException(masm); |
1145 // Retrieve the pending exception. | |
1146 __ li(a2, Operand(pending_exception_address)); | |
1147 __ ld(v0, MemOperand(a2)); | |
1148 | |
1149 // Clear the pending exception. | |
1150 __ li(a3, Operand(isolate()->factory()->the_hole_value())); | |
1151 __ sd(a3, MemOperand(a2)); | |
1152 | |
1153 // Special handling of termination exceptions which are uncatchable | |
1154 // by javascript code. | |
1155 Label throw_termination_exception; | |
1156 __ LoadRoot(a4, Heap::kTerminationExceptionRootIndex); | |
1157 __ Branch(&throw_termination_exception, eq, v0, Operand(a4)); | |
1158 | |
1159 // Handle normal exception. | |
1160 __ Throw(v0); | |
1161 | |
1162 __ bind(&throw_termination_exception); | |
1163 __ ThrowUncatchable(v0); | |
1164 } | 1197 } |
1165 | 1198 |
1166 | 1199 |
1167 void JSEntryStub::Generate(MacroAssembler* masm) { | 1200 void JSEntryStub::Generate(MacroAssembler* masm) { |
1168 Label invoke, handler_entry, exit; | 1201 Label invoke, handler_entry, exit; |
1169 Isolate* isolate = masm->isolate(); | 1202 Isolate* isolate = masm->isolate(); |
1170 | 1203 |
1171 // TODO(plind): unify the ABI description here. | 1204 // TODO(plind): unify the ABI description here. |
1172 // Registers: | 1205 // Registers: |
1173 // a0: entry address | 1206 // a0: entry address |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 // Result must now be exception. If there is no pending exception already a | 2400 // Result must now be exception. If there is no pending exception already a |
2368 // stack overflow (on the backtrack stack) was detected in RegExp code but | 2401 // stack overflow (on the backtrack stack) was detected in RegExp code but |
2369 // haven't created the exception yet. Handle that in the runtime system. | 2402 // haven't created the exception yet. Handle that in the runtime system. |
2370 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2403 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2371 __ li(a1, Operand(isolate()->factory()->the_hole_value())); | 2404 __ li(a1, Operand(isolate()->factory()->the_hole_value())); |
2372 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2405 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2373 isolate()))); | 2406 isolate()))); |
2374 __ ld(v0, MemOperand(a2, 0)); | 2407 __ ld(v0, MemOperand(a2, 0)); |
2375 __ Branch(&runtime, eq, v0, Operand(a1)); | 2408 __ Branch(&runtime, eq, v0, Operand(a1)); |
2376 | 2409 |
2377 __ sd(a1, MemOperand(a2, 0)); // Clear pending exception. | 2410 // For exception, throw the exception again. |
2378 | 2411 __ EnterExitFrame(false); |
2379 // Check if the exception is a termination. If so, throw as uncatchable. | 2412 ThrowPendingException(masm); |
2380 __ LoadRoot(a0, Heap::kTerminationExceptionRootIndex); | |
2381 Label termination_exception; | |
2382 __ Branch(&termination_exception, eq, v0, Operand(a0)); | |
2383 | |
2384 __ Throw(v0); | |
2385 | |
2386 __ bind(&termination_exception); | |
2387 __ ThrowUncatchable(v0); | |
2388 | 2413 |
2389 __ bind(&failure); | 2414 __ bind(&failure); |
2390 // For failure and exception return null. | 2415 // For failure and exception return null. |
2391 __ li(v0, Operand(isolate()->factory()->null_value())); | 2416 __ li(v0, Operand(isolate()->factory()->null_value())); |
2392 __ DropAndRet(4); | 2417 __ DropAndRet(4); |
2393 | 2418 |
2394 // Process the result from the native regexp code. | 2419 // Process the result from the native regexp code. |
2395 __ bind(&success); | 2420 __ bind(&success); |
2396 | 2421 |
2397 __ lw(a1, UntagSmiFieldMemOperand( | 2422 __ lw(a1, UntagSmiFieldMemOperand( |
(...skipping 2886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5284 kStackUnwindSpace, kInvalidStackOffset, | 5309 kStackUnwindSpace, kInvalidStackOffset, |
5285 MemOperand(fp, 6 * kPointerSize), NULL); | 5310 MemOperand(fp, 6 * kPointerSize), NULL); |
5286 } | 5311 } |
5287 | 5312 |
5288 | 5313 |
5289 #undef __ | 5314 #undef __ |
5290 | 5315 |
5291 } } // namespace v8::internal | 5316 } } // namespace v8::internal |
5292 | 5317 |
5293 #endif // V8_TARGET_ARCH_MIPS64 | 5318 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |