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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "lithium-allocator-inl.h" | 9 #include "lithium-allocator-inl.h" |
10 #include "ia32/lithium-ia32.h" | 10 #include "ia32/lithium-ia32.h" |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 LDummyUse(UseAny(current->OperandAt(0)))); | 875 LDummyUse(UseAny(current->OperandAt(0)))); |
876 } | 876 } |
877 for (int i = 1; i < current->OperandCount(); ++i) { | 877 for (int i = 1; i < current->OperandCount(); ++i) { |
878 if (current->OperandAt(i)->IsControlInstruction()) continue; | 878 if (current->OperandAt(i)->IsControlInstruction()) continue; |
879 LInstruction* dummy = | 879 LInstruction* dummy = |
880 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 880 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
881 dummy->set_hydrogen_value(current); | 881 dummy->set_hydrogen_value(current); |
882 chunk_->AddInstruction(dummy, current_block_); | 882 chunk_->AddInstruction(dummy, current_block_); |
883 } | 883 } |
884 } else { | 884 } else { |
885 instr = current->CompileToLithium(this); | 885 HBasicBlock* successor; |
| 886 if (current->IsControlInstruction() && |
| 887 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 888 successor != NULL) { |
| 889 instr = new(zone()) LGoto(successor); |
| 890 } else { |
| 891 instr = current->CompileToLithium(this); |
| 892 } |
886 } | 893 } |
887 | 894 |
888 argument_count_ += current->argument_delta(); | 895 argument_count_ += current->argument_delta(); |
889 ASSERT(argument_count_ >= 0); | 896 ASSERT(argument_count_ >= 0); |
890 | 897 |
891 if (instr != NULL) { | 898 if (instr != NULL) { |
892 AddInstruction(instr, current); | 899 AddInstruction(instr, current); |
893 } | 900 } |
894 | 901 |
895 current_instruction_ = old_current; | 902 current_instruction_ = old_current; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 } | 968 } |
962 } | 969 } |
963 | 970 |
964 | 971 |
965 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 972 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
966 return new(zone()) LGoto(instr->FirstSuccessor()); | 973 return new(zone()) LGoto(instr->FirstSuccessor()); |
967 } | 974 } |
968 | 975 |
969 | 976 |
970 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 977 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
971 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
972 if (goto_instr != NULL) return goto_instr; | |
973 | |
974 HValue* value = instr->value(); | 978 HValue* value = instr->value(); |
975 Representation r = value->representation(); | 979 Representation r = value->representation(); |
976 HType type = value->type(); | 980 HType type = value->type(); |
977 ToBooleanStub::Types expected = instr->expected_input_types(); | 981 ToBooleanStub::Types expected = instr->expected_input_types(); |
978 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 982 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); |
979 | 983 |
980 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || | 984 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() || |
981 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); | 985 type.IsJSArray() || type.IsHeapNumber() || type.IsString(); |
982 LOperand* temp = !easy_case && expected.NeedsMap() ? TempRegister() : NULL; | 986 LOperand* temp = !easy_case && expected.NeedsMap() ? TempRegister() : NULL; |
983 LInstruction* branch = new(zone()) LBranch(UseRegister(value), temp); | 987 LInstruction* branch = new(zone()) LBranch(UseRegister(value), temp); |
984 if (!easy_case && | 988 if (!easy_case && |
985 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || | 989 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) || |
986 !expected.IsGeneric())) { | 990 !expected.IsGeneric())) { |
987 branch = AssignEnvironment(branch); | 991 branch = AssignEnvironment(branch); |
988 } | 992 } |
989 return branch; | 993 return branch; |
990 } | 994 } |
991 | 995 |
992 | 996 |
993 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { | 997 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { |
994 return new(zone()) LDebugBreak(); | 998 return new(zone()) LDebugBreak(); |
995 } | 999 } |
996 | 1000 |
997 | 1001 |
998 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1002 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
999 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1000 if (goto_instr != NULL) return goto_instr; | |
1001 | |
1002 ASSERT(instr->value()->representation().IsTagged()); | 1003 ASSERT(instr->value()->representation().IsTagged()); |
1003 LOperand* value = UseRegisterAtStart(instr->value()); | 1004 LOperand* value = UseRegisterAtStart(instr->value()); |
1004 return new(zone()) LCmpMapAndBranch(value); | 1005 return new(zone()) LCmpMapAndBranch(value); |
1005 } | 1006 } |
1006 | 1007 |
1007 | 1008 |
1008 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 1009 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
1009 info()->MarkAsRequiresFrame(); | 1010 info()->MarkAsRequiresFrame(); |
1010 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 1011 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
1011 } | 1012 } |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1637 LOperand* context = UseFixed(instr->context(), esi); | 1638 LOperand* context = UseFixed(instr->context(), esi); |
1638 LOperand* left = UseFixed(instr->left(), edx); | 1639 LOperand* left = UseFixed(instr->left(), edx); |
1639 LOperand* right = UseFixed(instr->right(), eax); | 1640 LOperand* right = UseFixed(instr->right(), eax); |
1640 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1641 LCmpT* result = new(zone()) LCmpT(context, left, right); |
1641 return MarkAsCall(DefineFixed(result, eax), instr); | 1642 return MarkAsCall(DefineFixed(result, eax), instr); |
1642 } | 1643 } |
1643 | 1644 |
1644 | 1645 |
1645 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1646 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
1646 HCompareNumericAndBranch* instr) { | 1647 HCompareNumericAndBranch* instr) { |
1647 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1648 if (goto_instr != NULL) return goto_instr; | |
1649 Representation r = instr->representation(); | 1648 Representation r = instr->representation(); |
1650 if (r.IsSmiOrInteger32()) { | 1649 if (r.IsSmiOrInteger32()) { |
1651 ASSERT(instr->left()->representation().Equals(r)); | 1650 ASSERT(instr->left()->representation().Equals(r)); |
1652 ASSERT(instr->right()->representation().Equals(r)); | 1651 ASSERT(instr->right()->representation().Equals(r)); |
1653 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1652 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
1654 LOperand* right = UseOrConstantAtStart(instr->right()); | 1653 LOperand* right = UseOrConstantAtStart(instr->right()); |
1655 return new(zone()) LCompareNumericAndBranch(left, right); | 1654 return new(zone()) LCompareNumericAndBranch(left, right); |
1656 } else { | 1655 } else { |
1657 ASSERT(r.IsDouble()); | 1656 ASSERT(r.IsDouble()); |
1658 ASSERT(instr->left()->representation().IsDouble()); | 1657 ASSERT(instr->left()->representation().IsDouble()); |
(...skipping 10 matching lines...) Expand all Loading... |
1669 left = UseRegisterAtStart(instr->left()); | 1668 left = UseRegisterAtStart(instr->left()); |
1670 right = UseRegisterAtStart(instr->right()); | 1669 right = UseRegisterAtStart(instr->right()); |
1671 } | 1670 } |
1672 return new(zone()) LCompareNumericAndBranch(left, right); | 1671 return new(zone()) LCompareNumericAndBranch(left, right); |
1673 } | 1672 } |
1674 } | 1673 } |
1675 | 1674 |
1676 | 1675 |
1677 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1676 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1678 HCompareObjectEqAndBranch* instr) { | 1677 HCompareObjectEqAndBranch* instr) { |
1679 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1680 if (goto_instr != NULL) return goto_instr; | |
1681 LOperand* left = UseRegisterAtStart(instr->left()); | 1678 LOperand* left = UseRegisterAtStart(instr->left()); |
1682 LOperand* right = UseOrConstantAtStart(instr->right()); | 1679 LOperand* right = UseOrConstantAtStart(instr->right()); |
1683 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1680 return new(zone()) LCmpObjectEqAndBranch(left, right); |
1684 } | 1681 } |
1685 | 1682 |
1686 | 1683 |
1687 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( | 1684 LInstruction* LChunkBuilder::DoCompareHoleAndBranch( |
1688 HCompareHoleAndBranch* instr) { | 1685 HCompareHoleAndBranch* instr) { |
1689 LOperand* value = UseRegisterAtStart(instr->value()); | 1686 LOperand* value = UseRegisterAtStart(instr->value()); |
1690 return new(zone()) LCmpHoleAndBranch(value); | 1687 return new(zone()) LCmpHoleAndBranch(value); |
1691 } | 1688 } |
1692 | 1689 |
1693 | 1690 |
1694 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1691 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
1695 HCompareMinusZeroAndBranch* instr) { | 1692 HCompareMinusZeroAndBranch* instr) { |
1696 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1697 if (goto_instr != NULL) return goto_instr; | |
1698 LOperand* value = UseRegister(instr->value()); | 1693 LOperand* value = UseRegister(instr->value()); |
1699 LOperand* scratch = TempRegister(); | 1694 LOperand* scratch = TempRegister(); |
1700 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1695 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
1701 } | 1696 } |
1702 | 1697 |
1703 | 1698 |
1704 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1699 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
1705 ASSERT(instr->value()->representation().IsSmiOrTagged()); | 1700 ASSERT(instr->value()->representation().IsSmiOrTagged()); |
1706 LOperand* temp = TempRegister(); | 1701 LOperand* temp = TempRegister(); |
1707 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); | 1702 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp); |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2561 | 2556 |
2562 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 2557 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
2563 LOperand* context = UseFixed(instr->context(), esi); | 2558 LOperand* context = UseFixed(instr->context(), esi); |
2564 LOperand* value = UseAtStart(instr->value()); | 2559 LOperand* value = UseAtStart(instr->value()); |
2565 LTypeof* result = new(zone()) LTypeof(context, value); | 2560 LTypeof* result = new(zone()) LTypeof(context, value); |
2566 return MarkAsCall(DefineFixed(result, eax), instr); | 2561 return MarkAsCall(DefineFixed(result, eax), instr); |
2567 } | 2562 } |
2568 | 2563 |
2569 | 2564 |
2570 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2565 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
2571 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
2572 if (goto_instr != NULL) return goto_instr; | |
2573 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); | 2566 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value())); |
2574 } | 2567 } |
2575 | 2568 |
2576 | 2569 |
2577 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2570 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
2578 HIsConstructCallAndBranch* instr) { | 2571 HIsConstructCallAndBranch* instr) { |
2579 return new(zone()) LIsConstructCallAndBranch(TempRegister()); | 2572 return new(zone()) LIsConstructCallAndBranch(TempRegister()); |
2580 } | 2573 } |
2581 | 2574 |
2582 | 2575 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2665 LOperand* index = UseTempRegister(instr->index()); | 2658 LOperand* index = UseTempRegister(instr->index()); |
2666 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2659 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
2667 LInstruction* result = DefineSameAsFirst(load); | 2660 LInstruction* result = DefineSameAsFirst(load); |
2668 return AssignPointerMap(result); | 2661 return AssignPointerMap(result); |
2669 } | 2662 } |
2670 | 2663 |
2671 | 2664 |
2672 } } // namespace v8::internal | 2665 } } // namespace v8::internal |
2673 | 2666 |
2674 #endif // V8_TARGET_ARCH_IA32 | 2667 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |