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 5916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5927 CHECK_ALIVE(VisitForValue(prop->key())); | 5927 CHECK_ALIVE(VisitForValue(prop->key())); |
5928 key = Top(); | 5928 key = Top(); |
5929 } | 5929 } |
5930 | 5930 |
5931 CHECK_ALIVE(PushLoad(prop, object, key)); | 5931 CHECK_ALIVE(PushLoad(prop, object, key)); |
5932 | 5932 |
5933 CHECK_ALIVE(VisitForValue(expr->value())); | 5933 CHECK_ALIVE(VisitForValue(expr->value())); |
5934 HValue* right = Pop(); | 5934 HValue* right = Pop(); |
5935 HValue* left = Pop(); | 5935 HValue* left = Pop(); |
5936 | 5936 |
5937 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5937 Push(BuildBinaryOperation(operation, left, right)); |
5938 AddInstruction(instr); | |
5939 Push(instr); | |
5940 if (instr->HasObservableSideEffects()) { | |
5941 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); | |
5942 } | |
5943 BuildStore(expr, prop, expr->id(), | 5938 BuildStore(expr, prop, expr->id(), |
5944 expr->AssignmentId(), expr->IsUninitialized()); | 5939 expr->AssignmentId(), expr->IsUninitialized()); |
5945 } else { | 5940 } else { |
5946 return Bailout(kInvalidLhsInCompoundAssignment); | 5941 return Bailout(kInvalidLhsInCompoundAssignment); |
5947 } | 5942 } |
5948 } | 5943 } |
5949 | 5944 |
5950 | 5945 |
5951 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { | 5946 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { |
5952 ASSERT(!HasStackOverflow()); | 5947 ASSERT(!HasStackOverflow()); |
(...skipping 2615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8568 // This is already done by HChange. | 8563 // This is already done by HChange. |
8569 *expected = handle(Type::Union( | 8564 *expected = handle(Type::Union( |
8570 expected_number, handle(Type::Double(), isolate())), isolate()); | 8565 expected_number, handle(Type::Double(), isolate())), isolate()); |
8571 return value; | 8566 return value; |
8572 } | 8567 } |
8573 | 8568 |
8574 return value; | 8569 return value; |
8575 } | 8570 } |
8576 | 8571 |
8577 | 8572 |
8578 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 8573 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( |
8579 BinaryOperation* expr, | 8574 BinaryOperation* expr, |
8580 HValue* left, | 8575 HValue* left, |
8581 HValue* right) { | 8576 HValue* right) { |
8582 Handle<Type> left_type = expr->left()->bounds().lower; | 8577 Handle<Type> left_type = expr->left()->bounds().lower; |
8583 Handle<Type> right_type = expr->right()->bounds().lower; | 8578 Handle<Type> right_type = expr->right()->bounds().lower; |
8584 Handle<Type> result_type = expr->bounds().lower; | 8579 Handle<Type> result_type = expr->bounds().lower; |
8585 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 8580 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
8586 | 8581 |
8587 return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right, | 8582 HValue* result = HGraphBuilder::BuildBinaryOperation( |
8588 left_type, right_type, result_type, fixed_right_arg); | 8583 expr->op(), left, right, left_type, right_type, |
| 8584 result_type, fixed_right_arg); |
| 8585 // Add a simulate after instructions with observable side effects, and |
| 8586 // after phis, which are the result of BuildBinaryOperation when we |
| 8587 // inlined some complex subgraph. |
| 8588 if (result->HasObservableSideEffects() || result->IsPhi()) { |
| 8589 Push(result); |
| 8590 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
| 8591 Drop(1); |
| 8592 } |
| 8593 return result; |
8589 } | 8594 } |
8590 | 8595 |
8591 | 8596 |
8592 HInstruction* HGraphBuilder::BuildBinaryOperation( | 8597 HValue* HGraphBuilder::BuildBinaryOperation( |
8593 Token::Value op, | 8598 Token::Value op, |
8594 HValue* left, | 8599 HValue* left, |
8595 HValue* right, | 8600 HValue* right, |
8596 Handle<Type> left_type, | 8601 Handle<Type> left_type, |
8597 Handle<Type> right_type, | 8602 Handle<Type> right_type, |
8598 Handle<Type> result_type, | 8603 Handle<Type> result_type, |
8599 Maybe<int> fixed_right_arg, | 8604 Maybe<int> fixed_right_arg, |
8600 bool binop_stub) { | 8605 bool binop_stub) { |
8601 | 8606 |
8602 Representation left_rep = Representation::FromType(left_type); | 8607 Representation left_rep = Representation::FromType(left_type); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8647 | 8652 |
8648 // Convert left argument as necessary. | 8653 // Convert left argument as necessary. |
8649 if (left_type->Is(Type::Number())) { | 8654 if (left_type->Is(Type::Number())) { |
8650 ASSERT(right_type->Is(Type::String())); | 8655 ASSERT(right_type->Is(Type::String())); |
8651 left = BuildNumberToString(left, left_type); | 8656 left = BuildNumberToString(left, left_type); |
8652 } else if (!left_type->Is(Type::String())) { | 8657 } else if (!left_type->Is(Type::String())) { |
8653 ASSERT(right_type->Is(Type::String())); | 8658 ASSERT(right_type->Is(Type::String())); |
8654 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); | 8659 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); |
8655 Add<HPushArgument>(left); | 8660 Add<HPushArgument>(left); |
8656 Add<HPushArgument>(right); | 8661 Add<HPushArgument>(right); |
8657 return NewUncasted<HInvokeFunction>(function, 2); | 8662 return AddUncasted<HInvokeFunction>(function, 2); |
8658 } | 8663 } |
8659 | 8664 |
8660 // Convert right argument as necessary. | 8665 // Convert right argument as necessary. |
8661 if (right_type->Is(Type::Number())) { | 8666 if (right_type->Is(Type::Number())) { |
8662 ASSERT(left_type->Is(Type::String())); | 8667 ASSERT(left_type->Is(Type::String())); |
8663 right = BuildNumberToString(right, right_type); | 8668 right = BuildNumberToString(right, right_type); |
8664 } else if (!right_type->Is(Type::String())) { | 8669 } else if (!right_type->Is(Type::String())) { |
8665 ASSERT(left_type->Is(Type::String())); | 8670 ASSERT(left_type->Is(Type::String())); |
8666 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 8671 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
8667 Add<HPushArgument>(left); | 8672 Add<HPushArgument>(left); |
8668 Add<HPushArgument>(right); | 8673 Add<HPushArgument>(right); |
8669 return NewUncasted<HInvokeFunction>(function, 2); | 8674 return AddUncasted<HInvokeFunction>(function, 2); |
8670 } | 8675 } |
8671 | 8676 |
8672 return NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); | 8677 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); |
8673 } | 8678 } |
8674 | 8679 |
8675 if (binop_stub) { | 8680 if (binop_stub) { |
8676 left = EnforceNumberType(left, left_type); | 8681 left = EnforceNumberType(left, left_type); |
8677 right = EnforceNumberType(right, right_type); | 8682 right = EnforceNumberType(right, right_type); |
8678 } | 8683 } |
8679 | 8684 |
8680 Representation result_rep = Representation::FromType(result_type); | 8685 Representation result_rep = Representation::FromType(result_type); |
8681 | 8686 |
8682 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 8687 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
8683 (right_rep.IsTagged() && !right_rep.IsSmi()); | 8688 (right_rep.IsTagged() && !right_rep.IsSmi()); |
8684 | 8689 |
8685 HInstruction* instr = NULL; | 8690 HInstruction* instr = NULL; |
8686 // Only the stub is allowed to call into the runtime, since otherwise we would | 8691 // Only the stub is allowed to call into the runtime, since otherwise we would |
8687 // inline several instructions (including the two pushes) for every tagged | 8692 // inline several instructions (including the two pushes) for every tagged |
8688 // operation in optimized code, which is more expensive, than a stub call. | 8693 // operation in optimized code, which is more expensive, than a stub call. |
8689 if (binop_stub && is_non_primitive) { | 8694 if (binop_stub && is_non_primitive) { |
8690 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); | 8695 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); |
8691 Add<HPushArgument>(left); | 8696 Add<HPushArgument>(left); |
8692 Add<HPushArgument>(right); | 8697 Add<HPushArgument>(right); |
8693 instr = NewUncasted<HInvokeFunction>(function, 2); | 8698 instr = AddUncasted<HInvokeFunction>(function, 2); |
8694 } else { | 8699 } else { |
8695 switch (op) { | 8700 switch (op) { |
8696 case Token::ADD: | 8701 case Token::ADD: |
8697 instr = NewUncasted<HAdd>(left, right); | 8702 instr = AddUncasted<HAdd>(left, right); |
8698 break; | 8703 break; |
8699 case Token::SUB: | 8704 case Token::SUB: |
8700 instr = NewUncasted<HSub>(left, right); | 8705 instr = AddUncasted<HSub>(left, right); |
8701 break; | 8706 break; |
8702 case Token::MUL: | 8707 case Token::MUL: |
8703 instr = NewUncasted<HMul>(left, right); | 8708 instr = AddUncasted<HMul>(left, right); |
8704 break; | 8709 break; |
8705 case Token::MOD: | 8710 case Token::MOD: |
8706 instr = NewUncasted<HMod>(left, right, fixed_right_arg); | 8711 instr = AddUncasted<HMod>(left, right, fixed_right_arg); |
8707 break; | 8712 break; |
8708 case Token::DIV: | 8713 case Token::DIV: |
8709 instr = NewUncasted<HDiv>(left, right); | 8714 instr = AddUncasted<HDiv>(left, right); |
8710 break; | 8715 break; |
8711 case Token::BIT_XOR: | 8716 case Token::BIT_XOR: |
8712 case Token::BIT_AND: | 8717 case Token::BIT_AND: |
8713 instr = NewUncasted<HBitwise>(op, left, right); | 8718 instr = AddUncasted<HBitwise>(op, left, right); |
8714 break; | 8719 break; |
8715 case Token::BIT_OR: { | 8720 case Token::BIT_OR: { |
8716 HValue* operand, *shift_amount; | 8721 HValue* operand, *shift_amount; |
8717 if (left_type->Is(Type::Signed32()) && | 8722 if (left_type->Is(Type::Signed32()) && |
8718 right_type->Is(Type::Signed32()) && | 8723 right_type->Is(Type::Signed32()) && |
8719 MatchRotateRight(left, right, &operand, &shift_amount)) { | 8724 MatchRotateRight(left, right, &operand, &shift_amount)) { |
8720 instr = NewUncasted<HRor>(operand, shift_amount); | 8725 instr = AddUncasted<HRor>(operand, shift_amount); |
8721 } else { | 8726 } else { |
8722 instr = NewUncasted<HBitwise>(op, left, right); | 8727 instr = AddUncasted<HBitwise>(op, left, right); |
8723 } | 8728 } |
8724 break; | 8729 break; |
8725 } | 8730 } |
8726 case Token::SAR: | 8731 case Token::SAR: |
8727 instr = NewUncasted<HSar>(left, right); | 8732 instr = AddUncasted<HSar>(left, right); |
8728 break; | 8733 break; |
8729 case Token::SHR: | 8734 case Token::SHR: |
8730 instr = NewUncasted<HShr>(left, right); | 8735 instr = AddUncasted<HShr>(left, right); |
8731 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && | 8736 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && |
8732 CanBeZero(right)) { | 8737 CanBeZero(right)) { |
8733 graph()->RecordUint32Instruction(instr); | 8738 graph()->RecordUint32Instruction(instr); |
8734 } | 8739 } |
8735 break; | 8740 break; |
8736 case Token::SHL: | 8741 case Token::SHL: |
8737 instr = NewUncasted<HShl>(left, right); | 8742 instr = AddUncasted<HShl>(left, right); |
8738 break; | 8743 break; |
8739 default: | 8744 default: |
8740 UNREACHABLE(); | 8745 UNREACHABLE(); |
8741 } | 8746 } |
8742 } | 8747 } |
8743 | 8748 |
8744 if (instr->IsBinaryOperation()) { | 8749 if (instr->IsBinaryOperation()) { |
8745 HBinaryOperation* binop = HBinaryOperation::cast(instr); | 8750 HBinaryOperation* binop = HBinaryOperation::cast(instr); |
8746 binop->set_observed_input_representation(1, left_rep); | 8751 binop->set_observed_input_representation(1, left_rep); |
8747 binop->set_observed_input_representation(2, right_rep); | 8752 binop->set_observed_input_representation(2, right_rep); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8903 } | 8908 } |
8904 } | 8909 } |
8905 | 8910 |
8906 | 8911 |
8907 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 8912 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
8908 CHECK_ALIVE(VisitForValue(expr->left())); | 8913 CHECK_ALIVE(VisitForValue(expr->left())); |
8909 CHECK_ALIVE(VisitForValue(expr->right())); | 8914 CHECK_ALIVE(VisitForValue(expr->right())); |
8910 SetSourcePosition(expr->position()); | 8915 SetSourcePosition(expr->position()); |
8911 HValue* right = Pop(); | 8916 HValue* right = Pop(); |
8912 HValue* left = Pop(); | 8917 HValue* left = Pop(); |
8913 HInstruction* instr = BuildBinaryOperation(expr, left, right); | 8918 HValue* result = BuildBinaryOperation(expr, left, right); |
8914 if (FLAG_emit_opt_code_positions && instr->IsBinaryOperation()) { | 8919 if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { |
8915 HBinaryOperation::cast(instr)->SetOperandPositions( | 8920 HBinaryOperation::cast(result)->SetOperandPositions( |
8916 zone(), expr->left()->position(), expr->right()->position()); | 8921 zone(), expr->left()->position(), expr->right()->position()); |
8917 } | 8922 } |
8918 return ast_context()->ReturnInstruction(instr, expr->id()); | 8923 return ast_context()->ReturnValue(result); |
8919 } | 8924 } |
8920 | 8925 |
8921 | 8926 |
8922 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 8927 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
8923 Expression* sub_expr, | 8928 Expression* sub_expr, |
8924 Handle<String> check) { | 8929 Handle<String> check) { |
8925 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 8930 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
8926 SetSourcePosition(expr->position()); | 8931 SetSourcePosition(expr->position()); |
8927 HValue* value = Pop(); | 8932 HValue* value = Pop(); |
8928 HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); | 8933 HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); |
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10633 if (ShouldProduceTraceOutput()) { | 10638 if (ShouldProduceTraceOutput()) { |
10634 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10639 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10635 } | 10640 } |
10636 | 10641 |
10637 #ifdef DEBUG | 10642 #ifdef DEBUG |
10638 graph_->Verify(false); // No full verify. | 10643 graph_->Verify(false); // No full verify. |
10639 #endif | 10644 #endif |
10640 } | 10645 } |
10641 | 10646 |
10642 } } // namespace v8::internal | 10647 } } // namespace v8::internal |
OLD | NEW |