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 |