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 #include "lithium-allocator-inl.h" | 7 #include "lithium-allocator-inl.h" |
8 #include "arm/lithium-arm.h" | 8 #include "arm/lithium-arm.h" |
9 #include "arm/lithium-codegen-arm.h" | 9 #include "arm/lithium-codegen-arm.h" |
10 #include "hydrogen-osr.h" | 10 #include "hydrogen-osr.h" |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 LDummyUse(UseAny(current->OperandAt(0)))); | 834 LDummyUse(UseAny(current->OperandAt(0)))); |
835 } | 835 } |
836 for (int i = 1; i < current->OperandCount(); ++i) { | 836 for (int i = 1; i < current->OperandCount(); ++i) { |
837 if (current->OperandAt(i)->IsControlInstruction()) continue; | 837 if (current->OperandAt(i)->IsControlInstruction()) continue; |
838 LInstruction* dummy = | 838 LInstruction* dummy = |
839 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 839 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
840 dummy->set_hydrogen_value(current); | 840 dummy->set_hydrogen_value(current); |
841 chunk_->AddInstruction(dummy, current_block_); | 841 chunk_->AddInstruction(dummy, current_block_); |
842 } | 842 } |
843 } else { | 843 } else { |
844 instr = current->CompileToLithium(this); | 844 HBasicBlock* successor; |
| 845 if (current->IsControlInstruction() && |
| 846 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 847 successor != NULL) { |
| 848 instr = new(zone()) LGoto(successor); |
| 849 } else { |
| 850 instr = current->CompileToLithium(this); |
| 851 } |
845 } | 852 } |
846 | 853 |
847 argument_count_ += current->argument_delta(); | 854 argument_count_ += current->argument_delta(); |
848 ASSERT(argument_count_ >= 0); | 855 ASSERT(argument_count_ >= 0); |
849 | 856 |
850 if (instr != NULL) { | 857 if (instr != NULL) { |
851 AddInstruction(instr, current); | 858 AddInstruction(instr, current); |
852 } | 859 } |
853 | 860 |
854 current_instruction_ = old_current; | 861 current_instruction_ = old_current; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 } | 927 } |
921 } | 928 } |
922 | 929 |
923 | 930 |
924 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 931 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
925 return new(zone()) LGoto(instr->FirstSuccessor()); | 932 return new(zone()) LGoto(instr->FirstSuccessor()); |
926 } | 933 } |
927 | 934 |
928 | 935 |
929 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 936 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
930 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
931 if (goto_instr != NULL) return goto_instr; | |
932 | |
933 HValue* value = instr->value(); | 937 HValue* value = instr->value(); |
934 Representation r = value->representation(); | 938 Representation r = value->representation(); |
935 HType type = value->type(); | 939 HType type = value->type(); |
936 ToBooleanStub::Types expected = instr->expected_input_types(); | 940 ToBooleanStub::Types expected = instr->expected_input_types(); |
937 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 941 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); |
938 | 942 |
939 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || | 943 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || |
940 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); | 944 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); |
941 LInstruction* branch = new(zone()) LBranch(UseRegister(value)); | 945 LInstruction* branch = new(zone()) LBranch(UseRegister(value)); |
942 if (!easy_case && | 946 if (!easy_case && |
943 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || | 947 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || |
944 !expected.IsGeneric())) { | 948 !expected.IsGeneric())) { |
945 branch = AssignEnvironment(branch); | 949 branch = AssignEnvironment(branch); |
946 } | 950 } |
947 return branch; | 951 return branch; |
948 } | 952 } |
949 | 953 |
950 | 954 |
951 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 955 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
952 return new(zone()) LDebugBreak(); | 956 return new(zone()) LDebugBreak(); |
953 } | 957 } |
954 | 958 |
955 | 959 |
956 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 960 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
957 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
958 if (goto_instr != NULL) return goto_instr; | |
959 | |
960 ASSERT(instr->value()->representation().IsTagged()); | 961 ASSERT(instr->value()->representation().IsTagged()); |
961 LOperand* value = UseRegisterAtStart(instr->value()); | 962 LOperand* value = UseRegisterAtStart(instr->value()); |
962 LOperand* temp = TempRegister(); | 963 LOperand* temp = TempRegister(); |
963 return new(zone()) LCmpMapAndBranch(value, temp); | 964 return new(zone()) LCmpMapAndBranch(value, temp); |
964 } | 965 } |
965 | 966 |
966 | 967 |
967 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) { | 968 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) { |
968 info()->MarkAsRequiresFrame(); | 969 info()->MarkAsRequiresFrame(); |
969 LOperand* value = UseRegister(instr->value()); | 970 LOperand* value = UseRegister(instr->value()); |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1675 LOperand* context = UseFixed(instr->context(), cp); | 1676 LOperand* context = UseFixed(instr->context(), cp); |
1676 LOperand* left = UseFixed(instr->left(), r1); | 1677 LOperand* left = UseFixed(instr->left(), r1); |
1677 LOperand* right = UseFixed(instr->right(), r0); | 1678 LOperand* right = UseFixed(instr->right(), r0); |
1678 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1679 LCmpT* result = new(zone()) LCmpT(context, left, right); |
1679 return MarkAsCall(DefineFixed(result, r0), instr); | 1680 return MarkAsCall(DefineFixed(result, r0), instr); |
1680 } | 1681 } |
1681 | 1682 |
1682 | 1683 |
1683 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1684 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
1684 HCompareNumericAndBranch* instr) { | 1685 HCompareNumericAndBranch* instr) { |
1685 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1686 if (goto_instr != NULL) return goto_instr; | |
1687 Representation r = instr->representation(); | 1686 Representation r = instr->representation(); |
1688 if (r.IsSmiOrInteger32()) { | 1687 if (r.IsSmiOrInteger32()) { |
1689 ASSERT(instr->left()->representation().Equals(r)); | 1688 ASSERT(instr->left()->representation().Equals(r)); |
1690 ASSERT(instr->right()->representation().Equals(r)); | 1689 ASSERT(instr->right()->representation().Equals(r)); |
1691 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1690 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
1692 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1691 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
1693 return new(zone()) LCompareNumericAndBranch(left, right); | 1692 return new(zone()) LCompareNumericAndBranch(left, right); |
1694 } else { | 1693 } else { |
1695 ASSERT(r.IsDouble()); | 1694 ASSERT(r.IsDouble()); |
1696 ASSERT(instr->left()->representation().IsDouble()); | 1695 ASSERT(instr->left()->representation().IsDouble()); |
1697 ASSERT(instr->right()->representation().IsDouble()); | 1696 ASSERT(instr->right()->representation().IsDouble()); |
1698 LOperand* left = UseRegisterAtStart(instr->left()); | 1697 LOperand* left = UseRegisterAtStart(instr->left()); |
1699 LOperand* right = UseRegisterAtStart(instr->right()); | 1698 LOperand* right = UseRegisterAtStart(instr->right()); |
1700 return new(zone()) LCompareNumericAndBranch(left, right); | 1699 return new(zone()) LCompareNumericAndBranch(left, right); |
1701 } | 1700 } |
1702 } | 1701 } |
1703 | 1702 |
1704 | 1703 |
1705 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1704 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1706 HCompareObjectEqAndBranch* instr) { | 1705 HCompareObjectEqAndBranch* instr) { |
1707 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1708 if (goto_instr != NULL) return goto_instr; | |
1709 LOperand* left = UseRegisterAtStart(instr->left()); | 1706 LOperand* left = UseRegisterAtStart(instr->left()); |
1710 LOperand* right = UseRegisterAtStart(instr->right()); | 1707 LOperand* right = UseRegisterAtStart(instr->right()); |
1711 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1708 return new(zone()) LCmpObjectEqAndBranch(left, right); |
1712 } | 1709 } |
1713 | 1710 |
1714 | 1711 |
1715 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1712 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
1716 HCompareHoleAndBranch* instr) { | 1713 HCompareHoleAndBranch* instr) { |
1717 LOperand* value = UseRegisterAtStart(instr->value()); | 1714 LOperand* value = UseRegisterAtStart(instr->value()); |
1718 return new(zone()) LCmpHoleAndBranch(value); | 1715 return new(zone()) LCmpHoleAndBranch(value); |
1719 } | 1716 } |
1720 | 1717 |
1721 | 1718 |
1722 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1719 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
1723 HCompareMinusZeroAndBranch* instr) { | 1720 HCompareMinusZeroAndBranch* instr) { |
1724 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1725 if (goto_instr != NULL) return goto_instr; | |
1726 LOperand* value = UseRegister(instr->value()); | 1721 LOperand* value = UseRegister(instr->value()); |
1727 LOperand* scratch = TempRegister(); | 1722 LOperand* scratch = TempRegister(); |
1728 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1723 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
1729 } | 1724 } |
1730 | 1725 |
1731 | 1726 |
1732 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1727 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
1733 ASSERT(instr->value()->representation().IsTagged()); | 1728 ASSERT(instr->value()->representation().IsTagged()); |
1734 LOperand* value = UseRegisterAtStart(instr->value()); | 1729 LOperand* value = UseRegisterAtStart(instr->value()); |
1735 LOperand* temp = TempRegister(); | 1730 LOperand* temp = TempRegister(); |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 | 2483 |
2489 | 2484 |
2490 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2485 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
2491 LOperand* context = UseFixed(instr->context(), cp); | 2486 LOperand* context = UseFixed(instr->context(), cp); |
2492 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); | 2487 LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); |
2493 return MarkAsCall(DefineFixed(result, r0), instr); | 2488 return MarkAsCall(DefineFixed(result, r0), instr); |
2494 } | 2489 } |
2495 | 2490 |
2496 | 2491 |
2497 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2492 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
2498 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
2499 if (goto_instr != NULL) return goto_instr; | |
2500 | |
2501 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value())); | 2493 return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value())); |
2502 } | 2494 } |
2503 | 2495 |
2504 | 2496 |
2505 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2497 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
2506 HIsConstructCallAndBranch* instr) { | 2498 HIsConstructCallAndBranch* instr) { |
2507 return new(zone()) LIsConstructCallAndBranch(TempRegister()); | 2499 return new(zone()) LIsConstructCallAndBranch(TempRegister()); |
2508 } | 2500 } |
2509 | 2501 |
2510 | 2502 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 | 2581 |
2590 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2582 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2591 LOperand* object = UseRegister(instr->object()); | 2583 LOperand* object = UseRegister(instr->object()); |
2592 LOperand* index = UseTempRegister(instr->index()); | 2584 LOperand* index = UseTempRegister(instr->index()); |
2593 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2585 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
2594 LInstruction* result = DefineSameAsFirst(load); | 2586 LInstruction* result = DefineSameAsFirst(load); |
2595 return AssignPointerMap(result); | 2587 return AssignPointerMap(result); |
2596 } | 2588 } |
2597 | 2589 |
2598 } } // namespace v8::internal | 2590 } } // namespace v8::internal |
OLD | NEW |