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