| 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 |