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