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

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 1609893003: [es6] Tail calls support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Support for CS and TF compilers added Created 4 years, 11 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
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/crankshaft/hydrogen.h" 5 #include "src/crankshaft/hydrogen.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/allocation-site-scopes.h" 9 #include "src/allocation-site-scopes.h"
10 #include "src/ast/ast-numbering.h" 10 #include "src/ast/ast-numbering.h"
(...skipping 6556 matching lines...) Expand 10 before | Expand all | Expand 10 after
6567 int argument_count = 1; 6567 int argument_count = 1;
6568 if (!info->IsLoad()) { 6568 if (!info->IsLoad()) {
6569 argument_count = 2; 6569 argument_count = 2;
6570 Push(value); 6570 Push(value);
6571 } 6571 }
6572 6572
6573 if (info->NeedsWrappingFor(info->accessor())) { 6573 if (info->NeedsWrappingFor(info->accessor())) {
6574 HValue* function = Add<HConstant>(info->accessor()); 6574 HValue* function = Add<HConstant>(info->accessor());
6575 PushArgumentsFromEnvironment(argument_count); 6575 PushArgumentsFromEnvironment(argument_count);
6576 return New<HCallFunction>(function, argument_count, 6576 return New<HCallFunction>(function, argument_count,
6577 ConvertReceiverMode::kNotNullOrUndefined); 6577 ConvertReceiverMode::kNotNullOrUndefined,
6578 TailCallMode::kDisallow);
6578 } else if (FLAG_inline_accessors && can_inline_accessor) { 6579 } else if (FLAG_inline_accessors && can_inline_accessor) {
6579 bool success = info->IsLoad() 6580 bool success = info->IsLoad()
6580 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6581 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6581 : TryInlineSetter( 6582 : TryInlineSetter(
6582 info->accessor(), info->map(), ast_id, return_id, value); 6583 info->accessor(), info->map(), ast_id, return_id, value);
6583 if (success || HasStackOverflow()) return NULL; 6584 if (success || HasStackOverflow()) return NULL;
6584 } 6585 }
6585 6586
6586 PushArgumentsFromEnvironment(argument_count); 6587 PushArgumentsFromEnvironment(argument_count);
6587 return BuildCallConstantFunction(info->accessor(), argument_count); 6588 return BuildCallConstantFunction(info->accessor(), argument_count);
(...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after
8142 // entire compilation by setting stack overflow on the visitor. 8143 // entire compilation by setting stack overflow on the visitor.
8143 if (HasStackOverflow()) return; 8144 if (HasStackOverflow()) return;
8144 } else { 8145 } else {
8145 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8146 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8146 // use the regular CallFunctionStub for method calls to wrap the receiver. 8147 // use the regular CallFunctionStub for method calls to wrap the receiver.
8147 // TODO(verwaest): Support creation of value wrappers directly in 8148 // TODO(verwaest): Support creation of value wrappers directly in
8148 // HWrapReceiver. 8149 // HWrapReceiver.
8149 HInstruction* call = 8150 HInstruction* call =
8150 needs_wrapping ? NewUncasted<HCallFunction>( 8151 needs_wrapping ? NewUncasted<HCallFunction>(
8151 function, argument_count, 8152 function, argument_count,
8152 ConvertReceiverMode::kNotNullOrUndefined) 8153 ConvertReceiverMode::kNotNullOrUndefined,
8154 expr->tail_call_mode())
8153 : BuildCallConstantFunction(target, argument_count); 8155 : BuildCallConstantFunction(target, argument_count);
8154 PushArgumentsFromEnvironment(argument_count); 8156 PushArgumentsFromEnvironment(argument_count);
8155 AddInstruction(call); 8157 AddInstruction(call);
8156 Drop(1); // Drop the function. 8158 Drop(1); // Drop the function.
8157 if (!ast_context()->IsEffect()) Push(call); 8159 if (!ast_context()->IsEffect()) Push(call);
8158 } 8160 }
8159 8161
8160 if (current_block() != NULL) Goto(join); 8162 if (current_block() != NULL) Goto(join);
8161 set_current_block(if_false); 8163 set_current_block(if_false);
8162 } 8164 }
(...skipping 10 matching lines...) Expand all
8173 name, NULL, prop->IsUninitialized()); 8175 name, NULL, prop->IsUninitialized());
8174 AddInstruction(function); 8176 AddInstruction(function);
8175 Push(function); 8177 Push(function);
8176 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8178 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8177 8179
8178 environment()->SetExpressionStackAt(1, function); 8180 environment()->SetExpressionStackAt(1, function);
8179 environment()->SetExpressionStackAt(0, receiver); 8181 environment()->SetExpressionStackAt(0, receiver);
8180 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8182 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8181 8183
8182 HInstruction* call = New<HCallFunction>( 8184 HInstruction* call = New<HCallFunction>(
8183 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined); 8185 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined,
8186 expr->tail_call_mode());
8184 8187
8185 PushArgumentsFromEnvironment(argument_count); 8188 PushArgumentsFromEnvironment(argument_count);
8186 8189
8187 Drop(1); // Function. 8190 Drop(1); // Function.
8188 8191
8189 if (join != NULL) { 8192 if (join != NULL) {
8190 AddInstruction(call); 8193 AddInstruction(call);
8191 if (!ast_context()->IsEffect()) Push(call); 8194 if (!ast_context()->IsEffect()) Push(call);
8192 Goto(join); 8195 Goto(join);
8193 } else { 8196 } else {
(...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after
9700 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9703 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9701 9704
9702 // Wrap the receiver if necessary. 9705 // Wrap the receiver if necessary.
9703 if (NeedsWrapping(maps->first(), known_function)) { 9706 if (NeedsWrapping(maps->first(), known_function)) {
9704 // Since HWrapReceiver currently cannot actually wrap numbers and 9707 // Since HWrapReceiver currently cannot actually wrap numbers and
9705 // strings, use the regular CallFunctionStub for method calls to wrap 9708 // strings, use the regular CallFunctionStub for method calls to wrap
9706 // the receiver. 9709 // the receiver.
9707 // TODO(verwaest): Support creation of value wrappers directly in 9710 // TODO(verwaest): Support creation of value wrappers directly in
9708 // HWrapReceiver. 9711 // HWrapReceiver.
9709 call = New<HCallFunction>(function, argument_count, 9712 call = New<HCallFunction>(function, argument_count,
9710 ConvertReceiverMode::kNotNullOrUndefined); 9713 ConvertReceiverMode::kNotNullOrUndefined,
9714 expr->tail_call_mode());
9711 } else if (TryInlineCall(expr)) { 9715 } else if (TryInlineCall(expr)) {
9712 return; 9716 return;
9713 } else { 9717 } else {
9714 call = BuildCallConstantFunction(known_function, argument_count); 9718 call = BuildCallConstantFunction(known_function, argument_count);
9715 } 9719 }
9716 9720
9717 } else { 9721 } else {
9718 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9722 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9719 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9723 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9720 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9724 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9721 // gets ignored by the always-opt flag, which leads to incorrect code. 9725 // gets ignored by the always-opt flag, which leads to incorrect code.
9722 Add<HDeoptimize>( 9726 Add<HDeoptimize>(
9723 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9727 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9724 Deoptimizer::EAGER); 9728 Deoptimizer::EAGER);
9725 arguments_flag = ARGUMENTS_FAKED; 9729 arguments_flag = ARGUMENTS_FAKED;
9726 } 9730 }
9727 9731
9728 // Push the function under the receiver. 9732 // Push the function under the receiver.
9729 environment()->SetExpressionStackAt(0, function); 9733 environment()->SetExpressionStackAt(0, function);
9730 Push(receiver); 9734 Push(receiver);
9731 9735
9732 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9736 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9733 call = New<HCallFunction>(function, argument_count, 9737 call = New<HCallFunction>(function, argument_count,
9734 ConvertReceiverMode::kNotNullOrUndefined); 9738 ConvertReceiverMode::kNotNullOrUndefined,
9739 expr->tail_call_mode());
9735 } 9740 }
9736 PushArgumentsFromEnvironment(argument_count); 9741 PushArgumentsFromEnvironment(argument_count);
9737 9742
9738 } else { 9743 } else {
9739 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9744 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9740 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9745 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9741 return Bailout(kPossibleDirectCallToEval); 9746 return Bailout(kPossibleDirectCallToEval);
9742 } 9747 }
9743 9748
9744 // The function is on the stack in the unoptimized code during 9749 // The function is on the stack in the unoptimized code during
(...skipping 30 matching lines...) Expand all
9775 } 9780 }
9776 if (TryInlineApiFunctionCall(expr, receiver)) return; 9781 if (TryInlineApiFunctionCall(expr, receiver)) return;
9777 if (TryHandleArrayCall(expr, function)) return; 9782 if (TryHandleArrayCall(expr, function)) return;
9778 if (TryInlineCall(expr)) return; 9783 if (TryInlineCall(expr)) return;
9779 9784
9780 PushArgumentsFromEnvironment(argument_count); 9785 PushArgumentsFromEnvironment(argument_count);
9781 call = BuildCallConstantFunction(expr->target(), argument_count); 9786 call = BuildCallConstantFunction(expr->target(), argument_count);
9782 } else { 9787 } else {
9783 PushArgumentsFromEnvironment(argument_count); 9788 PushArgumentsFromEnvironment(argument_count);
9784 HCallFunction* call_function = New<HCallFunction>( 9789 HCallFunction* call_function = New<HCallFunction>(
9785 function, argument_count, ConvertReceiverMode::kNullOrUndefined); 9790 function, argument_count, ConvertReceiverMode::kNullOrUndefined,
9791 expr->tail_call_mode());
9786 call = call_function; 9792 call = call_function;
9787 if (expr->is_uninitialized() && 9793 if (expr->is_uninitialized() &&
9788 expr->IsUsingCallFeedbackICSlot(isolate())) { 9794 expr->IsUsingCallFeedbackICSlot(isolate())) {
9789 // We've never seen this call before, so let's have Crankshaft learn 9795 // We've never seen this call before, so let's have Crankshaft learn
9790 // through the type vector. 9796 // through the type vector.
9791 Handle<TypeFeedbackVector> vector = 9797 Handle<TypeFeedbackVector> vector =
9792 handle(current_feedback_vector(), isolate()); 9798 handle(current_feedback_vector(), isolate());
9793 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); 9799 FeedbackVectorSlot slot = expr->CallFeedbackICSlot();
9794 call_function->SetVectorAndSlot(vector, slot); 9800 call_function->SetVectorAndSlot(vector, slot);
9795 } 9801 }
(...skipping 3791 matching lines...) Expand 10 before | Expand all | Expand 10 after
13587 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13593 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13588 } 13594 }
13589 13595
13590 #ifdef DEBUG 13596 #ifdef DEBUG
13591 graph_->Verify(false); // No full verify. 13597 graph_->Verify(false); // No full verify.
13592 #endif 13598 #endif
13593 } 13599 }
13594 13600
13595 } // namespace internal 13601 } // namespace internal
13596 } // namespace v8 13602 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698