| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 8714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8725 } | 8725 } |
| 8726 | 8726 |
| 8727 | 8727 |
| 8728 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( | 8728 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
| 8729 BinaryOperation* expr, | 8729 BinaryOperation* expr, |
| 8730 HValue* left, | 8730 HValue* left, |
| 8731 HValue* right) { | 8731 HValue* right) { |
| 8732 Handle<Type> left_type = expr->left()->bounds().lower; | 8732 Handle<Type> left_type = expr->left()->bounds().lower; |
| 8733 Handle<Type> right_type = expr->right()->bounds().lower; | 8733 Handle<Type> right_type = expr->right()->bounds().lower; |
| 8734 Handle<Type> result_type = expr->bounds().lower; | 8734 Handle<Type> result_type = expr->bounds().lower; |
| 8735 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | |
| 8736 | 8735 |
| 8737 HValue* result = HGraphBuilder::BuildBinaryOperation( | 8736 HValue* result = HGraphBuilder::BuildBinaryOperation( |
| 8738 expr->op(), left, right, left_type, right_type, | 8737 expr->op(), left, right, left_type, right_type, result_type); |
| 8739 result_type, fixed_right_arg); | |
| 8740 // Add a simulate after instructions with observable side effects, and | 8738 // Add a simulate after instructions with observable side effects, and |
| 8741 // after phis, which are the result of BuildBinaryOperation when we | 8739 // after phis, which are the result of BuildBinaryOperation when we |
| 8742 // inlined some complex subgraph. | 8740 // inlined some complex subgraph. |
| 8743 if (result->HasObservableSideEffects() || result->IsPhi()) { | 8741 if (result->HasObservableSideEffects() || result->IsPhi()) { |
| 8744 Push(result); | 8742 Push(result); |
| 8745 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 8743 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 8746 Drop(1); | 8744 Drop(1); |
| 8747 } | 8745 } |
| 8748 return result; | 8746 return result; |
| 8749 } | 8747 } |
| 8750 | 8748 |
| 8751 | 8749 |
| 8752 HValue* HGraphBuilder::BuildBinaryOperation( | 8750 HValue* HGraphBuilder::BuildBinaryOperation( |
| 8753 Token::Value op, | 8751 Token::Value op, |
| 8754 HValue* left, | 8752 HValue* left, |
| 8755 HValue* right, | 8753 HValue* right, |
| 8756 Handle<Type> left_type, | 8754 Handle<Type> left_type, |
| 8757 Handle<Type> right_type, | 8755 Handle<Type> right_type, |
| 8758 Handle<Type> result_type, | 8756 Handle<Type> result_type) { |
| 8759 Maybe<int> fixed_right_arg) { | |
| 8760 | 8757 |
| 8761 Representation left_rep = Representation::FromType(left_type); | 8758 Representation left_rep = Representation::FromType(left_type); |
| 8762 Representation right_rep = Representation::FromType(right_type); | 8759 Representation right_rep = Representation::FromType(right_type); |
| 8763 | 8760 |
| 8764 bool maybe_string_add = op == Token::ADD && | |
| 8765 (left_type->Maybe(Type::String()) || | |
| 8766 right_type->Maybe(Type::String())); | |
| 8767 | |
| 8768 if (left_type->Is(Type::None())) { | 8761 if (left_type->Is(Type::None())) { |
| 8769 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", | 8762 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", |
| 8770 Deoptimizer::SOFT); | 8763 Deoptimizer::SOFT); |
| 8771 // TODO(rossberg): we should be able to get rid of non-continuous | 8764 // TODO(rossberg): we should be able to get rid of non-continuous |
| 8772 // defaults. | 8765 // defaults. |
| 8773 left_type = handle(Type::Any(), isolate()); | 8766 left_type = handle(Type::Any(), isolate()); |
| 8774 } else { | 8767 } else if (left_type->IsConstant()) { |
| 8775 if (!maybe_string_add) left = TruncateToNumber(left, &left_type); | 8768 HConstant* c_left = Add<HConstant>(left_type->AsConstant()); |
| 8776 left_rep = Representation::FromType(left_type); | 8769 IfBuilder if_same(this); |
| 8770 if (c_left->HasDoubleValue()) { |
| 8771 if_same.If<HCompareNumericAndBranch>(left, c_left, Token::EQ); |
| 8772 } else { |
| 8773 if_same.If<HCompareObjectEqAndBranch>(left, c_left); |
| 8774 } |
| 8775 if_same.Then(); |
| 8776 if_same.ElseDeopt("Unexpected LHS of binary operation"); |
| 8777 left = c_left; |
| 8777 } | 8778 } |
| 8778 | 8779 |
| 8779 if (right_type->Is(Type::None())) { | 8780 if (right_type->Is(Type::None())) { |
| 8780 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", | 8781 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", |
| 8781 Deoptimizer::SOFT); | 8782 Deoptimizer::SOFT); |
| 8782 right_type = handle(Type::Any(), isolate()); | 8783 right_type = handle(Type::Any(), isolate()); |
| 8783 } else { | 8784 } else if (right_type->IsConstant()) { |
| 8784 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); | 8785 HConstant* c_right = Add<HConstant>(right_type->AsConstant()); |
| 8785 right_rep = Representation::FromType(right_type); | 8786 IfBuilder if_same(this); |
| 8787 if (c_right->HasDoubleValue()) { |
| 8788 if_same.If<HCompareNumericAndBranch>(right, c_right, Token::EQ); |
| 8789 } else { |
| 8790 if_same.If<HCompareObjectEqAndBranch>(right, c_right); |
| 8791 } |
| 8792 if_same.Then(); |
| 8793 if_same.ElseDeopt("Unexpected RHS of binary operation"); |
| 8794 right = c_right; |
| 8786 } | 8795 } |
| 8787 | 8796 |
| 8788 // Special case for string addition here. | 8797 // Special case for string addition here. |
| 8789 if (op == Token::ADD && | 8798 if (op == Token::ADD && |
| 8790 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { | 8799 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { |
| 8791 // Validate type feedback for left argument. | 8800 // Validate type feedback for left argument. |
| 8792 if (left_type->Is(Type::String())) { | 8801 if (left_type->Is(Type::String())) { |
| 8793 left = BuildCheckString(left); | 8802 left = BuildCheckString(left); |
| 8794 } | 8803 } |
| 8795 | 8804 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8818 ASSERT(left_type->Is(Type::String())); | 8827 ASSERT(left_type->Is(Type::String())); |
| 8819 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 8828 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
| 8820 Add<HPushArgument>(left); | 8829 Add<HPushArgument>(left); |
| 8821 Add<HPushArgument>(right); | 8830 Add<HPushArgument>(right); |
| 8822 return AddUncasted<HInvokeFunction>(function, 2); | 8831 return AddUncasted<HInvokeFunction>(function, 2); |
| 8823 } | 8832 } |
| 8824 | 8833 |
| 8825 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); | 8834 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); |
| 8826 } | 8835 } |
| 8827 | 8836 |
| 8837 left = TruncateToNumber(left, &left_type); |
| 8838 left_rep = Representation::FromType(left_type); |
| 8839 right = TruncateToNumber(right, &right_type); |
| 8840 right_rep = Representation::FromType(right_type); |
| 8841 |
| 8828 if (graph()->info()->IsStub()) { | 8842 if (graph()->info()->IsStub()) { |
| 8829 left = EnforceNumberType(left, left_type); | 8843 left = EnforceNumberType(left, left_type); |
| 8830 right = EnforceNumberType(right, right_type); | 8844 right = EnforceNumberType(right, right_type); |
| 8831 } | 8845 } |
| 8832 | 8846 |
| 8833 Representation result_rep = Representation::FromType(result_type); | 8847 Representation result_rep = Representation::FromType(result_type); |
| 8834 | 8848 |
| 8835 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 8849 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
| 8836 (right_rep.IsTagged() && !right_rep.IsSmi()); | 8850 (right_rep.IsTagged() && !right_rep.IsSmi()); |
| 8837 | 8851 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8849 case Token::ADD: | 8863 case Token::ADD: |
| 8850 instr = AddUncasted<HAdd>(left, right); | 8864 instr = AddUncasted<HAdd>(left, right); |
| 8851 break; | 8865 break; |
| 8852 case Token::SUB: | 8866 case Token::SUB: |
| 8853 instr = AddUncasted<HSub>(left, right); | 8867 instr = AddUncasted<HSub>(left, right); |
| 8854 break; | 8868 break; |
| 8855 case Token::MUL: | 8869 case Token::MUL: |
| 8856 instr = AddUncasted<HMul>(left, right); | 8870 instr = AddUncasted<HMul>(left, right); |
| 8857 break; | 8871 break; |
| 8858 case Token::MOD: { | 8872 case Token::MOD: { |
| 8859 if (fixed_right_arg.has_value) { | |
| 8860 if (right->IsConstant()) { | |
| 8861 HConstant* c_right = HConstant::cast(right); | |
| 8862 if (c_right->HasInteger32Value()) { | |
| 8863 ASSERT_EQ(fixed_right_arg.value, c_right->Integer32Value()); | |
| 8864 } | |
| 8865 } else { | |
| 8866 HConstant* fixed_right = Add<HConstant>( | |
| 8867 static_cast<int>(fixed_right_arg.value)); | |
| 8868 IfBuilder if_same(this); | |
| 8869 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); | |
| 8870 if_same.Then(); | |
| 8871 if_same.ElseDeopt("Unexpected RHS of binary operation"); | |
| 8872 right = fixed_right; | |
| 8873 } | |
| 8874 } | |
| 8875 instr = AddUncasted<HMod>(left, right); | 8873 instr = AddUncasted<HMod>(left, right); |
| 8876 break; | 8874 break; |
| 8877 } | 8875 } |
| 8878 case Token::DIV: | 8876 case Token::DIV: |
| 8879 instr = AddUncasted<HDiv>(left, right); | 8877 instr = AddUncasted<HDiv>(left, right); |
| 8880 break; | 8878 break; |
| 8881 case Token::BIT_XOR: | 8879 case Token::BIT_XOR: |
| 8882 case Token::BIT_AND: | 8880 case Token::BIT_AND: |
| 8883 instr = AddUncasted<HBitwise>(op, left, right); | 8881 instr = AddUncasted<HBitwise>(op, left, right); |
| 8884 break; | 8882 break; |
| (...skipping 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10808 if (ShouldProduceTraceOutput()) { | 10806 if (ShouldProduceTraceOutput()) { |
| 10809 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10807 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10810 } | 10808 } |
| 10811 | 10809 |
| 10812 #ifdef DEBUG | 10810 #ifdef DEBUG |
| 10813 graph_->Verify(false); // No full verify. | 10811 graph_->Verify(false); // No full verify. |
| 10814 #endif | 10812 #endif |
| 10815 } | 10813 } |
| 10816 | 10814 |
| 10817 } } // namespace v8::internal | 10815 } } // namespace v8::internal |
| OLD | NEW |