OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 __ pop(a1); | 1167 __ pop(a1); |
1168 | 1168 |
1169 // Tear down temporary frame. | 1169 // Tear down temporary frame. |
1170 } | 1170 } |
1171 | 1171 |
1172 // Do a tail-call of the compiled function. | 1172 // Do a tail-call of the compiled function. |
1173 __ Jump(t9); | 1173 __ Jump(t9); |
1174 } | 1174 } |
1175 | 1175 |
1176 | 1176 |
1177 // These functions are called from C++ but cannot be used in live code. | 1177 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
| 1178 Deoptimizer::BailoutType type) { |
| 1179 { |
| 1180 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1181 // Pass the function and deoptimization type to the runtime system. |
| 1182 __ li(a0, Operand(Smi::FromInt(static_cast<int>(type)))); |
| 1183 __ push(a0); |
| 1184 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); |
| 1185 } |
| 1186 |
| 1187 // Get the full codegen state from the stack and untag it -> t2. |
| 1188 __ lw(t2, MemOperand(sp, 0 * kPointerSize)); |
| 1189 __ SmiUntag(t2); |
| 1190 // Switch on the state. |
| 1191 Label with_tos_register, unknown_state; |
| 1192 __ Branch(&with_tos_register, |
| 1193 ne, t2, Operand(FullCodeGenerator::NO_REGISTERS)); |
| 1194 __ Addu(sp, sp, Operand(1 * kPointerSize)); // Remove state. |
| 1195 __ Ret(); |
| 1196 |
| 1197 __ bind(&with_tos_register); |
| 1198 __ lw(v0, MemOperand(sp, 1 * kPointerSize)); |
| 1199 __ Branch(&unknown_state, ne, t2, Operand(FullCodeGenerator::TOS_REG)); |
| 1200 |
| 1201 __ Addu(sp, sp, Operand(2 * kPointerSize)); // Remove state. |
| 1202 __ Ret(); |
| 1203 |
| 1204 __ bind(&unknown_state); |
| 1205 __ stop("no cases left"); |
| 1206 } |
| 1207 |
| 1208 |
1178 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1209 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
1179 __ Abort("Call to unimplemented function in builtins-mips.cc"); | 1210 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
1180 } | 1211 } |
1181 | 1212 |
1182 | 1213 |
1183 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1214 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
1184 __ Abort("Call to unimplemented function in builtins-mips.cc"); | 1215 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
1185 } | 1216 } |
1186 | 1217 |
1187 | 1218 |
1188 void Builtins::Generate_NotifyOSR(MacroAssembler* masm) { | 1219 void Builtins::Generate_NotifyOSR(MacroAssembler* masm) { |
1189 __ Abort("Call to unimplemented function in builtins-mips.cc"); | 1220 // For now, we are relying on the fact that Runtime::NotifyOSR |
| 1221 // doesn't do any garbage collection which allows us to save/restore |
| 1222 // the registers without worrying about which of them contain |
| 1223 // pointers. This seems a bit fragile. |
| 1224 RegList saved_regs = |
| 1225 (kJSCallerSaved | kCalleeSaved | ra.bit() | fp.bit()) & ~sp.bit(); |
| 1226 __ MultiPush(saved_regs); |
| 1227 { |
| 1228 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1229 __ CallRuntime(Runtime::kNotifyOSR, 0); |
| 1230 } |
| 1231 __ MultiPop(saved_regs); |
| 1232 __ Ret(); |
1190 } | 1233 } |
1191 | 1234 |
1192 | 1235 |
1193 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1236 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1194 __ Abort("Call to unimplemented function in builtins-mips.cc"); | 1237 CpuFeatures::TryForceFeatureScope scope(VFP3); |
| 1238 if (!CpuFeatures::IsSupported(FPU)) { |
| 1239 __ Abort("Unreachable code: Cannot optimize without FPU support."); |
| 1240 return; |
| 1241 } |
| 1242 |
| 1243 // Lookup the function in the JavaScript frame and push it as an |
| 1244 // argument to the on-stack replacement function. |
| 1245 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1246 { |
| 1247 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1248 __ push(a0); |
| 1249 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); |
| 1250 } |
| 1251 |
| 1252 // If the result was -1 it means that we couldn't optimize the |
| 1253 // function. Just return and continue in the unoptimized version. |
| 1254 __ Ret(eq, v0, Operand(Smi::FromInt(-1))); |
| 1255 |
| 1256 // Untag the AST id and push it on the stack. |
| 1257 __ SmiUntag(v0); |
| 1258 __ push(v0); |
| 1259 |
| 1260 // Generate the code for doing the frame-to-frame translation using |
| 1261 // the deoptimizer infrastructure. |
| 1262 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
| 1263 generator.Generate(); |
1195 } | 1264 } |
1196 | 1265 |
1197 | 1266 |
1198 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 1267 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
1199 // 1. Make sure we have at least one argument. | 1268 // 1. Make sure we have at least one argument. |
1200 // a0: actual number of arguments | 1269 // a0: actual number of arguments |
1201 { Label done; | 1270 { Label done; |
1202 __ Branch(&done, ne, a0, Operand(zero_reg)); | 1271 __ Branch(&done, ne, a0, Operand(zero_reg)); |
1203 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); | 1272 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); |
1204 __ push(t2); | 1273 __ push(t2); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 | 1455 |
1387 | 1456 |
1388 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 1457 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
1389 const int kIndexOffset = -5 * kPointerSize; | 1458 const int kIndexOffset = -5 * kPointerSize; |
1390 const int kLimitOffset = -4 * kPointerSize; | 1459 const int kLimitOffset = -4 * kPointerSize; |
1391 const int kArgsOffset = 2 * kPointerSize; | 1460 const int kArgsOffset = 2 * kPointerSize; |
1392 const int kRecvOffset = 3 * kPointerSize; | 1461 const int kRecvOffset = 3 * kPointerSize; |
1393 const int kFunctionOffset = 4 * kPointerSize; | 1462 const int kFunctionOffset = 4 * kPointerSize; |
1394 | 1463 |
1395 { | 1464 { |
1396 FrameScope scope(masm, StackFrame::INTERNAL); | 1465 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1397 | |
1398 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. | 1466 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. |
1399 __ push(a0); | 1467 __ push(a0); |
1400 __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. | 1468 __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. |
1401 __ push(a0); | 1469 __ push(a0); |
1402 // Returns (in v0) number of arguments to copy to stack as Smi. | 1470 // Returns (in v0) number of arguments to copy to stack as Smi. |
1403 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1471 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1404 | 1472 |
1405 // Check the stack for overflow. We are not trying to catch | 1473 // Check the stack for overflow. We are not trying to catch |
1406 // interruptions (e.g. debug break and preemption) here, so the "real stack | 1474 // interruptions (e.g. debug break and preemption) here, so the "real stack |
1407 // limit" is checked. | 1475 // limit" is checked. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 Label call_proxy; | 1589 Label call_proxy; |
1522 ParameterCount actual(a0); | 1590 ParameterCount actual(a0); |
1523 __ sra(a0, a0, kSmiTagSize); | 1591 __ sra(a0, a0, kSmiTagSize); |
1524 __ lw(a1, MemOperand(fp, kFunctionOffset)); | 1592 __ lw(a1, MemOperand(fp, kFunctionOffset)); |
1525 __ GetObjectType(a1, a2, a2); | 1593 __ GetObjectType(a1, a2, a2); |
1526 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); | 1594 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); |
1527 | 1595 |
1528 __ InvokeFunction(a1, actual, CALL_FUNCTION, | 1596 __ InvokeFunction(a1, actual, CALL_FUNCTION, |
1529 NullCallWrapper(), CALL_AS_METHOD); | 1597 NullCallWrapper(), CALL_AS_METHOD); |
1530 | 1598 |
1531 scope.GenerateLeaveFrame(); | 1599 frame_scope.GenerateLeaveFrame(); |
1532 | |
1533 __ Ret(USE_DELAY_SLOT); | 1600 __ Ret(USE_DELAY_SLOT); |
1534 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. | 1601 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. |
1535 | 1602 |
1536 // Invoke the function proxy. | 1603 // Invoke the function proxy. |
1537 __ bind(&call_proxy); | 1604 __ bind(&call_proxy); |
1538 __ push(a1); // Add function proxy as last argument. | 1605 __ push(a1); // Add function proxy as last argument. |
1539 __ Addu(a0, a0, Operand(1)); | 1606 __ Addu(a0, a0, Operand(1)); |
1540 __ li(a2, Operand(0, RelocInfo::NONE)); | 1607 __ li(a2, Operand(0, RelocInfo::NONE)); |
1541 __ SetCallKind(t1, CALL_AS_METHOD); | 1608 __ SetCallKind(t1, CALL_AS_METHOD); |
1542 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 1609 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 __ bind(&dont_adapt_arguments); | 1754 __ bind(&dont_adapt_arguments); |
1688 __ Jump(a3); | 1755 __ Jump(a3); |
1689 } | 1756 } |
1690 | 1757 |
1691 | 1758 |
1692 #undef __ | 1759 #undef __ |
1693 | 1760 |
1694 } } // namespace v8::internal | 1761 } } // namespace v8::internal |
1695 | 1762 |
1696 #endif // V8_TARGET_ARCH_MIPS | 1763 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |