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