OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 10289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10300 } | 10300 } |
10301 Push(number_input); | 10301 Push(number_input); |
10302 } | 10302 } |
10303 | 10303 |
10304 // The addition has no side effects, so we do not need | 10304 // The addition has no side effects, so we do not need |
10305 // to simulate the expression stack after this instruction. | 10305 // to simulate the expression stack after this instruction. |
10306 // Any later failures deopt to the load of the input or earlier. | 10306 // Any later failures deopt to the load of the input or earlier. |
10307 HConstant* delta = (expr->op() == Token::INC) | 10307 HConstant* delta = (expr->op() == Token::INC) |
10308 ? graph()->GetConstant1() | 10308 ? graph()->GetConstant1() |
10309 : graph()->GetConstantMinus1(); | 10309 : graph()->GetConstantMinus1(); |
10310 HInstruction* instr = AddUncasted<HAdd>(Top(), delta, | 10310 HInstruction* instr = |
10311 function_language_mode()); | 10311 AddUncasted<HAdd>(Top(), delta, strength(function_language_mode())); |
10312 if (instr->IsAdd()) { | 10312 if (instr->IsAdd()) { |
10313 HAdd* add = HAdd::cast(instr); | 10313 HAdd* add = HAdd::cast(instr); |
10314 add->set_observed_input_representation(1, rep); | 10314 add->set_observed_input_representation(1, rep); |
10315 add->set_observed_input_representation(2, Representation::Smi()); | 10315 add->set_observed_input_representation(2, Representation::Smi()); |
10316 } | 10316 } |
10317 instr->SetFlag(HInstruction::kCannotBeTagged); | 10317 instr->SetFlag(HInstruction::kCannotBeTagged); |
10318 instr->ClearAllSideEffects(); | 10318 instr->ClearAllSideEffects(); |
10319 return instr; | 10319 return instr; |
10320 } | 10320 } |
10321 | 10321 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10595 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); | 10595 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); |
10596 Handle<AllocationSite> allocation_site = expr->allocation_site(); | 10596 Handle<AllocationSite> allocation_site = expr->allocation_site(); |
10597 | 10597 |
10598 HAllocationMode allocation_mode; | 10598 HAllocationMode allocation_mode; |
10599 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { | 10599 if (FLAG_allocation_site_pretenuring && !allocation_site.is_null()) { |
10600 allocation_mode = HAllocationMode(allocation_site); | 10600 allocation_mode = HAllocationMode(allocation_site); |
10601 } | 10601 } |
10602 | 10602 |
10603 HValue* result = HGraphBuilder::BuildBinaryOperation( | 10603 HValue* result = HGraphBuilder::BuildBinaryOperation( |
10604 expr->op(), left, right, left_type, right_type, result_type, | 10604 expr->op(), left, right, left_type, right_type, result_type, |
10605 fixed_right_arg, allocation_mode, function_language_mode()); | 10605 fixed_right_arg, allocation_mode, strength(function_language_mode())); |
10606 // Add a simulate after instructions with observable side effects, and | 10606 // Add a simulate after instructions with observable side effects, and |
10607 // after phis, which are the result of BuildBinaryOperation when we | 10607 // after phis, which are the result of BuildBinaryOperation when we |
10608 // inlined some complex subgraph. | 10608 // inlined some complex subgraph. |
10609 if (result->HasObservableSideEffects() || result->IsPhi()) { | 10609 if (result->HasObservableSideEffects() || result->IsPhi()) { |
10610 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 10610 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
10611 Push(result); | 10611 Push(result); |
10612 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10612 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10613 Drop(1); | 10613 Drop(1); |
10614 } else { | 10614 } else { |
10615 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 10615 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
10616 } | 10616 } |
10617 } | 10617 } |
10618 return result; | 10618 return result; |
10619 } | 10619 } |
10620 | 10620 |
10621 | 10621 |
10622 HValue* HGraphBuilder::BuildBinaryOperation( | 10622 HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left, |
10623 Token::Value op, | 10623 HValue* right, Type* left_type, |
10624 HValue* left, | 10624 Type* right_type, Type* result_type, |
10625 HValue* right, | 10625 Maybe<int> fixed_right_arg, |
10626 Type* left_type, | 10626 HAllocationMode allocation_mode, |
10627 Type* right_type, | 10627 Strength strength) { |
10628 Type* result_type, | |
10629 Maybe<int> fixed_right_arg, | |
10630 HAllocationMode allocation_mode, | |
10631 LanguageMode language_mode) { | |
10632 bool maybe_string_add = false; | 10628 bool maybe_string_add = false; |
10633 if (op == Token::ADD) { | 10629 if (op == Token::ADD) { |
10634 // If we are adding constant string with something for which we don't have | 10630 // If we are adding constant string with something for which we don't have |
10635 // a feedback yet, assume that it's also going to be a string and don't | 10631 // a feedback yet, assume that it's also going to be a string and don't |
10636 // generate deopt instructions. | 10632 // generate deopt instructions. |
10637 if (!left_type->IsInhabited() && right->IsConstant() && | 10633 if (!left_type->IsInhabited() && right->IsConstant() && |
10638 HConstant::cast(right)->HasStringValue()) { | 10634 HConstant::cast(right)->HasStringValue()) { |
10639 left_type = Type::String(); | 10635 left_type = Type::String(); |
10640 } | 10636 } |
10641 | 10637 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10683 if (left_type->Is(Type::String())) { | 10679 if (left_type->Is(Type::String())) { |
10684 left = BuildCheckString(left); | 10680 left = BuildCheckString(left); |
10685 } | 10681 } |
10686 | 10682 |
10687 // Validate type feedback for right argument. | 10683 // Validate type feedback for right argument. |
10688 if (right_type->Is(Type::String())) { | 10684 if (right_type->Is(Type::String())) { |
10689 right = BuildCheckString(right); | 10685 right = BuildCheckString(right); |
10690 } | 10686 } |
10691 | 10687 |
10692 // Convert left argument as necessary. | 10688 // Convert left argument as necessary. |
10693 if (left_type->Is(Type::Number()) && !is_strong(language_mode)) { | 10689 if (left_type->Is(Type::Number()) && !is_strong(strength)) { |
10694 DCHECK(right_type->Is(Type::String())); | 10690 DCHECK(right_type->Is(Type::String())); |
10695 left = BuildNumberToString(left, left_type); | 10691 left = BuildNumberToString(left, left_type); |
10696 } else if (!left_type->Is(Type::String())) { | 10692 } else if (!left_type->Is(Type::String())) { |
10697 DCHECK(right_type->Is(Type::String())); | 10693 DCHECK(right_type->Is(Type::String())); |
10698 HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ? | 10694 HValue* function = AddLoadJSBuiltin( |
10699 Builtins::STRING_ADD_RIGHT_STRONG : | 10695 is_strong(strength) ? Builtins::STRING_ADD_RIGHT_STRONG |
10700 Builtins::STRING_ADD_RIGHT); | 10696 : Builtins::STRING_ADD_RIGHT); |
10701 Add<HPushArguments>(left, right); | 10697 Add<HPushArguments>(left, right); |
10702 return AddUncasted<HInvokeFunction>(function, 2); | 10698 return AddUncasted<HInvokeFunction>(function, 2); |
10703 } | 10699 } |
10704 | 10700 |
10705 // Convert right argument as necessary. | 10701 // Convert right argument as necessary. |
10706 if (right_type->Is(Type::Number()) && !is_strong(language_mode)) { | 10702 if (right_type->Is(Type::Number()) && !is_strong(strength)) { |
10707 DCHECK(left_type->Is(Type::String())); | 10703 DCHECK(left_type->Is(Type::String())); |
10708 right = BuildNumberToString(right, right_type); | 10704 right = BuildNumberToString(right, right_type); |
10709 } else if (!right_type->Is(Type::String())) { | 10705 } else if (!right_type->Is(Type::String())) { |
10710 DCHECK(left_type->Is(Type::String())); | 10706 DCHECK(left_type->Is(Type::String())); |
10711 HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ? | 10707 HValue* function = AddLoadJSBuiltin(is_strong(strength) |
10712 Builtins::STRING_ADD_LEFT_STRONG : | 10708 ? Builtins::STRING_ADD_LEFT_STRONG |
10713 Builtins::STRING_ADD_LEFT); | 10709 : Builtins::STRING_ADD_LEFT); |
10714 Add<HPushArguments>(left, right); | 10710 Add<HPushArguments>(left, right); |
10715 return AddUncasted<HInvokeFunction>(function, 2); | 10711 return AddUncasted<HInvokeFunction>(function, 2); |
10716 } | 10712 } |
10717 | 10713 |
10718 // Fast paths for empty constant strings. | 10714 // Fast paths for empty constant strings. |
10719 Handle<String> left_string = | 10715 Handle<String> left_string = |
10720 left->IsConstant() && HConstant::cast(left)->HasStringValue() | 10716 left->IsConstant() && HConstant::cast(left)->HasStringValue() |
10721 ? HConstant::cast(left)->StringValue() | 10717 ? HConstant::cast(left)->StringValue() |
10722 : Handle<String>(); | 10718 : Handle<String>(); |
10723 Handle<String> right_string = | 10719 Handle<String> right_string = |
10724 right->IsConstant() && HConstant::cast(right)->HasStringValue() | 10720 right->IsConstant() && HConstant::cast(right)->HasStringValue() |
10725 ? HConstant::cast(right)->StringValue() | 10721 ? HConstant::cast(right)->StringValue() |
10726 : Handle<String>(); | 10722 : Handle<String>(); |
10727 if (!left_string.is_null() && left_string->length() == 0) return right; | 10723 if (!left_string.is_null() && left_string->length() == 0) return right; |
10728 if (!right_string.is_null() && right_string->length() == 0) return left; | 10724 if (!right_string.is_null() && right_string->length() == 0) return left; |
10729 if (!left_string.is_null() && !right_string.is_null()) { | 10725 if (!left_string.is_null() && !right_string.is_null()) { |
10730 return AddUncasted<HStringAdd>( | 10726 return AddUncasted<HStringAdd>( |
10731 left, right, language_mode, allocation_mode.GetPretenureMode(), | 10727 left, right, strength, allocation_mode.GetPretenureMode(), |
10732 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); | 10728 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); |
10733 } | 10729 } |
10734 | 10730 |
10735 // Register the dependent code with the allocation site. | 10731 // Register the dependent code with the allocation site. |
10736 if (!allocation_mode.feedback_site().is_null()) { | 10732 if (!allocation_mode.feedback_site().is_null()) { |
10737 DCHECK(!graph()->info()->IsStub()); | 10733 DCHECK(!graph()->info()->IsStub()); |
10738 Handle<AllocationSite> site(allocation_mode.feedback_site()); | 10734 Handle<AllocationSite> site(allocation_mode.feedback_site()); |
10739 top_info()->dependencies()->AssumeTenuringDecision(site); | 10735 top_info()->dependencies()->AssumeTenuringDecision(site); |
10740 } | 10736 } |
10741 | 10737 |
10742 // Inline the string addition into the stub when creating allocation | 10738 // Inline the string addition into the stub when creating allocation |
10743 // mementos to gather allocation site feedback, or if we can statically | 10739 // mementos to gather allocation site feedback, or if we can statically |
10744 // infer that we're going to create a cons string. | 10740 // infer that we're going to create a cons string. |
10745 if ((graph()->info()->IsStub() && | 10741 if ((graph()->info()->IsStub() && |
10746 allocation_mode.CreateAllocationMementos()) || | 10742 allocation_mode.CreateAllocationMementos()) || |
10747 (left->IsConstant() && | 10743 (left->IsConstant() && |
10748 HConstant::cast(left)->HasStringValue() && | 10744 HConstant::cast(left)->HasStringValue() && |
10749 HConstant::cast(left)->StringValue()->length() + 1 >= | 10745 HConstant::cast(left)->StringValue()->length() + 1 >= |
10750 ConsString::kMinLength) || | 10746 ConsString::kMinLength) || |
10751 (right->IsConstant() && | 10747 (right->IsConstant() && |
10752 HConstant::cast(right)->HasStringValue() && | 10748 HConstant::cast(right)->HasStringValue() && |
10753 HConstant::cast(right)->StringValue()->length() + 1 >= | 10749 HConstant::cast(right)->StringValue()->length() + 1 >= |
10754 ConsString::kMinLength)) { | 10750 ConsString::kMinLength)) { |
10755 return BuildStringAdd(left, right, allocation_mode); | 10751 return BuildStringAdd(left, right, allocation_mode); |
10756 } | 10752 } |
10757 | 10753 |
10758 // Fallback to using the string add stub. | 10754 // Fallback to using the string add stub. |
10759 return AddUncasted<HStringAdd>( | 10755 return AddUncasted<HStringAdd>( |
10760 left, right, language_mode, allocation_mode.GetPretenureMode(), | 10756 left, right, strength, allocation_mode.GetPretenureMode(), |
10761 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); | 10757 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); |
10762 } | 10758 } |
10763 | 10759 |
10764 if (graph()->info()->IsStub()) { | 10760 if (graph()->info()->IsStub()) { |
10765 left = EnforceNumberType(left, left_type); | 10761 left = EnforceNumberType(left, left_type); |
10766 right = EnforceNumberType(right, right_type); | 10762 right = EnforceNumberType(right, right_type); |
10767 } | 10763 } |
10768 | 10764 |
10769 Representation result_rep = RepresentationFor(result_type); | 10765 Representation result_rep = RepresentationFor(result_type); |
10770 | 10766 |
10771 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 10767 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
10772 (right_rep.IsTagged() && !right_rep.IsSmi()); | 10768 (right_rep.IsTagged() && !right_rep.IsSmi()); |
10773 | 10769 |
10774 HInstruction* instr = NULL; | 10770 HInstruction* instr = NULL; |
10775 // Only the stub is allowed to call into the runtime, since otherwise we would | 10771 // Only the stub is allowed to call into the runtime, since otherwise we would |
10776 // inline several instructions (including the two pushes) for every tagged | 10772 // inline several instructions (including the two pushes) for every tagged |
10777 // operation in optimized code, which is more expensive, than a stub call. | 10773 // operation in optimized code, which is more expensive, than a stub call. |
10778 if (graph()->info()->IsStub() && is_non_primitive) { | 10774 if (graph()->info()->IsStub() && is_non_primitive) { |
10779 HValue* function = AddLoadJSBuiltin( | 10775 HValue* function = |
10780 BinaryOpIC::TokenToJSBuiltin(op, language_mode)); | 10776 AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength)); |
10781 Add<HPushArguments>(left, right); | 10777 Add<HPushArguments>(left, right); |
10782 instr = AddUncasted<HInvokeFunction>(function, 2); | 10778 instr = AddUncasted<HInvokeFunction>(function, 2); |
10783 } else { | 10779 } else { |
10784 switch (op) { | 10780 switch (op) { |
10785 case Token::ADD: | 10781 case Token::ADD: |
10786 instr = AddUncasted<HAdd>(left, right, language_mode); | 10782 instr = AddUncasted<HAdd>(left, right, strength); |
10787 break; | 10783 break; |
10788 case Token::SUB: | 10784 case Token::SUB: |
10789 instr = AddUncasted<HSub>(left, right, language_mode); | 10785 instr = AddUncasted<HSub>(left, right, strength); |
10790 break; | 10786 break; |
10791 case Token::MUL: | 10787 case Token::MUL: |
10792 instr = AddUncasted<HMul>(left, right, language_mode); | 10788 instr = AddUncasted<HMul>(left, right, strength); |
10793 break; | 10789 break; |
10794 case Token::MOD: { | 10790 case Token::MOD: { |
10795 if (fixed_right_arg.IsJust() && | 10791 if (fixed_right_arg.IsJust() && |
10796 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { | 10792 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { |
10797 HConstant* fixed_right = | 10793 HConstant* fixed_right = |
10798 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); | 10794 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); |
10799 IfBuilder if_same(this); | 10795 IfBuilder if_same(this); |
10800 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); | 10796 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); |
10801 if_same.Then(); | 10797 if_same.Then(); |
10802 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); | 10798 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); |
10803 right = fixed_right; | 10799 right = fixed_right; |
10804 } | 10800 } |
10805 instr = AddUncasted<HMod>(left, right, language_mode); | 10801 instr = AddUncasted<HMod>(left, right, strength); |
10806 break; | 10802 break; |
10807 } | 10803 } |
10808 case Token::DIV: | 10804 case Token::DIV: |
10809 instr = AddUncasted<HDiv>(left, right, language_mode); | 10805 instr = AddUncasted<HDiv>(left, right, strength); |
10810 break; | 10806 break; |
10811 case Token::BIT_XOR: | 10807 case Token::BIT_XOR: |
10812 case Token::BIT_AND: | 10808 case Token::BIT_AND: |
10813 instr = AddUncasted<HBitwise>(op, left, right, language_mode); | 10809 instr = AddUncasted<HBitwise>(op, left, right, strength); |
10814 break; | 10810 break; |
10815 case Token::BIT_OR: { | 10811 case Token::BIT_OR: { |
10816 HValue* operand, *shift_amount; | 10812 HValue* operand, *shift_amount; |
10817 if (left_type->Is(Type::Signed32()) && | 10813 if (left_type->Is(Type::Signed32()) && |
10818 right_type->Is(Type::Signed32()) && | 10814 right_type->Is(Type::Signed32()) && |
10819 MatchRotateRight(left, right, &operand, &shift_amount)) { | 10815 MatchRotateRight(left, right, &operand, &shift_amount)) { |
10820 instr = AddUncasted<HRor>(operand, shift_amount, language_mode); | 10816 instr = AddUncasted<HRor>(operand, shift_amount, strength); |
10821 } else { | 10817 } else { |
10822 instr = AddUncasted<HBitwise>(op, left, right, language_mode); | 10818 instr = AddUncasted<HBitwise>(op, left, right, strength); |
10823 } | 10819 } |
10824 break; | 10820 break; |
10825 } | 10821 } |
10826 case Token::SAR: | 10822 case Token::SAR: |
10827 instr = AddUncasted<HSar>(left, right, language_mode); | 10823 instr = AddUncasted<HSar>(left, right, strength); |
10828 break; | 10824 break; |
10829 case Token::SHR: | 10825 case Token::SHR: |
10830 instr = AddUncasted<HShr>(left, right, language_mode); | 10826 instr = AddUncasted<HShr>(left, right, strength); |
10831 if (instr->IsShr() && CanBeZero(right)) { | 10827 if (instr->IsShr() && CanBeZero(right)) { |
10832 graph()->RecordUint32Instruction(instr); | 10828 graph()->RecordUint32Instruction(instr); |
10833 } | 10829 } |
10834 break; | 10830 break; |
10835 case Token::SHL: | 10831 case Token::SHL: |
10836 instr = AddUncasted<HShl>(left, right, language_mode); | 10832 instr = AddUncasted<HShl>(left, right, strength); |
10837 break; | 10833 break; |
10838 default: | 10834 default: |
10839 UNREACHABLE(); | 10835 UNREACHABLE(); |
10840 } | 10836 } |
10841 } | 10837 } |
10842 | 10838 |
10843 if (instr->IsBinaryOperation()) { | 10839 if (instr->IsBinaryOperation()) { |
10844 HBinaryOperation* binop = HBinaryOperation::cast(instr); | 10840 HBinaryOperation* binop = HBinaryOperation::cast(instr); |
10845 binop->set_observed_input_representation(1, left_rep); | 10841 binop->set_observed_input_representation(1, left_rep); |
10846 binop->set_observed_input_representation(2, right_rep); | 10842 binop->set_observed_input_representation(2, right_rep); |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11214 } else if (combined_type->Is(Type::String())) { | 11210 } else if (combined_type->Is(Type::String())) { |
11215 BuildCheckHeapObject(left); | 11211 BuildCheckHeapObject(left); |
11216 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); | 11212 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING); |
11217 BuildCheckHeapObject(right); | 11213 BuildCheckHeapObject(right); |
11218 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); | 11214 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_STRING); |
11219 HStringCompareAndBranch* result = | 11215 HStringCompareAndBranch* result = |
11220 New<HStringCompareAndBranch>(left, right, op); | 11216 New<HStringCompareAndBranch>(left, right, op); |
11221 return result; | 11217 return result; |
11222 } else { | 11218 } else { |
11223 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 11219 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
11224 HCompareGeneric* result = | 11220 HCompareGeneric* result = Add<HCompareGeneric>( |
11225 Add<HCompareGeneric>(left, right, op, function_language_mode()); | 11221 left, right, op, strength(function_language_mode())); |
11226 result->set_observed_input_representation(1, left_rep); | 11222 result->set_observed_input_representation(1, left_rep); |
11227 result->set_observed_input_representation(2, right_rep); | 11223 result->set_observed_input_representation(2, right_rep); |
11228 if (result->HasObservableSideEffects()) { | 11224 if (result->HasObservableSideEffects()) { |
11229 if (push_sim_result == PUSH_BEFORE_SIMULATE) { | 11225 if (push_sim_result == PUSH_BEFORE_SIMULATE) { |
11230 Push(result); | 11226 Push(result); |
11231 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11227 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
11232 Drop(1); | 11228 Drop(1); |
11233 } else { | 11229 } else { |
11234 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 11230 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
11235 } | 11231 } |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12075 } | 12071 } |
12076 | 12072 |
12077 | 12073 |
12078 // Fast support for StringAdd. | 12074 // Fast support for StringAdd. |
12079 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 12075 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
12080 DCHECK_EQ(2, call->arguments()->length()); | 12076 DCHECK_EQ(2, call->arguments()->length()); |
12081 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12077 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
12082 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12078 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
12083 HValue* right = Pop(); | 12079 HValue* right = Pop(); |
12084 HValue* left = Pop(); | 12080 HValue* left = Pop(); |
12085 HInstruction* result = NewUncasted<HStringAdd>(left, right, | 12081 HInstruction* result = |
12086 function_language_mode()); | 12082 NewUncasted<HStringAdd>(left, right, strength(function_language_mode())); |
12087 return ast_context()->ReturnInstruction(result, call->id()); | 12083 return ast_context()->ReturnInstruction(result, call->id()); |
12088 } | 12084 } |
12089 | 12085 |
12090 | 12086 |
12091 // Fast support for SubString. | 12087 // Fast support for SubString. |
12092 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { | 12088 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
12093 DCHECK_EQ(3, call->arguments()->length()); | 12089 DCHECK_EQ(3, call->arguments()->length()); |
12094 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12090 CHECK_ALIVE(VisitExpressions(call->arguments())); |
12095 PushArgumentsFromEnvironment(call->arguments()->length()); | 12091 PushArgumentsFromEnvironment(call->arguments()->length()); |
12096 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); | 12092 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); |
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13174 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13170 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13175 } | 13171 } |
13176 | 13172 |
13177 #ifdef DEBUG | 13173 #ifdef DEBUG |
13178 graph_->Verify(false); // No full verify. | 13174 graph_->Verify(false); // No full verify. |
13179 #endif | 13175 #endif |
13180 } | 13176 } |
13181 | 13177 |
13182 } // namespace internal | 13178 } // namespace internal |
13183 } // namespace v8 | 13179 } // namespace v8 |
OLD | NEW |