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 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1421 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1422 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1422 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1423 | 1423 |
1424 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1424 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1425 ParameterCount expected(0); | 1425 ParameterCount expected(0); |
1426 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1426 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1427 } | 1427 } |
1428 | 1428 |
1429 | 1429 |
1430 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1430 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1431 const int vectorOffset, |
1431 const int argumentsOffset, | 1432 const int argumentsOffset, |
1432 const int indexOffset, | 1433 const int indexOffset, |
1433 const int limitOffset) { | 1434 const int limitOffset) { |
1434 Label entry, loop; | 1435 Label entry, loop; |
1435 Register receiver = LoadDescriptor::ReceiverRegister(); | 1436 Register receiver = LoadDescriptor::ReceiverRegister(); |
1436 Register key = LoadDescriptor::NameRegister(); | 1437 Register key = LoadDescriptor::NameRegister(); |
1437 Register slot = LoadDescriptor::SlotRegister(); | 1438 Register slot = LoadDescriptor::SlotRegister(); |
1438 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1439 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1439 | 1440 |
1440 __ ld(key, MemOperand(fp, indexOffset)); | 1441 __ ld(key, MemOperand(fp, indexOffset)); |
1441 __ Branch(&entry); | 1442 __ Branch(&entry); |
1442 | 1443 |
1443 // Load the current argument from the arguments array. | 1444 // Load the current argument from the arguments array. |
1444 __ bind(&loop); | 1445 __ bind(&loop); |
1445 __ ld(receiver, MemOperand(fp, argumentsOffset)); | 1446 __ ld(receiver, MemOperand(fp, argumentsOffset)); |
1446 | 1447 |
1447 // Use inline caching to speed up access to arguments. | 1448 // Use inline caching to speed up access to arguments. |
1448 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1449 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1449 FeedbackVectorSpec spec(0, 1, kinds); | 1450 __ li(slot, Operand(Smi::FromInt(slot_index))); |
1450 Handle<TypeFeedbackVector> feedback_vector = | 1451 __ ld(vector, MemOperand(fp, vectorOffset)); |
1451 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1452 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1453 __ li(slot, Operand(Smi::FromInt(index))); | |
1454 __ li(vector, feedback_vector); | |
1455 Handle<Code> ic = | 1452 Handle<Code> ic = |
1456 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1453 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1457 __ Call(ic, RelocInfo::CODE_TARGET); | 1454 __ Call(ic, RelocInfo::CODE_TARGET); |
1458 | 1455 |
1459 __ push(v0); | 1456 __ push(v0); |
1460 | 1457 |
1461 // Use inline caching to access the arguments. | 1458 // Use inline caching to access the arguments. |
1462 __ ld(key, MemOperand(fp, indexOffset)); | 1459 __ ld(key, MemOperand(fp, indexOffset)); |
1463 __ Daddu(key, key, Operand(Smi::FromInt(1))); | 1460 __ Daddu(key, key, Operand(Smi::FromInt(1))); |
1464 __ sd(key, MemOperand(fp, indexOffset)); | 1461 __ sd(key, MemOperand(fp, indexOffset)); |
(...skipping 13 matching lines...) Expand all Loading... |
1478 // Used by FunctionApply and ReflectApply | 1475 // Used by FunctionApply and ReflectApply |
1479 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { | 1476 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { |
1480 const int kFormalParameters = targetIsArgument ? 3 : 2; | 1477 const int kFormalParameters = targetIsArgument ? 3 : 2; |
1481 const int kStackSize = kFormalParameters + 1; | 1478 const int kStackSize = kFormalParameters + 1; |
1482 | 1479 |
1483 { | 1480 { |
1484 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1481 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1485 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1482 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1486 const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1483 const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1487 const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1484 const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1485 const int kVectorOffset = |
| 1486 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1487 |
| 1488 // Push the vector. |
| 1489 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1490 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1491 __ Push(a1); |
1488 | 1492 |
1489 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. | 1493 __ ld(a0, MemOperand(fp, kFunctionOffset)); // Get the function. |
1490 __ push(a0); | 1494 __ push(a0); |
1491 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. | 1495 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. |
1492 __ push(a0); | 1496 __ push(a0); |
1493 | 1497 |
1494 // Returns (in v0) number of arguments to copy to stack as Smi. | 1498 // Returns (in v0) number of arguments to copy to stack as Smi. |
1495 if (targetIsArgument) { | 1499 if (targetIsArgument) { |
1496 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1500 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1497 } else { | 1501 } else { |
1498 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1502 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1499 } | 1503 } |
1500 | 1504 |
1501 // Returns the result in v0. | 1505 // Returns the result in v0. |
1502 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1506 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1503 | 1507 |
1504 // Push current limit and index. | 1508 // Push current limit and index. |
1505 const int kIndexOffset = | 1509 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1506 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1510 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1507 const int kLimitOffset = | |
1508 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1509 __ mov(a1, zero_reg); | 1511 __ mov(a1, zero_reg); |
1510 __ Push(v0, a1); // Limit and initial index. | 1512 __ Push(v0, a1); // Limit and initial index. |
1511 | 1513 |
1512 // Get the receiver. | 1514 // Get the receiver. |
1513 __ ld(a0, MemOperand(fp, kReceiverOffset)); | 1515 __ ld(a0, MemOperand(fp, kReceiverOffset)); |
1514 | 1516 |
1515 // Check that the function is a JS function (otherwise it must be a proxy). | 1517 // Check that the function is a JS function (otherwise it must be a proxy). |
1516 Label push_receiver; | 1518 Label push_receiver; |
1517 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1519 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
1518 __ GetObjectType(a1, a2, a2); | 1520 __ GetObjectType(a1, a2, a2); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 __ bind(&use_global_proxy); | 1561 __ bind(&use_global_proxy); |
1560 __ ld(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 1562 __ ld(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
1561 __ ld(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset)); | 1563 __ ld(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset)); |
1562 | 1564 |
1563 // Push the receiver. | 1565 // Push the receiver. |
1564 // a0: receiver | 1566 // a0: receiver |
1565 __ bind(&push_receiver); | 1567 __ bind(&push_receiver); |
1566 __ push(a0); | 1568 __ push(a0); |
1567 | 1569 |
1568 // Copy all arguments from the array to the stack. | 1570 // Copy all arguments from the array to the stack. |
1569 Generate_PushAppliedArguments( | 1571 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1570 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1572 kIndexOffset, kLimitOffset); |
1571 | 1573 |
1572 // Call the function. | 1574 // Call the function. |
1573 Label call_proxy; | 1575 Label call_proxy; |
1574 ParameterCount actual(a0); | 1576 ParameterCount actual(a0); |
1575 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1577 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
1576 __ GetObjectType(a1, a2, a2); | 1578 __ GetObjectType(a1, a2, a2); |
1577 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); | 1579 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); |
1578 | 1580 |
1579 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); | 1581 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); |
1580 | 1582 |
(...skipping 19 matching lines...) Expand all Loading... |
1600 | 1602 |
1601 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1603 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1602 const int kFormalParameters = 3; | 1604 const int kFormalParameters = 3; |
1603 const int kStackSize = kFormalParameters + 1; | 1605 const int kStackSize = kFormalParameters + 1; |
1604 | 1606 |
1605 { | 1607 { |
1606 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1608 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1607 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1609 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1608 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1610 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1609 const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1611 const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1612 const int kVectorOffset = |
| 1613 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1614 |
| 1615 // Push the vector. |
| 1616 __ ld(a1, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1617 __ ld(a1, FieldMemOperand(a1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1618 __ Push(a1); |
1610 | 1619 |
1611 // If newTarget is not supplied, set it to constructor | 1620 // If newTarget is not supplied, set it to constructor |
1612 Label validate_arguments; | 1621 Label validate_arguments; |
1613 __ ld(a0, MemOperand(fp, kNewTargetOffset)); | 1622 __ ld(a0, MemOperand(fp, kNewTargetOffset)); |
1614 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1623 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
1615 __ Branch(&validate_arguments, ne, a0, Operand(at)); | 1624 __ Branch(&validate_arguments, ne, a0, Operand(at)); |
1616 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1625 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
1617 __ sd(a0, MemOperand(fp, kNewTargetOffset)); | 1626 __ sd(a0, MemOperand(fp, kNewTargetOffset)); |
1618 | 1627 |
1619 // Validate arguments | 1628 // Validate arguments |
1620 __ bind(&validate_arguments); | 1629 __ bind(&validate_arguments); |
1621 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function | 1630 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function |
1622 __ push(a0); | 1631 __ push(a0); |
1623 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1632 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1624 __ push(a0); | 1633 __ push(a0); |
1625 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1634 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1626 __ push(a0); | 1635 __ push(a0); |
1627 // Returns argument count in v0. | 1636 // Returns argument count in v0. |
1628 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1637 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1629 | 1638 |
1630 // Returns result in v0. | 1639 // Returns result in v0. |
1631 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); | 1640 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1632 | 1641 |
1633 // Push current limit and index. | 1642 // Push current limit and index. |
1634 const int kIndexOffset = | 1643 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1635 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1644 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1636 const int kLimitOffset = | |
1637 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1638 __ push(v0); // limit | 1645 __ push(v0); // limit |
1639 __ mov(a1, zero_reg); // initial index | 1646 __ mov(a1, zero_reg); // initial index |
1640 __ push(a1); | 1647 __ push(a1); |
1641 // Push the constructor function as callee. | 1648 // Push the constructor function as callee. |
1642 __ ld(a0, MemOperand(fp, kFunctionOffset)); | 1649 __ ld(a0, MemOperand(fp, kFunctionOffset)); |
1643 __ push(a0); | 1650 __ push(a0); |
1644 | 1651 |
1645 // Copy all arguments from the array to the stack. | 1652 // Copy all arguments from the array to the stack. |
1646 Generate_PushAppliedArguments( | 1653 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1647 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1654 kIndexOffset, kLimitOffset); |
1648 | 1655 |
1649 // Use undefined feedback vector | 1656 // Use undefined feedback vector |
1650 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 1657 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
1651 __ ld(a1, MemOperand(fp, kFunctionOffset)); | 1658 __ ld(a1, MemOperand(fp, kFunctionOffset)); |
1652 __ ld(a4, MemOperand(fp, kNewTargetOffset)); | 1659 __ ld(a4, MemOperand(fp, kNewTargetOffset)); |
1653 | 1660 |
1654 // Call the function. | 1661 // Call the function. |
1655 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1662 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1656 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1663 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1657 | 1664 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 } | 1881 } |
1875 } | 1882 } |
1876 | 1883 |
1877 | 1884 |
1878 #undef __ | 1885 #undef __ |
1879 | 1886 |
1880 } // namespace internal | 1887 } // namespace internal |
1881 } // namespace v8 | 1888 } // namespace v8 |
1882 | 1889 |
1883 #endif // V8_TARGET_ARCH_MIPS64 | 1890 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |