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 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 isolate->set_fp_stubs_generated(true); | 1030 isolate->set_fp_stubs_generated(true); |
1031 } | 1031 } |
1032 | 1032 |
1033 | 1033 |
1034 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 1034 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
1035 CEntryStub stub(isolate, 1, kDontSaveFPRegs); | 1035 CEntryStub stub(isolate, 1, kDontSaveFPRegs); |
1036 stub.GetCode(); | 1036 stub.GetCode(); |
1037 } | 1037 } |
1038 | 1038 |
1039 | 1039 |
1040 static void ThrowPendingException(MacroAssembler* masm) { | |
1041 Isolate* isolate = masm->isolate(); | |
1042 | |
1043 ExternalReference pending_handler_context_address( | |
1044 Isolate::kPendingHandlerContextAddress, isolate); | |
1045 ExternalReference pending_handler_code_address( | |
1046 Isolate::kPendingHandlerCodeAddress, isolate); | |
1047 ExternalReference pending_handler_offset_address( | |
1048 Isolate::kPendingHandlerOffsetAddress, isolate); | |
1049 ExternalReference pending_handler_fp_address( | |
1050 Isolate::kPendingHandlerFPAddress, isolate); | |
1051 ExternalReference pending_handler_sp_address( | |
1052 Isolate::kPendingHandlerSPAddress, isolate); | |
1053 | |
1054 // Ask the runtime for help to determine the handler. This will set v0 to | |
1055 // contain the current pending exception, don't clobber it. | |
1056 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); | |
1057 { | |
1058 FrameScope scope(masm, StackFrame::MANUAL); | |
1059 __ PrepareCallCFunction(3, 0, a0); | |
1060 __ mov(a0, zero_reg); | |
1061 __ mov(a1, zero_reg); | |
1062 __ li(a2, Operand(ExternalReference::isolate_address(isolate))); | |
1063 __ CallCFunction(find_handler, 3); | |
1064 } | |
1065 | |
1066 // Retrieve the handler context, SP and FP. | |
1067 __ li(cp, Operand(pending_handler_context_address)); | |
1068 __ lw(cp, MemOperand(cp)); | |
1069 __ li(sp, Operand(pending_handler_sp_address)); | |
1070 __ lw(sp, MemOperand(sp)); | |
1071 __ li(fp, Operand(pending_handler_fp_address)); | |
1072 __ lw(fp, MemOperand(fp)); | |
1073 | |
1074 // If the handler is a JS frame, restore the context to the frame. | |
1075 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp | |
1076 // or cp. | |
1077 Label zero; | |
1078 __ Branch(&zero, eq, cp, Operand(zero_reg)); | |
1079 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
1080 __ bind(&zero); | |
1081 | |
1082 // Compute the handler entry address and jump to it. | |
1083 __ li(a1, Operand(pending_handler_code_address)); | |
1084 __ lw(a1, MemOperand(a1)); | |
1085 __ li(a2, Operand(pending_handler_offset_address)); | |
1086 __ lw(a2, MemOperand(a2)); | |
1087 __ Addu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
1088 __ Addu(t9, a1, a2); | |
1089 __ Jump(t9); | |
1090 } | |
1091 | |
1092 | |
1093 void CEntryStub::Generate(MacroAssembler* masm) { | 1040 void CEntryStub::Generate(MacroAssembler* masm) { |
1094 // Called from JavaScript; parameters are on stack as if calling JS function | 1041 // Called from JavaScript; parameters are on stack as if calling JS function |
1095 // a0: number of arguments including receiver | 1042 // a0: number of arguments including receiver |
1096 // a1: pointer to builtin function | 1043 // a1: pointer to builtin function |
1097 // fp: frame pointer (restored after C call) | 1044 // fp: frame pointer (restored after C call) |
1098 // sp: stack pointer (restored as callee's sp after C call) | 1045 // sp: stack pointer (restored as callee's sp after C call) |
1099 // cp: current context (C callee-saved) | 1046 // cp: current context (C callee-saved) |
1100 | 1047 |
1101 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1048 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
1102 | 1049 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 | 1139 |
1193 // Exit C frame and return. | 1140 // Exit C frame and return. |
1194 // v0:v1: result | 1141 // v0:v1: result |
1195 // sp: stack pointer | 1142 // sp: stack pointer |
1196 // fp: frame pointer | 1143 // fp: frame pointer |
1197 // s0: still holds argc (callee-saved). | 1144 // s0: still holds argc (callee-saved). |
1198 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); | 1145 __ LeaveExitFrame(save_doubles(), s0, true, EMIT_RETURN); |
1199 | 1146 |
1200 // Handling of exception. | 1147 // Handling of exception. |
1201 __ bind(&exception_returned); | 1148 __ bind(&exception_returned); |
1202 ThrowPendingException(masm); | 1149 |
| 1150 ExternalReference pending_handler_context_address( |
| 1151 Isolate::kPendingHandlerContextAddress, isolate()); |
| 1152 ExternalReference pending_handler_code_address( |
| 1153 Isolate::kPendingHandlerCodeAddress, isolate()); |
| 1154 ExternalReference pending_handler_offset_address( |
| 1155 Isolate::kPendingHandlerOffsetAddress, isolate()); |
| 1156 ExternalReference pending_handler_fp_address( |
| 1157 Isolate::kPendingHandlerFPAddress, isolate()); |
| 1158 ExternalReference pending_handler_sp_address( |
| 1159 Isolate::kPendingHandlerSPAddress, isolate()); |
| 1160 |
| 1161 // Ask the runtime for help to determine the handler. This will set v0 to |
| 1162 // contain the current pending exception, don't clobber it. |
| 1163 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate()); |
| 1164 { |
| 1165 FrameScope scope(masm, StackFrame::MANUAL); |
| 1166 __ PrepareCallCFunction(3, 0, a0); |
| 1167 __ mov(a0, zero_reg); |
| 1168 __ mov(a1, zero_reg); |
| 1169 __ li(a2, Operand(ExternalReference::isolate_address(isolate()))); |
| 1170 __ CallCFunction(find_handler, 3); |
| 1171 } |
| 1172 |
| 1173 // Retrieve the handler context, SP and FP. |
| 1174 __ li(cp, Operand(pending_handler_context_address)); |
| 1175 __ lw(cp, MemOperand(cp)); |
| 1176 __ li(sp, Operand(pending_handler_sp_address)); |
| 1177 __ lw(sp, MemOperand(sp)); |
| 1178 __ li(fp, Operand(pending_handler_fp_address)); |
| 1179 __ lw(fp, MemOperand(fp)); |
| 1180 |
| 1181 // If the handler is a JS frame, restore the context to the frame. |
| 1182 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp |
| 1183 // or cp. |
| 1184 Label zero; |
| 1185 __ Branch(&zero, eq, cp, Operand(zero_reg)); |
| 1186 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 1187 __ bind(&zero); |
| 1188 |
| 1189 // Compute the handler entry address and jump to it. |
| 1190 __ li(a1, Operand(pending_handler_code_address)); |
| 1191 __ lw(a1, MemOperand(a1)); |
| 1192 __ li(a2, Operand(pending_handler_offset_address)); |
| 1193 __ lw(a2, MemOperand(a2)); |
| 1194 __ Addu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1195 __ Addu(t9, a1, a2); |
| 1196 __ Jump(t9); |
1203 } | 1197 } |
1204 | 1198 |
1205 | 1199 |
1206 void JSEntryStub::Generate(MacroAssembler* masm) { | 1200 void JSEntryStub::Generate(MacroAssembler* masm) { |
1207 Label invoke, handler_entry, exit; | 1201 Label invoke, handler_entry, exit; |
1208 Isolate* isolate = masm->isolate(); | 1202 Isolate* isolate = masm->isolate(); |
1209 | 1203 |
1210 // Registers: | 1204 // Registers: |
1211 // a0: entry address | 1205 // a0: entry address |
1212 // a1: function | 1206 // a1: function |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 // stack overflow (on the backtrack stack) was detected in RegExp code but | 2360 // stack overflow (on the backtrack stack) was detected in RegExp code but |
2367 // haven't created the exception yet. Handle that in the runtime system. | 2361 // haven't created the exception yet. Handle that in the runtime system. |
2368 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2362 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2369 __ li(a1, Operand(isolate()->factory()->the_hole_value())); | 2363 __ li(a1, Operand(isolate()->factory()->the_hole_value())); |
2370 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2364 __ li(a2, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2371 isolate()))); | 2365 isolate()))); |
2372 __ lw(v0, MemOperand(a2, 0)); | 2366 __ lw(v0, MemOperand(a2, 0)); |
2373 __ Branch(&runtime, eq, v0, Operand(a1)); | 2367 __ Branch(&runtime, eq, v0, Operand(a1)); |
2374 | 2368 |
2375 // For exception, throw the exception again. | 2369 // For exception, throw the exception again. |
2376 __ EnterExitFrame(false); | 2370 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4, 1); |
2377 ThrowPendingException(masm); | |
2378 | 2371 |
2379 __ bind(&failure); | 2372 __ bind(&failure); |
2380 // For failure and exception return null. | 2373 // For failure and exception return null. |
2381 __ li(v0, Operand(isolate()->factory()->null_value())); | 2374 __ li(v0, Operand(isolate()->factory()->null_value())); |
2382 __ DropAndRet(4); | 2375 __ DropAndRet(4); |
2383 | 2376 |
2384 // Process the result from the native regexp code. | 2377 // Process the result from the native regexp code. |
2385 __ bind(&success); | 2378 __ bind(&success); |
2386 __ lw(a1, | 2379 __ lw(a1, |
2387 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); | 2380 FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset)); |
(...skipping 3114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5502 kStackUnwindSpace, kInvalidStackOffset, | 5495 kStackUnwindSpace, kInvalidStackOffset, |
5503 MemOperand(fp, 6 * kPointerSize), NULL); | 5496 MemOperand(fp, 6 * kPointerSize), NULL); |
5504 } | 5497 } |
5505 | 5498 |
5506 | 5499 |
5507 #undef __ | 5500 #undef __ |
5508 | 5501 |
5509 } } // namespace v8::internal | 5502 } } // namespace v8::internal |
5510 | 5503 |
5511 #endif // V8_TARGET_ARCH_MIPS | 5504 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |