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 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 __ Dsubu(a0, a0, Operand(1)); | 1243 __ Dsubu(a0, a0, Operand(1)); |
1244 __ Pop(); | 1244 __ Pop(); |
1245 } | 1245 } |
1246 | 1246 |
1247 // 4. Call the callable. | 1247 // 4. Call the callable. |
1248 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1248 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1249 } | 1249 } |
1250 | 1250 |
1251 | 1251 |
1252 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1252 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1253 const int vectorOffset, |
1253 const int argumentsOffset, | 1254 const int argumentsOffset, |
1254 const int indexOffset, | 1255 const int indexOffset, |
1255 const int limitOffset) { | 1256 const int limitOffset) { |
1256 Label entry, loop; | 1257 Label entry, loop; |
1257 Register receiver = LoadDescriptor::ReceiverRegister(); | 1258 Register receiver = LoadDescriptor::ReceiverRegister(); |
1258 Register key = LoadDescriptor::NameRegister(); | 1259 Register key = LoadDescriptor::NameRegister(); |
1259 Register slot = LoadDescriptor::SlotRegister(); | 1260 Register slot = LoadDescriptor::SlotRegister(); |
1260 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1261 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1261 | 1262 |
1262 __ ld(key, MemOperand(fp, indexOffset)); | 1263 __ ld(key, MemOperand(fp, indexOffset)); |
1263 __ Branch(&entry); | 1264 __ Branch(&entry); |
1264 | 1265 |
1265 // Load the current argument from the arguments array. | 1266 // Load the current argument from the arguments array. |
1266 __ bind(&loop); | 1267 __ bind(&loop); |
1267 __ ld(receiver, MemOperand(fp, argumentsOffset)); | 1268 __ ld(receiver, MemOperand(fp, argumentsOffset)); |
1268 | 1269 |
1269 // Use inline caching to speed up access to arguments. | 1270 // Use inline caching to speed up access to arguments. |
1270 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1271 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1271 FeedbackVectorSpec spec(0, 1, kinds); | 1272 __ li(slot, Operand(Smi::FromInt(slot_index))); |
1272 Handle<TypeFeedbackVector> feedback_vector = | 1273 __ ld(vector, MemOperand(fp, vectorOffset)); |
1273 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1274 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1275 __ li(slot, Operand(Smi::FromInt(index))); | |
1276 __ li(vector, feedback_vector); | |
1277 Handle<Code> ic = | 1274 Handle<Code> ic = |
1278 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1275 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1279 __ Call(ic, RelocInfo::CODE_TARGET); | 1276 __ Call(ic, RelocInfo::CODE_TARGET); |
1280 | 1277 |
1281 __ push(v0); | 1278 __ push(v0); |
1282 | 1279 |
1283 // Use inline caching to access the arguments. | 1280 // Use inline caching to access the arguments. |
1284 __ ld(key, MemOperand(fp, indexOffset)); | 1281 __ ld(key, MemOperand(fp, indexOffset)); |
1285 __ Daddu(key, key, Operand(Smi::FromInt(1))); | 1282 __ Daddu(key, key, Operand(Smi::FromInt(1))); |
1286 __ sd(key, MemOperand(fp, indexOffset)); | 1283 __ sd(key, MemOperand(fp, indexOffset)); |
(...skipping 13 matching lines...) Expand all Loading... |
1300 // Used by FunctionApply and ReflectApply | 1297 // Used by FunctionApply and ReflectApply |
1301 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { | 1298 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { |
1302 const int kFormalParameters = targetIsArgument ? 3 : 2; | 1299 const int kFormalParameters = targetIsArgument ? 3 : 2; |
1303 const int kStackSize = kFormalParameters + 1; | 1300 const int kStackSize = kFormalParameters + 1; |
1304 | 1301 |
1305 { | 1302 { |
1306 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1303 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1307 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1304 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1308 const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1305 const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1309 const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1306 const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1307 const int kVectorOffset = |
| 1308 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1309 |
| 1310 // Push the vector. |
| 1311 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1312 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1313 __ Push(a1); |
1310 | 1314 |
1311 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. | 1315 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. |
1312 __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. | 1316 __ ld(a1, MemOperand(fp, kArgumentsOffset)); // Get the args array. |
1313 __ Push(a0, a1); | 1317 __ Push(a0, a1); |
1314 | 1318 |
1315 // Returns (in v0) number of arguments to copy to stack as Smi. | 1319 // Returns (in v0) number of arguments to copy to stack as Smi. |
1316 if (targetIsArgument) { | 1320 if (targetIsArgument) { |
1317 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1321 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
1318 CALL_FUNCTION); | 1322 CALL_FUNCTION); |
1319 } else { | 1323 } else { |
1320 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1324 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
1321 } | 1325 } |
1322 | 1326 |
1323 // Returns the result in v0. | 1327 // Returns the result in v0. |
1324 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1328 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1325 | 1329 |
1326 // Push current limit and index. | 1330 // Push current limit and index. |
1327 const int kIndexOffset = | 1331 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1328 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1332 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1329 const int kLimitOffset = | |
1330 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1331 __ mov(a1, zero_reg); | 1333 __ mov(a1, zero_reg); |
1332 __ ld(a2, MemOperand(fp, kReceiverOffset)); | 1334 __ ld(a2, MemOperand(fp, kReceiverOffset)); |
1333 __ Push(v0, a1, a2); // limit, initial index and receiver. | 1335 __ Push(v0, a1, a2); // limit, initial index and receiver. |
1334 | 1336 |
1335 // Copy all arguments from the array to the stack. | 1337 // Copy all arguments from the array to the stack. |
1336 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset, | 1338 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1337 kLimitOffset); | 1339 kIndexOffset, kLimitOffset); |
1338 | 1340 |
1339 // Call the callable. | 1341 // Call the callable. |
1340 // TODO(bmeurer): This should be a tail call according to ES6. | 1342 // TODO(bmeurer): This should be a tail call according to ES6. |
1341 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1343 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
1342 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1344 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1343 | 1345 |
1344 // Tear down the internal frame and remove function, receiver and args. | 1346 // Tear down the internal frame and remove function, receiver and args. |
1345 } | 1347 } |
1346 | 1348 |
1347 __ Ret(USE_DELAY_SLOT); | 1349 __ Ret(USE_DELAY_SLOT); |
1348 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. | 1350 __ Daddu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. |
1349 } | 1351 } |
1350 | 1352 |
1351 | 1353 |
1352 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1354 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1353 const int kFormalParameters = 3; | 1355 const int kFormalParameters = 3; |
1354 const int kStackSize = kFormalParameters + 1; | 1356 const int kStackSize = kFormalParameters + 1; |
1355 | 1357 |
1356 { | 1358 { |
1357 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1359 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1358 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1360 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1359 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1361 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1360 const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1362 const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1363 const int kVectorOffset = |
| 1364 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1365 |
| 1366 // Push the vector. |
| 1367 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1368 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1369 __ Push(a1); |
1361 | 1370 |
1362 // If newTarget is not supplied, set it to constructor | 1371 // If newTarget is not supplied, set it to constructor |
1363 Label validate_arguments; | 1372 Label validate_arguments; |
1364 __ ld(a0, MemOperand(fp, kNewTargetOffset)); | 1373 __ ld(a0, MemOperand(fp, kNewTargetOffset)); |
1365 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1374 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
1366 __ Branch(&validate_arguments, ne, a0, Operand(at)); | 1375 __ Branch(&validate_arguments, ne, a0, Operand(at)); |
1367 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1376 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
1368 __ sd(a0, MemOperand(fp, kNewTargetOffset)); | 1377 __ sd(a0, MemOperand(fp, kNewTargetOffset)); |
1369 | 1378 |
1370 // Validate arguments | 1379 // Validate arguments |
1371 __ bind(&validate_arguments); | 1380 __ bind(&validate_arguments); |
1372 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function | 1381 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function |
1373 __ push(a0); | 1382 __ push(a0); |
1374 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1383 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1375 __ push(a0); | 1384 __ push(a0); |
1376 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1385 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1377 __ push(a0); | 1386 __ push(a0); |
1378 // Returns argument count in v0. | 1387 // Returns argument count in v0. |
1379 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1388 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
1380 CALL_FUNCTION); | 1389 CALL_FUNCTION); |
1381 | 1390 |
1382 // Returns result in v0. | 1391 // Returns result in v0. |
1383 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1392 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1384 | 1393 |
1385 // Push current limit and index. | 1394 // Push current limit and index. |
1386 const int kIndexOffset = | 1395 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1387 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1396 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1388 const int kLimitOffset = | |
1389 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1390 __ push(v0); // limit | 1397 __ push(v0); // limit |
1391 __ mov(a1, zero_reg); // initial index | 1398 __ mov(a1, zero_reg); // initial index |
1392 __ push(a1); | 1399 __ push(a1); |
1393 // Push the constructor function as callee. | 1400 // Push the constructor function as callee. |
1394 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1401 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
1395 __ push(a0); | 1402 __ push(a0); |
1396 | 1403 |
1397 // Copy all arguments from the array to the stack. | 1404 // Copy all arguments from the array to the stack. |
1398 Generate_PushAppliedArguments( | 1405 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1399 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1406 kIndexOffset, kLimitOffset); |
1400 | 1407 |
1401 // Use undefined feedback vector | 1408 // Use undefined feedback vector |
1402 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 1409 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
1403 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1410 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
1404 __ ld(a4, MemOperand(fp, kNewTargetOffset)); | 1411 __ ld(a4, MemOperand(fp, kNewTargetOffset)); |
1405 | 1412 |
1406 // Call the function. | 1413 // Call the function. |
1407 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1414 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1408 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1415 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1409 | 1416 |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 } | 1804 } |
1798 } | 1805 } |
1799 | 1806 |
1800 | 1807 |
1801 #undef __ | 1808 #undef __ |
1802 | 1809 |
1803 } // namespace internal | 1810 } // namespace internal |
1804 } // namespace v8 | 1811 } // namespace v8 |
1805 | 1812 |
1806 #endif // V8_TARGET_ARCH_MIPS64 | 1813 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |