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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1429 RelocInfo::CODE_TARGET, | 1429 RelocInfo::CODE_TARGET, |
1430 ne); | 1430 ne); |
1431 | 1431 |
1432 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 1432 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
1433 ParameterCount expected(0); | 1433 ParameterCount expected(0); |
1434 __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1434 __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1435 } | 1435 } |
1436 | 1436 |
1437 | 1437 |
1438 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1438 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1439 const int vectorOffset, |
1439 const int argumentsOffset, | 1440 const int argumentsOffset, |
1440 const int indexOffset, | 1441 const int indexOffset, |
1441 const int limitOffset) { | 1442 const int limitOffset) { |
1442 Label entry, loop; | 1443 Label entry, loop; |
1443 Register receiver = LoadDescriptor::ReceiverRegister(); | 1444 Register receiver = LoadDescriptor::ReceiverRegister(); |
1444 Register key = LoadDescriptor::NameRegister(); | 1445 Register key = LoadDescriptor::NameRegister(); |
1445 Register slot = LoadDescriptor::SlotRegister(); | 1446 Register slot = LoadDescriptor::SlotRegister(); |
1446 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1447 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1447 | 1448 |
1448 __ ldr(key, MemOperand(fp, indexOffset)); | 1449 __ ldr(key, MemOperand(fp, indexOffset)); |
1449 __ b(&entry); | 1450 __ b(&entry); |
1450 | 1451 |
1451 // Load the current argument from the arguments array. | 1452 // Load the current argument from the arguments array. |
1452 __ bind(&loop); | 1453 __ bind(&loop); |
1453 __ ldr(receiver, MemOperand(fp, argumentsOffset)); | 1454 __ ldr(receiver, MemOperand(fp, argumentsOffset)); |
1454 | 1455 |
1455 // Use inline caching to speed up access to arguments. | 1456 // Use inline caching to speed up access to arguments. |
1456 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1457 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1457 FeedbackVectorSpec spec(0, 1, kinds); | 1458 __ mov(slot, Operand(Smi::FromInt(slot_index))); |
1458 Handle<TypeFeedbackVector> feedback_vector = | 1459 __ ldr(vector, MemOperand(fp, vectorOffset)); |
1459 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1460 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1461 __ mov(slot, Operand(Smi::FromInt(index))); | |
1462 __ Move(vector, feedback_vector); | |
1463 Handle<Code> ic = | 1460 Handle<Code> ic = |
1464 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1461 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1465 __ Call(ic, RelocInfo::CODE_TARGET); | 1462 __ Call(ic, RelocInfo::CODE_TARGET); |
1466 | 1463 |
1467 // Push the nth argument. | 1464 // Push the nth argument. |
1468 __ push(r0); | 1465 __ push(r0); |
1469 | 1466 |
1470 __ ldr(key, MemOperand(fp, indexOffset)); | 1467 __ ldr(key, MemOperand(fp, indexOffset)); |
1471 __ add(key, key, Operand(1 << kSmiTagSize)); | 1468 __ add(key, key, Operand(1 << kSmiTagSize)); |
1472 __ str(key, MemOperand(fp, indexOffset)); | 1469 __ str(key, MemOperand(fp, indexOffset)); |
(...skipping 14 matching lines...) Expand all Loading... |
1487 // Used by FunctionApply and ReflectApply | 1484 // Used by FunctionApply and ReflectApply |
1488 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { | 1485 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { |
1489 const int kFormalParameters = targetIsArgument ? 3 : 2; | 1486 const int kFormalParameters = targetIsArgument ? 3 : 2; |
1490 const int kStackSize = kFormalParameters + 1; | 1487 const int kStackSize = kFormalParameters + 1; |
1491 | 1488 |
1492 { | 1489 { |
1493 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); | 1490 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
1494 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1491 const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1495 const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1492 const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1496 const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1493 const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1494 const int kVectorOffset = |
| 1495 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1496 |
| 1497 // Push the vector. |
| 1498 __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1499 __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1500 __ Push(r1); |
1497 | 1501 |
1498 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function | 1502 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function |
1499 __ push(r0); | 1503 __ push(r0); |
1500 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1504 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1501 __ push(r0); | 1505 __ push(r0); |
1502 if (targetIsArgument) { | 1506 if (targetIsArgument) { |
1503 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1507 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1504 } else { | 1508 } else { |
1505 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1509 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1506 } | 1510 } |
1507 | 1511 |
1508 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); | 1512 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); |
1509 | 1513 |
1510 // Push current limit and index. | 1514 // Push current limit and index. |
1511 const int kIndexOffset = | 1515 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1512 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1516 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1513 const int kLimitOffset = | |
1514 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1515 __ push(r0); // limit | 1517 __ push(r0); // limit |
1516 __ mov(r1, Operand::Zero()); // initial index | 1518 __ mov(r1, Operand::Zero()); // initial index |
1517 __ push(r1); | 1519 __ push(r1); |
1518 | 1520 |
1519 // Get the receiver. | 1521 // Get the receiver. |
1520 __ ldr(r0, MemOperand(fp, kReceiverOffset)); | 1522 __ ldr(r0, MemOperand(fp, kReceiverOffset)); |
1521 | 1523 |
1522 // Check that the function is a JS function (otherwise it must be a proxy). | 1524 // Check that the function is a JS function (otherwise it must be a proxy). |
1523 Label push_receiver; | 1525 Label push_receiver; |
1524 __ ldr(r1, MemOperand(fp, kFunctionOffset)); | 1526 __ ldr(r1, MemOperand(fp, kFunctionOffset)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 __ bind(&use_global_proxy); | 1569 __ bind(&use_global_proxy); |
1568 __ ldr(r0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 1570 __ ldr(r0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
1569 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalProxyOffset)); | 1571 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalProxyOffset)); |
1570 | 1572 |
1571 // Push the receiver. | 1573 // Push the receiver. |
1572 // r0: receiver | 1574 // r0: receiver |
1573 __ bind(&push_receiver); | 1575 __ bind(&push_receiver); |
1574 __ push(r0); | 1576 __ push(r0); |
1575 | 1577 |
1576 // Copy all arguments from the array to the stack. | 1578 // Copy all arguments from the array to the stack. |
1577 Generate_PushAppliedArguments( | 1579 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1578 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1580 kIndexOffset, kLimitOffset); |
1579 | 1581 |
1580 // Call the function. | 1582 // Call the function. |
1581 Label call_proxy; | 1583 Label call_proxy; |
1582 ParameterCount actual(r0); | 1584 ParameterCount actual(r0); |
1583 __ ldr(r1, MemOperand(fp, kFunctionOffset)); | 1585 __ ldr(r1, MemOperand(fp, kFunctionOffset)); |
1584 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 1586 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
1585 __ b(ne, &call_proxy); | 1587 __ b(ne, &call_proxy); |
1586 __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper()); | 1588 __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper()); |
1587 | 1589 |
1588 frame_scope.GenerateLeaveFrame(); | 1590 frame_scope.GenerateLeaveFrame(); |
(...skipping 18 matching lines...) Expand all Loading... |
1607 | 1609 |
1608 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1610 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1609 const int kFormalParameters = 3; | 1611 const int kFormalParameters = 3; |
1610 const int kStackSize = kFormalParameters + 1; | 1612 const int kStackSize = kFormalParameters + 1; |
1611 | 1613 |
1612 { | 1614 { |
1613 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); | 1615 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
1614 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1616 const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1615 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1617 const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1616 const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1618 const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1619 static const int kVectorOffset = |
| 1620 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1621 |
| 1622 // Push the vector. |
| 1623 __ ldr(r1, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1624 __ ldr(r1, FieldMemOperand(r1, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1625 __ Push(r1); |
1617 | 1626 |
1618 // If newTarget is not supplied, set it to constructor | 1627 // If newTarget is not supplied, set it to constructor |
1619 Label validate_arguments; | 1628 Label validate_arguments; |
1620 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); | 1629 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); |
1621 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); | 1630 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
1622 __ b(ne, &validate_arguments); | 1631 __ b(ne, &validate_arguments); |
1623 __ ldr(r0, MemOperand(fp, kFunctionOffset)); | 1632 __ ldr(r0, MemOperand(fp, kFunctionOffset)); |
1624 __ str(r0, MemOperand(fp, kNewTargetOffset)); | 1633 __ str(r0, MemOperand(fp, kNewTargetOffset)); |
1625 | 1634 |
1626 // Validate arguments | 1635 // Validate arguments |
1627 __ bind(&validate_arguments); | 1636 __ bind(&validate_arguments); |
1628 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function | 1637 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function |
1629 __ push(r0); | 1638 __ push(r0); |
1630 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1639 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1631 __ push(r0); | 1640 __ push(r0); |
1632 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1641 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1633 __ push(r0); | 1642 __ push(r0); |
1634 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1643 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1635 | 1644 |
1636 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); | 1645 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); |
1637 | 1646 |
1638 // Push current limit and index. | 1647 // Push current limit and index. |
1639 const int kIndexOffset = | 1648 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
1640 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1649 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
1641 const int kLimitOffset = | |
1642 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | |
1643 __ push(r0); // limit | 1650 __ push(r0); // limit |
1644 __ mov(r1, Operand::Zero()); // initial index | 1651 __ mov(r1, Operand::Zero()); // initial index |
1645 __ push(r1); | 1652 __ push(r1); |
1646 // Push the constructor function as callee. | 1653 // Push the constructor function as callee. |
1647 __ ldr(r0, MemOperand(fp, kFunctionOffset)); | 1654 __ ldr(r0, MemOperand(fp, kFunctionOffset)); |
1648 __ push(r0); | 1655 __ push(r0); |
1649 | 1656 |
1650 // Copy all arguments from the array to the stack. | 1657 // Copy all arguments from the array to the stack. |
1651 Generate_PushAppliedArguments( | 1658 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1652 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1659 kIndexOffset, kLimitOffset); |
1653 | 1660 |
1654 // Use undefined feedback vector | 1661 // Use undefined feedback vector |
1655 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 1662 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
1656 __ ldr(r1, MemOperand(fp, kFunctionOffset)); | 1663 __ ldr(r1, MemOperand(fp, kFunctionOffset)); |
1657 __ ldr(r4, MemOperand(fp, kNewTargetOffset)); | 1664 __ ldr(r4, MemOperand(fp, kNewTargetOffset)); |
1658 | 1665 |
1659 // Call the function. | 1666 // Call the function. |
1660 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1667 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1661 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1668 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1662 | 1669 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 } | 1874 } |
1868 } | 1875 } |
1869 | 1876 |
1870 | 1877 |
1871 #undef __ | 1878 #undef __ |
1872 | 1879 |
1873 } // namespace internal | 1880 } // namespace internal |
1874 } // namespace v8 | 1881 } // namespace v8 |
1875 | 1882 |
1876 #endif // V8_TARGET_ARCH_ARM | 1883 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |