| 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 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "lithium-allocator-inl.h" | 9 #include "lithium-allocator-inl.h" |
| 10 #include "x64/lithium-x64.h" | 10 #include "x64/lithium-x64.h" |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 LDummyUse(UseAny(current->OperandAt(0)))); | 842 LDummyUse(UseAny(current->OperandAt(0)))); |
| 843 } | 843 } |
| 844 for (int i = 1; i < current->OperandCount(); ++i) { | 844 for (int i = 1; i < current->OperandCount(); ++i) { |
| 845 if (current->OperandAt(i)->IsControlInstruction()) continue; | 845 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 846 LInstruction* dummy = | 846 LInstruction* dummy = |
| 847 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 847 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 848 dummy->set_hydrogen_value(current); | 848 dummy->set_hydrogen_value(current); |
| 849 chunk_->AddInstruction(dummy, current_block_); | 849 chunk_->AddInstruction(dummy, current_block_); |
| 850 } | 850 } |
| 851 } else { | 851 } else { |
| 852 instr = current->CompileToLithium(this); | 852 HBasicBlock* successor; |
| 853 if (current->IsControlInstruction() && |
| 854 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 855 successor != NULL) { |
| 856 instr = new(zone()) LGoto(successor); |
| 857 } else { |
| 858 instr = current->CompileToLithium(this); |
| 859 } |
| 853 } | 860 } |
| 854 | 861 |
| 855 argument_count_ += current->argument_delta(); | 862 argument_count_ += current->argument_delta(); |
| 856 ASSERT(argument_count_ >= 0); | 863 ASSERT(argument_count_ >= 0); |
| 857 | 864 |
| 858 if (instr != NULL) { | 865 if (instr != NULL) { |
| 859 AddInstruction(instr, current); | 866 AddInstruction(instr, current); |
| 860 } | 867 } |
| 861 | 868 |
| 862 current_instruction_ = old_current; | 869 current_instruction_ = old_current; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 return new(zone()) LGoto(instr->FirstSuccessor()); | 940 return new(zone()) LGoto(instr->FirstSuccessor()); |
| 934 } | 941 } |
| 935 | 942 |
| 936 | 943 |
| 937 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 944 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
| 938 return new(zone()) LDebugBreak(); | 945 return new(zone()) LDebugBreak(); |
| 939 } | 946 } |
| 940 | 947 |
| 941 | 948 |
| 942 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 949 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 943 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 944 if (goto_instr != NULL) return goto_instr; | |
| 945 | |
| 946 HValue* value = instr->value(); | 950 HValue* value = instr->value(); |
| 947 Representation r = value->representation(); | 951 Representation r = value->representation(); |
| 948 HType type = value->type(); | 952 HType type = value->type(); |
| 949 ToBooleanStub::Types expected = instr->expected_input_types(); | 953 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 950 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 954 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); |
| 951 | 955 |
| 952 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || | 956 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || |
| 953 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); | 957 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); |
| 954 LInstruction* branch = new(zone()) LBranch(UseRegister(value)); | 958 LInstruction* branch = new(zone()) LBranch(UseRegister(value)); |
| 955 if (!easy_case && | 959 if (!easy_case && |
| 956 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || | 960 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || |
| 957 !expected.IsGeneric())) { | 961 !expected.IsGeneric())) { |
| 958 branch = AssignEnvironment(branch); | 962 branch = AssignEnvironment(branch); |
| 959 } | 963 } |
| 960 return branch; | 964 return branch; |
| 961 } | 965 } |
| 962 | 966 |
| 963 | 967 |
| 964 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 968 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 965 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 966 if (goto_instr != NULL) return goto_instr; | |
| 967 | |
| 968 ASSERT(instr->value()->representation().IsTagged()); | 969 ASSERT(instr->value()->representation().IsTagged()); |
| 969 LOperand* value = UseRegisterAtStart(instr->value()); | 970 LOperand* value = UseRegisterAtStart(instr->value()); |
| 970 return new(zone()) LCmpMapAndBranch(value); | 971 return new(zone()) LCmpMapAndBranch(value); |
| 971 } | 972 } |
| 972 | 973 |
| 973 | 974 |
| 974 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 975 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 975 info()->MarkAsRequiresFrame(); | 976 info()->MarkAsRequiresFrame(); |
| 976 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 977 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
| 977 } | 978 } |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 LOperand* context = UseFixed(instr->context(), rsi); | 1603 LOperand* context = UseFixed(instr->context(), rsi); |
| 1603 LOperand* left = UseFixed(instr->left(), rdx); | 1604 LOperand* left = UseFixed(instr->left(), rdx); |
| 1604 LOperand* right = UseFixed(instr->right(), rax); | 1605 LOperand* right = UseFixed(instr->right(), rax); |
| 1605 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1606 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1606 return MarkAsCall(DefineFixed(result, rax), instr); | 1607 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1607 } | 1608 } |
| 1608 | 1609 |
| 1609 | 1610 |
| 1610 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1611 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
| 1611 HCompareNumericAndBranch* instr) { | 1612 HCompareNumericAndBranch* instr) { |
| 1612 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 1613 if (goto_instr != NULL) return goto_instr; | |
| 1614 Representation r = instr->representation(); | 1613 Representation r = instr->representation(); |
| 1615 if (r.IsSmiOrInteger32()) { | 1614 if (r.IsSmiOrInteger32()) { |
| 1616 ASSERT(instr->left()->representation().Equals(r)); | 1615 ASSERT(instr->left()->representation().Equals(r)); |
| 1617 ASSERT(instr->right()->representation().Equals(r)); | 1616 ASSERT(instr->right()->representation().Equals(r)); |
| 1618 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1617 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
| 1619 LOperand* right = UseOrConstantAtStart(instr->right()); | 1618 LOperand* right = UseOrConstantAtStart(instr->right()); |
| 1620 return new(zone()) LCompareNumericAndBranch(left, right); | 1619 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1621 } else { | 1620 } else { |
| 1622 ASSERT(r.IsDouble()); | 1621 ASSERT(r.IsDouble()); |
| 1623 ASSERT(instr->left()->representation().IsDouble()); | 1622 ASSERT(instr->left()->representation().IsDouble()); |
| 1624 ASSERT(instr->right()->representation().IsDouble()); | 1623 ASSERT(instr->right()->representation().IsDouble()); |
| 1625 LOperand* left; | 1624 LOperand* left; |
| 1626 LOperand* right; | 1625 LOperand* right; |
| 1627 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { | 1626 if (instr->left()->IsConstant() && instr->right()->IsConstant()) { |
| 1628 left = UseRegisterOrConstantAtStart(instr->left()); | 1627 left = UseRegisterOrConstantAtStart(instr->left()); |
| 1629 right = UseRegisterOrConstantAtStart(instr->right()); | 1628 right = UseRegisterOrConstantAtStart(instr->right()); |
| 1630 } else { | 1629 } else { |
| 1631 left = UseRegisterAtStart(instr->left()); | 1630 left = UseRegisterAtStart(instr->left()); |
| 1632 right = UseRegisterAtStart(instr->right()); | 1631 right = UseRegisterAtStart(instr->right()); |
| 1633 } | 1632 } |
| 1634 return new(zone()) LCompareNumericAndBranch(left, right); | 1633 return new(zone()) LCompareNumericAndBranch(left, right); |
| 1635 } | 1634 } |
| 1636 } | 1635 } |
| 1637 | 1636 |
| 1638 | 1637 |
| 1639 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1638 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
| 1640 HCompareObjectEqAndBranch* instr) { | 1639 HCompareObjectEqAndBranch* instr) { |
| 1641 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 1642 if (goto_instr != NULL) return goto_instr; | |
| 1643 LOperand* left = UseRegisterAtStart(instr->left()); | 1640 LOperand* left = UseRegisterAtStart(instr->left()); |
| 1644 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1641 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
| 1645 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1642 return new(zone()) LCmpObjectEqAndBranch(left, right); |
| 1646 } | 1643 } |
| 1647 | 1644 |
| 1648 | 1645 |
| 1649 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1646 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
| 1650 HCompareHoleAndBranch* instr) { | 1647 HCompareHoleAndBranch* instr) { |
| 1651 LOperand* value = UseRegisterAtStart(instr->value()); | 1648 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1652 return new(zone()) LCmpHoleAndBranch(value); | 1649 return new(zone()) LCmpHoleAndBranch(value); |
| 1653 } | 1650 } |
| 1654 | 1651 |
| 1655 | 1652 |
| 1656 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1653 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
| 1657 HCompareMinusZeroAndBranch* instr) { | 1654 HCompareMinusZeroAndBranch* instr) { |
| 1658 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 1659 if (goto_instr != NULL) return goto_instr; | |
| 1660 LOperand* value = UseRegister(instr->value()); | 1655 LOperand* value = UseRegister(instr->value()); |
| 1661 return new(zone()) LCompareMinusZeroAndBranch(value); | 1656 return new(zone()) LCompareMinusZeroAndBranch(value); |
| 1662 } | 1657 } |
| 1663 | 1658 |
| 1664 | 1659 |
| 1665 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1660 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
| 1666 ASSERT(instr->value()->representation().IsTagged()); | 1661 ASSERT(instr->value()->representation().IsTagged()); |
| 1667 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); | 1662 return new(zone()) LIsObjectAndBranch(UseRegisterAtStart(instr->value())); |
| 1668 } | 1663 } |
| 1669 | 1664 |
| (...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2489 | 2484 |
| 2490 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2485 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
| 2491 LOperand* context = UseFixed(instr->context(), rsi); | 2486 LOperand* context = UseFixed(instr->context(), rsi); |
| 2492 LOperand* value = UseAtStart(instr->value()); | 2487 LOperand* value = UseAtStart(instr->value()); |
| 2493 LTypeof* result = new(zone()) LTypeof(context, value); | 2488 LTypeof* result = new(zone()) LTypeof(context, value); |
| 2494 return MarkAsCall(DefineFixed(result, rax), instr); | 2489 return MarkAsCall(DefineFixed(result, rax), instr); |
| 2495 } | 2490 } |
| 2496 | 2491 |
| 2497 | 2492 |
| 2498 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2493 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
| 2499 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
| 2500 if (goto_instr != NULL) return goto_instr; | |
| 2501 | |
| 2502 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); | 2494 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); |
| 2503 } | 2495 } |
| 2504 | 2496 |
| 2505 | 2497 |
| 2506 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2498 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| 2507 HIsConstructCallAndBranch* instr) { | 2499 HIsConstructCallAndBranch* instr) { |
| 2508 return new(zone()) LIsConstructCallAndBranch(TempRegister()); | 2500 return new(zone()) LIsConstructCallAndBranch(TempRegister()); |
| 2509 } | 2501 } |
| 2510 | 2502 |
| 2511 | 2503 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2595 LOperand* index = UseTempRegister(instr->index()); | 2587 LOperand* index = UseTempRegister(instr->index()); |
| 2596 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2588 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
| 2597 LInstruction* result = DefineSameAsFirst(load); | 2589 LInstruction* result = DefineSameAsFirst(load); |
| 2598 return AssignPointerMap(result); | 2590 return AssignPointerMap(result); |
| 2599 } | 2591 } |
| 2600 | 2592 |
| 2601 | 2593 |
| 2602 } } // namespace v8::internal | 2594 } } // namespace v8::internal |
| 2603 | 2595 |
| 2604 #endif // V8_TARGET_ARCH_X64 | 2596 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |