Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1067)

Side by Side Diff: src/hydrogen.cc

Issue 1123043002: [strong] Fix inlining issue (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10271 matching lines...) Expand 10 before | Expand all | Expand 10 after
10282 } 10282 }
10283 Push(number_input); 10283 Push(number_input);
10284 } 10284 }
10285 10285
10286 // The addition has no side effects, so we do not need 10286 // The addition has no side effects, so we do not need
10287 // to simulate the expression stack after this instruction. 10287 // to simulate the expression stack after this instruction.
10288 // Any later failures deopt to the load of the input or earlier. 10288 // Any later failures deopt to the load of the input or earlier.
10289 HConstant* delta = (expr->op() == Token::INC) 10289 HConstant* delta = (expr->op() == Token::INC)
10290 ? graph()->GetConstant1() 10290 ? graph()->GetConstant1()
10291 : graph()->GetConstantMinus1(); 10291 : graph()->GetConstantMinus1();
10292 HInstruction* instr = AddUncasted<HAdd>(Top(), delta); 10292 HInstruction* instr = AddUncasted<HAdd>(Top(), delta,
10293 function_language_mode());
10293 if (instr->IsAdd()) { 10294 if (instr->IsAdd()) {
10294 HAdd* add = HAdd::cast(instr); 10295 HAdd* add = HAdd::cast(instr);
10295 add->set_observed_input_representation(1, rep); 10296 add->set_observed_input_representation(1, rep);
10296 add->set_observed_input_representation(2, Representation::Smi()); 10297 add->set_observed_input_representation(2, Representation::Smi());
10297 } 10298 }
10298 instr->SetFlag(HInstruction::kCannotBeTagged); 10299 instr->SetFlag(HInstruction::kCannotBeTagged);
10299 instr->ClearAllSideEffects(); 10300 instr->ClearAllSideEffects();
10300 return instr; 10301 return instr;
10301 } 10302 }
10302 10303
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
10630 right_type->Maybe(Type::String()) || 10631 right_type->Maybe(Type::String()) ||
10631 right_type->Maybe(Type::Receiver())); 10632 right_type->Maybe(Type::Receiver()));
10632 } 10633 }
10633 10634
10634 Representation left_rep = RepresentationFor(left_type); 10635 Representation left_rep = RepresentationFor(left_type);
10635 Representation right_rep = RepresentationFor(right_type); 10636 Representation right_rep = RepresentationFor(right_type);
10636 10637
10637 if (!left_type->IsInhabited()) { 10638 if (!left_type->IsInhabited()) {
10638 Add<HDeoptimize>( 10639 Add<HDeoptimize>(
10639 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, 10640 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation,
10640 is_strong(language_mode) ? Deoptimizer::EAGER : Deoptimizer::SOFT); 10641 Deoptimizer::SOFT);
10641 left_type = Type::Any(zone()); 10642 left_type = Type::Any(zone());
10642 left_rep = RepresentationFor(left_type); 10643 left_rep = RepresentationFor(left_type);
10643 maybe_string_add = op == Token::ADD; 10644 maybe_string_add = op == Token::ADD;
10644 } 10645 }
10645 10646
10646 if (!right_type->IsInhabited()) { 10647 if (!right_type->IsInhabited()) {
10647 Add<HDeoptimize>( 10648 Add<HDeoptimize>(
10648 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, 10649 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation,
10649 is_strong(language_mode) ? Deoptimizer::EAGER : Deoptimizer::SOFT); 10650 Deoptimizer::SOFT);
10650 right_type = Type::Any(zone()); 10651 right_type = Type::Any(zone());
10651 right_rep = RepresentationFor(right_type); 10652 right_rep = RepresentationFor(right_type);
10652 maybe_string_add = op == Token::ADD; 10653 maybe_string_add = op == Token::ADD;
10653 } 10654 }
10654 10655
10655 if (!maybe_string_add) { 10656 if (!maybe_string_add) {
10656 left = TruncateToNumber(left, &left_type); 10657 left = TruncateToNumber(left, &left_type);
10657 right = TruncateToNumber(right, &right_type); 10658 right = TruncateToNumber(right, &right_type);
10658 } 10659 }
10659 10660
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
10702 ? HConstant::cast(left)->StringValue() 10703 ? HConstant::cast(left)->StringValue()
10703 : Handle<String>(); 10704 : Handle<String>();
10704 Handle<String> right_string = 10705 Handle<String> right_string =
10705 right->IsConstant() && HConstant::cast(right)->HasStringValue() 10706 right->IsConstant() && HConstant::cast(right)->HasStringValue()
10706 ? HConstant::cast(right)->StringValue() 10707 ? HConstant::cast(right)->StringValue()
10707 : Handle<String>(); 10708 : Handle<String>();
10708 if (!left_string.is_null() && left_string->length() == 0) return right; 10709 if (!left_string.is_null() && left_string->length() == 0) return right;
10709 if (!right_string.is_null() && right_string->length() == 0) return left; 10710 if (!right_string.is_null() && right_string->length() == 0) return left;
10710 if (!left_string.is_null() && !right_string.is_null()) { 10711 if (!left_string.is_null() && !right_string.is_null()) {
10711 return AddUncasted<HStringAdd>( 10712 return AddUncasted<HStringAdd>(
10712 left, right, allocation_mode.GetPretenureMode(), 10713 left, right, language_mode, allocation_mode.GetPretenureMode(),
10713 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10714 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10714 } 10715 }
10715 10716
10716 // Register the dependent code with the allocation site. 10717 // Register the dependent code with the allocation site.
10717 if (!allocation_mode.feedback_site().is_null()) { 10718 if (!allocation_mode.feedback_site().is_null()) {
10718 DCHECK(!graph()->info()->IsStub()); 10719 DCHECK(!graph()->info()->IsStub());
10719 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10720 Handle<AllocationSite> site(allocation_mode.feedback_site());
10720 top_info()->dependencies()->AssumeTenuringDecision(site); 10721 top_info()->dependencies()->AssumeTenuringDecision(site);
10721 } 10722 }
10722 10723
10723 // Inline the string addition into the stub when creating allocation 10724 // Inline the string addition into the stub when creating allocation
10724 // mementos to gather allocation site feedback, or if we can statically 10725 // mementos to gather allocation site feedback, or if we can statically
10725 // infer that we're going to create a cons string. 10726 // infer that we're going to create a cons string.
10726 if ((graph()->info()->IsStub() && 10727 if ((graph()->info()->IsStub() &&
10727 allocation_mode.CreateAllocationMementos()) || 10728 allocation_mode.CreateAllocationMementos()) ||
10728 (left->IsConstant() && 10729 (left->IsConstant() &&
10729 HConstant::cast(left)->HasStringValue() && 10730 HConstant::cast(left)->HasStringValue() &&
10730 HConstant::cast(left)->StringValue()->length() + 1 >= 10731 HConstant::cast(left)->StringValue()->length() + 1 >=
10731 ConsString::kMinLength) || 10732 ConsString::kMinLength) ||
10732 (right->IsConstant() && 10733 (right->IsConstant() &&
10733 HConstant::cast(right)->HasStringValue() && 10734 HConstant::cast(right)->HasStringValue() &&
10734 HConstant::cast(right)->StringValue()->length() + 1 >= 10735 HConstant::cast(right)->StringValue()->length() + 1 >=
10735 ConsString::kMinLength)) { 10736 ConsString::kMinLength)) {
10736 return BuildStringAdd(left, right, allocation_mode); 10737 return BuildStringAdd(left, right, allocation_mode);
10737 } 10738 }
10738 10739
10739 // Fallback to using the string add stub. 10740 // Fallback to using the string add stub.
10740 return AddUncasted<HStringAdd>( 10741 return AddUncasted<HStringAdd>(
10741 left, right, allocation_mode.GetPretenureMode(), 10742 left, right, language_mode, allocation_mode.GetPretenureMode(),
10742 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site()); 10743 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
10743 } 10744 }
10744 10745
10745 if (graph()->info()->IsStub()) { 10746 if (graph()->info()->IsStub()) {
10746 left = EnforceNumberType(left, left_type); 10747 left = EnforceNumberType(left, left_type);
10747 right = EnforceNumberType(right, right_type); 10748 right = EnforceNumberType(right, right_type);
10748 } 10749 }
10749 10750
10750 Representation result_rep = RepresentationFor(result_type); 10751 Representation result_rep = RepresentationFor(result_type);
10751 10752
10752 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 10753 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) ||
10753 (right_rep.IsTagged() && !right_rep.IsSmi()); 10754 (right_rep.IsTagged() && !right_rep.IsSmi());
10754 10755
10755 HInstruction* instr = NULL; 10756 HInstruction* instr = NULL;
10756 // Only the stub is allowed to call into the runtime, since otherwise we would 10757 // Only the stub is allowed to call into the runtime, since otherwise we would
10757 // inline several instructions (including the two pushes) for every tagged 10758 // inline several instructions (including the two pushes) for every tagged
10758 // operation in optimized code, which is more expensive, than a stub call. 10759 // operation in optimized code, which is more expensive, than a stub call.
10759 if (graph()->info()->IsStub() && is_non_primitive) { 10760 if (graph()->info()->IsStub() && is_non_primitive) {
10760 HValue* function = AddLoadJSBuiltin( 10761 HValue* function = AddLoadJSBuiltin(
10761 BinaryOpIC::TokenToJSBuiltin(op, language_mode)); 10762 BinaryOpIC::TokenToJSBuiltin(op, language_mode));
10762 Add<HPushArguments>(left, right); 10763 Add<HPushArguments>(left, right);
10763 instr = AddUncasted<HInvokeFunction>(function, 2); 10764 instr = AddUncasted<HInvokeFunction>(function, 2);
10764 } else { 10765 } else {
10765 switch (op) { 10766 switch (op) {
10766 case Token::ADD: 10767 case Token::ADD:
10767 instr = AddUncasted<HAdd>(left, right); 10768 instr = AddUncasted<HAdd>(left, right, language_mode);
10768 break; 10769 break;
10769 case Token::SUB: 10770 case Token::SUB:
10770 instr = AddUncasted<HSub>(left, right); 10771 instr = AddUncasted<HSub>(left, right, language_mode);
10771 break; 10772 break;
10772 case Token::MUL: 10773 case Token::MUL:
10773 instr = AddUncasted<HMul>(left, right); 10774 instr = AddUncasted<HMul>(left, right, language_mode);
10774 break; 10775 break;
10775 case Token::MOD: { 10776 case Token::MOD: {
10776 if (fixed_right_arg.IsJust() && 10777 if (fixed_right_arg.IsJust() &&
10777 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { 10778 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) {
10778 HConstant* fixed_right = 10779 HConstant* fixed_right =
10779 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); 10780 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust()));
10780 IfBuilder if_same(this); 10781 IfBuilder if_same(this);
10781 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); 10782 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
10782 if_same.Then(); 10783 if_same.Then();
10783 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); 10784 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation);
10784 right = fixed_right; 10785 right = fixed_right;
10785 } 10786 }
10786 instr = AddUncasted<HMod>(left, right); 10787 instr = AddUncasted<HMod>(left, right, language_mode);
10787 break; 10788 break;
10788 } 10789 }
10789 case Token::DIV: 10790 case Token::DIV:
10790 instr = AddUncasted<HDiv>(left, right); 10791 instr = AddUncasted<HDiv>(left, right, language_mode);
10791 break; 10792 break;
10792 case Token::BIT_XOR: 10793 case Token::BIT_XOR:
10793 case Token::BIT_AND: 10794 case Token::BIT_AND:
10794 instr = AddUncasted<HBitwise>(op, left, right); 10795 instr = AddUncasted<HBitwise>(op, left, right, language_mode);
10795 break; 10796 break;
10796 case Token::BIT_OR: { 10797 case Token::BIT_OR: {
10797 HValue* operand, *shift_amount; 10798 HValue* operand, *shift_amount;
10798 if (left_type->Is(Type::Signed32()) && 10799 if (left_type->Is(Type::Signed32()) &&
10799 right_type->Is(Type::Signed32()) && 10800 right_type->Is(Type::Signed32()) &&
10800 MatchRotateRight(left, right, &operand, &shift_amount)) { 10801 MatchRotateRight(left, right, &operand, &shift_amount)) {
10801 instr = AddUncasted<HRor>(operand, shift_amount); 10802 instr = AddUncasted<HRor>(operand, shift_amount, language_mode);
10802 } else { 10803 } else {
10803 instr = AddUncasted<HBitwise>(op, left, right); 10804 instr = AddUncasted<HBitwise>(op, left, right, language_mode);
10804 } 10805 }
10805 break; 10806 break;
10806 } 10807 }
10807 case Token::SAR: 10808 case Token::SAR:
10808 instr = AddUncasted<HSar>(left, right); 10809 instr = AddUncasted<HSar>(left, right, language_mode);
10809 break; 10810 break;
10810 case Token::SHR: 10811 case Token::SHR:
10811 instr = AddUncasted<HShr>(left, right); 10812 instr = AddUncasted<HShr>(left, right, language_mode);
10812 if (instr->IsShr() && CanBeZero(right)) { 10813 if (instr->IsShr() && CanBeZero(right)) {
10813 graph()->RecordUint32Instruction(instr); 10814 graph()->RecordUint32Instruction(instr);
10814 } 10815 }
10815 break; 10816 break;
10816 case Token::SHL: 10817 case Token::SHL:
10817 instr = AddUncasted<HShl>(left, right); 10818 instr = AddUncasted<HShl>(left, right, language_mode);
10818 break; 10819 break;
10819 default: 10820 default:
10820 UNREACHABLE(); 10821 UNREACHABLE();
10821 } 10822 }
10822 } 10823 }
10823 10824
10824 if (instr->IsBinaryOperation()) { 10825 if (instr->IsBinaryOperation()) {
10825 HBinaryOperation* binop = HBinaryOperation::cast(instr); 10826 HBinaryOperation* binop = HBinaryOperation::cast(instr);
10826 binop->set_observed_input_representation(1, left_rep); 10827 binop->set_observed_input_representation(1, left_rep);
10827 binop->set_observed_input_representation(2, right_rep); 10828 binop->set_observed_input_representation(2, right_rep);
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
12047 } 12048 }
12048 12049
12049 12050
12050 // Fast support for StringAdd. 12051 // Fast support for StringAdd.
12051 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 12052 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
12052 DCHECK_EQ(2, call->arguments()->length()); 12053 DCHECK_EQ(2, call->arguments()->length());
12053 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 12054 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
12054 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 12055 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
12055 HValue* right = Pop(); 12056 HValue* right = Pop();
12056 HValue* left = Pop(); 12057 HValue* left = Pop();
12057 HInstruction* result = NewUncasted<HStringAdd>(left, right); 12058 HInstruction* result = NewUncasted<HStringAdd>(left, right,
12059 function_language_mode());
12058 return ast_context()->ReturnInstruction(result, call->id()); 12060 return ast_context()->ReturnInstruction(result, call->id());
12059 } 12061 }
12060 12062
12061 12063
12062 // Fast support for SubString. 12064 // Fast support for SubString.
12063 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 12065 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
12064 DCHECK_EQ(3, call->arguments()->length()); 12066 DCHECK_EQ(3, call->arguments()->length());
12065 CHECK_ALIVE(VisitExpressions(call->arguments())); 12067 CHECK_ALIVE(VisitExpressions(call->arguments()));
12066 PushArgumentsFromEnvironment(call->arguments()->length()); 12068 PushArgumentsFromEnvironment(call->arguments()->length());
12067 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 12069 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
13144 if (ShouldProduceTraceOutput()) { 13146 if (ShouldProduceTraceOutput()) {
13145 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13147 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13146 } 13148 }
13147 13149
13148 #ifdef DEBUG 13150 #ifdef DEBUG
13149 graph_->Verify(false); // No full verify. 13151 graph_->Verify(false); // No full verify.
13150 #endif 13152 #endif
13151 } 13153 }
13152 13154
13153 } } // namespace v8::internal 13155 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698