Chromium Code Reviews| 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 7613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7624 return false; | 7624 return false; |
| 7625 } | 7625 } |
| 7626 return (sub->right() == sa); | 7626 return (sub->right() == sa); |
| 7627 } | 7627 } |
| 7628 | 7628 |
| 7629 | 7629 |
| 7630 // Checks if the left and the right are shift instructions with the oposite | 7630 // Checks if the left and the right are shift instructions with the oposite |
| 7631 // directions that can be replaced by one rotate right instruction or not. | 7631 // directions that can be replaced by one rotate right instruction or not. |
| 7632 // Returns the operand and the shift amount for the rotate instruction in the | 7632 // Returns the operand and the shift amount for the rotate instruction in the |
| 7633 // former case. | 7633 // former case. |
| 7634 bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left, | 7634 bool HGraphBuilder::MatchRotateRight(HValue* left, |
| 7635 HValue* right, | 7635 HValue* right, |
|
Sven Panne
2013/08/01 09:21:09
Nit: Fix indentation of arguments.
| |
| 7636 HValue** operand, | 7636 HValue** operand, |
| 7637 HValue** shift_amount) { | 7637 HValue** shift_amount) { |
| 7638 HShl* shl; | 7638 HShl* shl; |
| 7639 HShr* shr; | 7639 HShr* shr; |
| 7640 if (left->IsShl() && right->IsShr()) { | 7640 if (left->IsShl() && right->IsShr()) { |
| 7641 shl = HShl::cast(left); | 7641 shl = HShl::cast(left); |
| 7642 shr = HShr::cast(right); | 7642 shr = HShr::cast(right); |
| 7643 } else if (left->IsShr() && right->IsShl()) { | 7643 } else if (left->IsShr() && right->IsShl()) { |
| 7644 shl = HShl::cast(right); | 7644 shl = HShl::cast(right); |
| 7645 shr = HShr::cast(left); | 7645 shr = HShr::cast(left); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7690 // tagged representation later on. | 7690 // tagged representation later on. |
| 7691 if (expected_type->Is(Type::Oddball())) { | 7691 if (expected_type->Is(Type::Oddball())) { |
| 7692 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to | 7692 // TODO(olivf) The BinaryOpStub only records undefined. It might pay off to |
| 7693 // also record booleans and convert them to 0/1 here. | 7693 // also record booleans and convert them to 0/1 here. |
| 7694 IfBuilder if_nan(this); | 7694 IfBuilder if_nan(this); |
| 7695 if_nan.If<HCompareObjectEqAndBranch>(value, | 7695 if_nan.If<HCompareObjectEqAndBranch>(value, |
| 7696 graph()->GetConstantUndefined()); | 7696 graph()->GetConstantUndefined()); |
| 7697 if_nan.Then(); | 7697 if_nan.Then(); |
| 7698 if_nan.ElseDeopt(); | 7698 if_nan.ElseDeopt(); |
| 7699 if_nan.End(); | 7699 if_nan.End(); |
| 7700 *expected = handle(Type::Double(), isolate()); | |
| 7700 return Add<HConstant>(OS::nan_value()); | 7701 return Add<HConstant>(OS::nan_value()); |
| 7701 } | 7702 } |
| 7702 | 7703 |
| 7703 return value; | 7704 return value; |
| 7704 } | 7705 } |
| 7705 | 7706 |
| 7706 | 7707 |
| 7707 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( | 7708 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( |
| 7708 BinaryOperation* expr, | 7709 BinaryOperation* expr, |
| 7709 HValue* left, | 7710 HValue* left, |
| 7710 HValue* right) { | 7711 HValue* right) { |
| 7711 HValue* context = environment()->context(); | 7712 HValue* context = environment()->context(); |
| 7712 Handle<Type> left_type = expr->left()->bounds().lower; | 7713 Handle<Type> left_type = expr->left()->bounds().lower; |
| 7713 Handle<Type> right_type = expr->right()->bounds().lower; | 7714 Handle<Type> right_type = expr->right()->bounds().lower; |
| 7714 Handle<Type> result_type = expr->bounds().lower; | 7715 Handle<Type> result_type = expr->bounds().lower; |
| 7715 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 7716 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
| 7717 | |
| 7718 return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right, | |
| 7719 left_type, right_type, result_type, fixed_right_arg, context); | |
| 7720 } | |
| 7721 | |
| 7722 | |
| 7723 HInstruction* HGraphBuilder::BuildBinaryOperation( | |
| 7724 Token::Value op, | |
| 7725 HValue* left, | |
| 7726 HValue* right, | |
| 7727 Handle<Type> left_type, | |
| 7728 Handle<Type> right_type, | |
| 7729 Handle<Type> result_type, | |
| 7730 Maybe<int> fixed_right_arg, | |
| 7731 HValue* context) { | |
|
Sven Panne
2013/08/01 09:21:09
Hmmm, having 8 arguments is not very nice, but let
oliv
2013/08/01 09:53:43
well i know that the stub will have to pass exactl
| |
| 7716 Representation left_rep = Representation::FromType(left_type); | 7732 Representation left_rep = Representation::FromType(left_type); |
| 7717 Representation right_rep = Representation::FromType(right_type); | 7733 Representation right_rep = Representation::FromType(right_type); |
| 7718 Representation result_rep = Representation::FromType(result_type); | 7734 Representation result_rep = Representation::FromType(result_type); |
| 7719 | 7735 |
| 7720 if (expr->op() != Token::ADD || | 7736 if (op != Token::ADD || |
|
Sven Panne
2013/08/01 09:21:09
Brain explosion caused by heavy use of negation...
oliv
2013/08/01 09:53:43
yup, mechanical refactoring issue...
| |
| 7721 (left->type().IsNonString() && right->type().IsNonString())) { | 7737 (!left_type->Maybe(Type::String()) && |
| 7738 !right_type->Maybe(Type::String()))) { | |
| 7722 // For addition we can only truncate the arguments to number if we can | 7739 // For addition we can only truncate the arguments to number if we can |
| 7723 // prove that we will not end up in string concatenation mode. | 7740 // prove that we will not end up in string concatenation mode. |
| 7724 left = TruncateToNumber(left, &left_type); | 7741 left = TruncateToNumber(left, &left_type); |
| 7725 right = TruncateToNumber(right, &right_type); | 7742 right = TruncateToNumber(right, &right_type); |
| 7726 } | 7743 } |
| 7727 | 7744 |
| 7728 if (left_type->Is(Type::None())) { | 7745 if (left_type->Is(Type::None())) { |
| 7729 Add<HDeoptimize>(Deoptimizer::SOFT); | 7746 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 7730 // TODO(rossberg): we should be able to get rid of non-continuous defaults. | 7747 // TODO(rossberg): we should be able to get rid of non-continuous defaults. |
| 7731 left_type = handle(Type::Any(), isolate()); | 7748 left_type = handle(Type::Any(), isolate()); |
| 7732 } | 7749 } |
| 7733 if (right_type->Is(Type::None())) { | 7750 if (right_type->Is(Type::None())) { |
| 7734 Add<HDeoptimize>(Deoptimizer::SOFT); | 7751 Add<HDeoptimize>(Deoptimizer::SOFT); |
| 7735 right_type = handle(Type::Any(), isolate()); | 7752 right_type = handle(Type::Any(), isolate()); |
| 7736 } | 7753 } |
| 7737 HInstruction* instr = NULL; | 7754 HInstruction* instr = NULL; |
| 7738 switch (expr->op()) { | 7755 switch (op) { |
| 7739 case Token::ADD: | 7756 case Token::ADD: |
| 7740 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { | 7757 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { |
| 7741 BuildCheckHeapObject(left); | 7758 BuildCheckHeapObject(left); |
| 7742 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 7759 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 7743 BuildCheckHeapObject(right); | 7760 BuildCheckHeapObject(right); |
| 7744 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 7761 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 7745 instr = HStringAdd::New(zone(), context, left, right); | 7762 instr = HStringAdd::New(zone(), context, left, right); |
| 7746 } else { | 7763 } else { |
| 7747 instr = HAdd::New(zone(), context, left, right); | 7764 instr = HAdd::New(zone(), context, left, right); |
| 7748 } | 7765 } |
| 7749 break; | 7766 break; |
| 7750 case Token::SUB: | 7767 case Token::SUB: |
| 7751 instr = HSub::New(zone(), context, left, right); | 7768 instr = HSub::New(zone(), context, left, right); |
| 7752 break; | 7769 break; |
| 7753 case Token::MUL: | 7770 case Token::MUL: |
| 7754 instr = HMul::New(zone(), context, left, right); | 7771 instr = HMul::New(zone(), context, left, right); |
| 7755 break; | 7772 break; |
| 7756 case Token::MOD: | 7773 case Token::MOD: |
| 7757 instr = HMod::New(zone(), context, left, right, fixed_right_arg); | 7774 instr = HMod::New(zone(), context, left, right, fixed_right_arg); |
| 7758 break; | 7775 break; |
| 7759 case Token::DIV: | 7776 case Token::DIV: |
| 7760 instr = HDiv::New(zone(), context, left, right); | 7777 instr = HDiv::New(zone(), context, left, right); |
| 7761 break; | 7778 break; |
| 7762 case Token::BIT_XOR: | 7779 case Token::BIT_XOR: |
| 7763 case Token::BIT_AND: | 7780 case Token::BIT_AND: |
| 7764 instr = NewUncasted<HBitwise>(expr->op(), left, right); | 7781 instr = NewUncasted<HBitwise>(op, left, right); |
| 7765 break; | 7782 break; |
| 7766 case Token::BIT_OR: { | 7783 case Token::BIT_OR: { |
| 7767 HValue* operand, *shift_amount; | 7784 HValue* operand, *shift_amount; |
| 7768 if (left_type->Is(Type::Signed32()) && | 7785 if (left_type->Is(Type::Signed32()) && |
| 7769 right_type->Is(Type::Signed32()) && | 7786 right_type->Is(Type::Signed32()) && |
| 7770 MatchRotateRight(left, right, &operand, &shift_amount)) { | 7787 MatchRotateRight(left, right, &operand, &shift_amount)) { |
| 7771 instr = new(zone()) HRor(context, operand, shift_amount); | 7788 instr = new(zone()) HRor(context, operand, shift_amount); |
| 7772 } else { | 7789 } else { |
| 7773 instr = NewUncasted<HBitwise>(expr->op(), left, right); | 7790 instr = NewUncasted<HBitwise>(op, left, right); |
| 7774 } | 7791 } |
| 7775 break; | 7792 break; |
| 7776 } | 7793 } |
| 7777 case Token::SAR: | 7794 case Token::SAR: |
| 7778 instr = HSar::New(zone(), context, left, right); | 7795 instr = HSar::New(zone(), context, left, right); |
| 7779 break; | 7796 break; |
| 7780 case Token::SHR: | 7797 case Token::SHR: |
| 7781 instr = HShr::New(zone(), context, left, right); | 7798 instr = HShr::New(zone(), context, left, right); |
| 7782 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && | 7799 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && |
| 7783 CanBeZero(right)) { | 7800 CanBeZero(right)) { |
| (...skipping 2014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9798 if (ShouldProduceTraceOutput()) { | 9815 if (ShouldProduceTraceOutput()) { |
| 9799 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9816 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9800 } | 9817 } |
| 9801 | 9818 |
| 9802 #ifdef DEBUG | 9819 #ifdef DEBUG |
| 9803 graph_->Verify(false); // No full verify. | 9820 graph_->Verify(false); // No full verify. |
| 9804 #endif | 9821 #endif |
| 9805 } | 9822 } |
| 9806 | 9823 |
| 9807 } } // namespace v8::internal | 9824 } } // namespace v8::internal |
| OLD | NEW |