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 if (result->HasObservableSideEffects() || result->IsPhi()) { | |
Sven Panne
2013/11/20 11:44:48
Please add a comment about the "IsPhi()" part, it
Benedikt Meurer
2013/11/20 12:00:21
Done.
| |
8586 Push(result); | |
8587 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | |
8588 Drop(1); | |
8589 } | |
8590 return result; | |
8589 } | 8591 } |
8590 | 8592 |
8591 | 8593 |
8592 HInstruction* HGraphBuilder::BuildBinaryOperation( | 8594 HValue* HGraphBuilder::BuildBinaryOperation( |
8593 Token::Value op, | 8595 Token::Value op, |
8594 HValue* left, | 8596 HValue* left, |
8595 HValue* right, | 8597 HValue* right, |
8596 Handle<Type> left_type, | 8598 Handle<Type> left_type, |
8597 Handle<Type> right_type, | 8599 Handle<Type> right_type, |
8598 Handle<Type> result_type, | 8600 Handle<Type> result_type, |
8599 Maybe<int> fixed_right_arg, | 8601 Maybe<int> fixed_right_arg, |
8600 bool binop_stub) { | 8602 bool binop_stub) { |
8601 | 8603 |
8602 Representation left_rep = Representation::FromType(left_type); | 8604 Representation left_rep = Representation::FromType(left_type); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8647 | 8649 |
8648 // Convert left argument as necessary. | 8650 // Convert left argument as necessary. |
8649 if (left_type->Is(Type::Number())) { | 8651 if (left_type->Is(Type::Number())) { |
8650 ASSERT(right_type->Is(Type::String())); | 8652 ASSERT(right_type->Is(Type::String())); |
8651 left = BuildNumberToString(left, left_type); | 8653 left = BuildNumberToString(left, left_type); |
8652 } else if (!left_type->Is(Type::String())) { | 8654 } else if (!left_type->Is(Type::String())) { |
8653 ASSERT(right_type->Is(Type::String())); | 8655 ASSERT(right_type->Is(Type::String())); |
8654 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); | 8656 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); |
8655 Add<HPushArgument>(left); | 8657 Add<HPushArgument>(left); |
8656 Add<HPushArgument>(right); | 8658 Add<HPushArgument>(right); |
8657 return NewUncasted<HInvokeFunction>(function, 2); | 8659 return AddUncasted<HInvokeFunction>(function, 2); |
8658 } | 8660 } |
8659 | 8661 |
8660 // Convert right argument as necessary. | 8662 // Convert right argument as necessary. |
8661 if (right_type->Is(Type::Number())) { | 8663 if (right_type->Is(Type::Number())) { |
8662 ASSERT(left_type->Is(Type::String())); | 8664 ASSERT(left_type->Is(Type::String())); |
8663 right = BuildNumberToString(right, right_type); | 8665 right = BuildNumberToString(right, right_type); |
8664 } else if (!right_type->Is(Type::String())) { | 8666 } else if (!right_type->Is(Type::String())) { |
8665 ASSERT(left_type->Is(Type::String())); | 8667 ASSERT(left_type->Is(Type::String())); |
8666 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); | 8668 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); |
8667 Add<HPushArgument>(left); | 8669 Add<HPushArgument>(left); |
8668 Add<HPushArgument>(right); | 8670 Add<HPushArgument>(right); |
8669 return NewUncasted<HInvokeFunction>(function, 2); | 8671 return AddUncasted<HInvokeFunction>(function, 2); |
8670 } | 8672 } |
8671 | 8673 |
8672 return NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); | 8674 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); |
8673 } | 8675 } |
8674 | 8676 |
8675 if (binop_stub) { | 8677 if (binop_stub) { |
8676 left = EnforceNumberType(left, left_type); | 8678 left = EnforceNumberType(left, left_type); |
8677 right = EnforceNumberType(right, right_type); | 8679 right = EnforceNumberType(right, right_type); |
8678 } | 8680 } |
8679 | 8681 |
8680 Representation result_rep = Representation::FromType(result_type); | 8682 Representation result_rep = Representation::FromType(result_type); |
8681 | 8683 |
8682 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 8684 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
8683 (right_rep.IsTagged() && !right_rep.IsSmi()); | 8685 (right_rep.IsTagged() && !right_rep.IsSmi()); |
8684 | 8686 |
8685 HInstruction* instr = NULL; | 8687 HInstruction* instr = NULL; |
8686 // Only the stub is allowed to call into the runtime, since otherwise we would | 8688 // 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 | 8689 // inline several instructions (including the two pushes) for every tagged |
8688 // operation in optimized code, which is more expensive, than a stub call. | 8690 // operation in optimized code, which is more expensive, than a stub call. |
8689 if (binop_stub && is_non_primitive) { | 8691 if (binop_stub && is_non_primitive) { |
8690 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); | 8692 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); |
8691 Add<HPushArgument>(left); | 8693 Add<HPushArgument>(left); |
8692 Add<HPushArgument>(right); | 8694 Add<HPushArgument>(right); |
8693 instr = NewUncasted<HInvokeFunction>(function, 2); | 8695 instr = AddUncasted<HInvokeFunction>(function, 2); |
8694 } else { | 8696 } else { |
8695 switch (op) { | 8697 switch (op) { |
8696 case Token::ADD: | 8698 case Token::ADD: |
8697 instr = NewUncasted<HAdd>(left, right); | 8699 instr = AddUncasted<HAdd>(left, right); |
8698 break; | 8700 break; |
8699 case Token::SUB: | 8701 case Token::SUB: |
8700 instr = NewUncasted<HSub>(left, right); | 8702 instr = AddUncasted<HSub>(left, right); |
8701 break; | 8703 break; |
8702 case Token::MUL: | 8704 case Token::MUL: |
8703 instr = NewUncasted<HMul>(left, right); | 8705 instr = AddUncasted<HMul>(left, right); |
8704 break; | 8706 break; |
8705 case Token::MOD: | 8707 case Token::MOD: |
8706 instr = NewUncasted<HMod>(left, right, fixed_right_arg); | 8708 instr = AddUncasted<HMod>(left, right, fixed_right_arg); |
8707 break; | 8709 break; |
8708 case Token::DIV: | 8710 case Token::DIV: |
8709 instr = NewUncasted<HDiv>(left, right); | 8711 instr = AddUncasted<HDiv>(left, right); |
8710 break; | 8712 break; |
8711 case Token::BIT_XOR: | 8713 case Token::BIT_XOR: |
8712 case Token::BIT_AND: | 8714 case Token::BIT_AND: |
8713 instr = NewUncasted<HBitwise>(op, left, right); | 8715 instr = AddUncasted<HBitwise>(op, left, right); |
8714 break; | 8716 break; |
8715 case Token::BIT_OR: { | 8717 case Token::BIT_OR: { |
8716 HValue* operand, *shift_amount; | 8718 HValue* operand, *shift_amount; |
8717 if (left_type->Is(Type::Signed32()) && | 8719 if (left_type->Is(Type::Signed32()) && |
8718 right_type->Is(Type::Signed32()) && | 8720 right_type->Is(Type::Signed32()) && |
8719 MatchRotateRight(left, right, &operand, &shift_amount)) { | 8721 MatchRotateRight(left, right, &operand, &shift_amount)) { |
8720 instr = NewUncasted<HRor>(operand, shift_amount); | 8722 instr = AddUncasted<HRor>(operand, shift_amount); |
8721 } else { | 8723 } else { |
8722 instr = NewUncasted<HBitwise>(op, left, right); | 8724 instr = AddUncasted<HBitwise>(op, left, right); |
8723 } | 8725 } |
8724 break; | 8726 break; |
8725 } | 8727 } |
8726 case Token::SAR: | 8728 case Token::SAR: |
8727 instr = NewUncasted<HSar>(left, right); | 8729 instr = AddUncasted<HSar>(left, right); |
8728 break; | 8730 break; |
8729 case Token::SHR: | 8731 case Token::SHR: |
8730 instr = NewUncasted<HShr>(left, right); | 8732 instr = AddUncasted<HShr>(left, right); |
8731 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && | 8733 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && |
8732 CanBeZero(right)) { | 8734 CanBeZero(right)) { |
8733 graph()->RecordUint32Instruction(instr); | 8735 graph()->RecordUint32Instruction(instr); |
8734 } | 8736 } |
8735 break; | 8737 break; |
8736 case Token::SHL: | 8738 case Token::SHL: |
8737 instr = NewUncasted<HShl>(left, right); | 8739 instr = AddUncasted<HShl>(left, right); |
8738 break; | 8740 break; |
8739 default: | 8741 default: |
8740 UNREACHABLE(); | 8742 UNREACHABLE(); |
8741 } | 8743 } |
8742 } | 8744 } |
8743 | 8745 |
8744 if (instr->IsBinaryOperation()) { | 8746 if (instr->IsBinaryOperation()) { |
8745 HBinaryOperation* binop = HBinaryOperation::cast(instr); | 8747 HBinaryOperation* binop = HBinaryOperation::cast(instr); |
8746 binop->set_observed_input_representation(1, left_rep); | 8748 binop->set_observed_input_representation(1, left_rep); |
8747 binop->set_observed_input_representation(2, right_rep); | 8749 binop->set_observed_input_representation(2, right_rep); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8903 } | 8905 } |
8904 } | 8906 } |
8905 | 8907 |
8906 | 8908 |
8907 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 8909 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
8908 CHECK_ALIVE(VisitForValue(expr->left())); | 8910 CHECK_ALIVE(VisitForValue(expr->left())); |
8909 CHECK_ALIVE(VisitForValue(expr->right())); | 8911 CHECK_ALIVE(VisitForValue(expr->right())); |
8910 SetSourcePosition(expr->position()); | 8912 SetSourcePosition(expr->position()); |
8911 HValue* right = Pop(); | 8913 HValue* right = Pop(); |
8912 HValue* left = Pop(); | 8914 HValue* left = Pop(); |
8913 HInstruction* instr = BuildBinaryOperation(expr, left, right); | 8915 HValue* result = BuildBinaryOperation(expr, left, right); |
8914 if (FLAG_emit_opt_code_positions && instr->IsBinaryOperation()) { | 8916 if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { |
8915 HBinaryOperation::cast(instr)->SetOperandPositions( | 8917 HBinaryOperation::cast(result)->SetOperandPositions( |
8916 zone(), expr->left()->position(), expr->right()->position()); | 8918 zone(), expr->left()->position(), expr->right()->position()); |
8917 } | 8919 } |
8918 return ast_context()->ReturnInstruction(instr, expr->id()); | 8920 return ast_context()->ReturnValue(result); |
8919 } | 8921 } |
8920 | 8922 |
8921 | 8923 |
8922 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 8924 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
8923 Expression* sub_expr, | 8925 Expression* sub_expr, |
8924 Handle<String> check) { | 8926 Handle<String> check) { |
8925 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 8927 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
8926 SetSourcePosition(expr->position()); | 8928 SetSourcePosition(expr->position()); |
8927 HValue* value = Pop(); | 8929 HValue* value = Pop(); |
8928 HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); | 8930 HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); |
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10633 if (ShouldProduceTraceOutput()) { | 10635 if (ShouldProduceTraceOutput()) { |
10634 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10636 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10635 } | 10637 } |
10636 | 10638 |
10637 #ifdef DEBUG | 10639 #ifdef DEBUG |
10638 graph_->Verify(false); // No full verify. | 10640 graph_->Verify(false); // No full verify. |
10639 #endif | 10641 #endif |
10640 } | 10642 } |
10641 | 10643 |
10642 } } // namespace v8::internal | 10644 } } // namespace v8::internal |
OLD | NEW |