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

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

Issue 1683793004: [crankshaft] Disable Crankshaft when it sees a tail call. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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/crankshaft/arm64/lithium-codegen-arm64.cc ('k') | src/crankshaft/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/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 6603 matching lines...) Expand 10 before | Expand all | Expand 10 after
6614 int argument_count = 1; 6614 int argument_count = 1;
6615 if (!info->IsLoad()) { 6615 if (!info->IsLoad()) {
6616 argument_count = 2; 6616 argument_count = 2;
6617 Push(value); 6617 Push(value);
6618 } 6618 }
6619 6619
6620 if (info->NeedsWrappingFor(info->accessor())) { 6620 if (info->NeedsWrappingFor(info->accessor())) {
6621 HValue* function = Add<HConstant>(info->accessor()); 6621 HValue* function = Add<HConstant>(info->accessor());
6622 PushArgumentsFromEnvironment(argument_count); 6622 PushArgumentsFromEnvironment(argument_count);
6623 return New<HCallFunction>(function, argument_count, 6623 return New<HCallFunction>(function, argument_count,
6624 ConvertReceiverMode::kNotNullOrUndefined, 6624 ConvertReceiverMode::kNotNullOrUndefined);
6625 TailCallMode::kDisallow);
6626 } else if (FLAG_inline_accessors && can_inline_accessor) { 6625 } else if (FLAG_inline_accessors && can_inline_accessor) {
6627 bool success = info->IsLoad() 6626 bool success = info->IsLoad()
6628 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6627 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6629 : TryInlineSetter( 6628 : TryInlineSetter(
6630 info->accessor(), info->map(), ast_id, return_id, value); 6629 info->accessor(), info->map(), ast_id, return_id, value);
6631 if (success || HasStackOverflow()) return NULL; 6630 if (success || HasStackOverflow()) return NULL;
6632 } 6631 }
6633 6632
6634 PushArgumentsFromEnvironment(argument_count); 6633 PushArgumentsFromEnvironment(argument_count);
6635 return BuildCallConstantFunction(info->accessor(), argument_count); 6634 return BuildCallConstantFunction(info->accessor(), argument_count);
(...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after
8190 // entire compilation by setting stack overflow on the visitor. 8189 // entire compilation by setting stack overflow on the visitor.
8191 if (HasStackOverflow()) return; 8190 if (HasStackOverflow()) return;
8192 } else { 8191 } else {
8193 // Since HWrapReceiver currently cannot actually wrap numbers and strings, 8192 // Since HWrapReceiver currently cannot actually wrap numbers and strings,
8194 // use the regular CallFunctionStub for method calls to wrap the receiver. 8193 // use the regular CallFunctionStub for method calls to wrap the receiver.
8195 // TODO(verwaest): Support creation of value wrappers directly in 8194 // TODO(verwaest): Support creation of value wrappers directly in
8196 // HWrapReceiver. 8195 // HWrapReceiver.
8197 HInstruction* call = 8196 HInstruction* call =
8198 needs_wrapping ? NewUncasted<HCallFunction>( 8197 needs_wrapping ? NewUncasted<HCallFunction>(
8199 function, argument_count, 8198 function, argument_count,
8200 ConvertReceiverMode::kNotNullOrUndefined, 8199 ConvertReceiverMode::kNotNullOrUndefined)
8201 expr->tail_call_mode())
8202 : BuildCallConstantFunction(target, argument_count); 8200 : BuildCallConstantFunction(target, argument_count);
8203 PushArgumentsFromEnvironment(argument_count); 8201 PushArgumentsFromEnvironment(argument_count);
8204 AddInstruction(call); 8202 AddInstruction(call);
8205 Drop(1); // Drop the function. 8203 Drop(1); // Drop the function.
8206 if (!ast_context()->IsEffect()) Push(call); 8204 if (!ast_context()->IsEffect()) Push(call);
8207 } 8205 }
8208 8206
8209 if (current_block() != NULL) Goto(join); 8207 if (current_block() != NULL) Goto(join);
8210 set_current_block(if_false); 8208 set_current_block(if_false);
8211 } 8209 }
(...skipping 10 matching lines...) Expand all
8222 name, NULL, prop->IsUninitialized()); 8220 name, NULL, prop->IsUninitialized());
8223 AddInstruction(function); 8221 AddInstruction(function);
8224 Push(function); 8222 Push(function);
8225 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 8223 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8226 8224
8227 environment()->SetExpressionStackAt(1, function); 8225 environment()->SetExpressionStackAt(1, function);
8228 environment()->SetExpressionStackAt(0, receiver); 8226 environment()->SetExpressionStackAt(0, receiver);
8229 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8227 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8230 8228
8231 HInstruction* call = New<HCallFunction>( 8229 HInstruction* call = New<HCallFunction>(
8232 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined, 8230 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined);
8233 expr->tail_call_mode());
8234 8231
8235 PushArgumentsFromEnvironment(argument_count); 8232 PushArgumentsFromEnvironment(argument_count);
8236 8233
8237 Drop(1); // Function. 8234 Drop(1); // Function.
8238 8235
8239 if (join != NULL) { 8236 if (join != NULL) {
8240 AddInstruction(call); 8237 AddInstruction(call);
8241 if (!ast_context()->IsEffect()) Push(call); 8238 if (!ast_context()->IsEffect()) Push(call);
8242 Goto(join); 8239 Goto(join);
8243 } else { 8240 } else {
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after
9686 if (args->length() != 2) return false; 9683 if (args->length() != 2) return false;
9687 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 9684 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
9688 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 9685 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
9689 HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); 9686 HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
9690 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 9687 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
9691 return true; 9688 return true;
9692 } 9689 }
9693 9690
9694 9691
9695 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 9692 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
9693 if (expr->tail_call_mode() == TailCallMode::kAllow) {
9694 return Bailout(kTailCall);
9695 }
9696 DCHECK(!HasStackOverflow()); 9696 DCHECK(!HasStackOverflow());
9697 DCHECK(current_block() != NULL); 9697 DCHECK(current_block() != NULL);
9698 DCHECK(current_block()->HasPredecessor()); 9698 DCHECK(current_block()->HasPredecessor());
9699 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); 9699 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position());
9700 Expression* callee = expr->expression(); 9700 Expression* callee = expr->expression();
9701 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 9701 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
9702 HInstruction* call = NULL; 9702 HInstruction* call = NULL;
9703 9703
9704 Property* prop = callee->AsProperty(); 9704 Property* prop = callee->AsProperty();
9705 if (prop != NULL) { 9705 if (prop != NULL) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
9752 if (TryInlineApiMethodCall(expr, receiver, maps)) return; 9752 if (TryInlineApiMethodCall(expr, receiver, maps)) return;
9753 9753
9754 // Wrap the receiver if necessary. 9754 // Wrap the receiver if necessary.
9755 if (NeedsWrapping(maps->first(), known_function)) { 9755 if (NeedsWrapping(maps->first(), known_function)) {
9756 // Since HWrapReceiver currently cannot actually wrap numbers and 9756 // Since HWrapReceiver currently cannot actually wrap numbers and
9757 // strings, use the regular CallFunctionStub for method calls to wrap 9757 // strings, use the regular CallFunctionStub for method calls to wrap
9758 // the receiver. 9758 // the receiver.
9759 // TODO(verwaest): Support creation of value wrappers directly in 9759 // TODO(verwaest): Support creation of value wrappers directly in
9760 // HWrapReceiver. 9760 // HWrapReceiver.
9761 call = New<HCallFunction>(function, argument_count, 9761 call = New<HCallFunction>(function, argument_count,
9762 ConvertReceiverMode::kNotNullOrUndefined, 9762 ConvertReceiverMode::kNotNullOrUndefined);
9763 expr->tail_call_mode());
9764 } else if (TryInlineCall(expr)) { 9763 } else if (TryInlineCall(expr)) {
9765 return; 9764 return;
9766 } else { 9765 } else {
9767 call = BuildCallConstantFunction(known_function, argument_count); 9766 call = BuildCallConstantFunction(known_function, argument_count);
9768 } 9767 }
9769 9768
9770 } else { 9769 } else {
9771 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; 9770 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
9772 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { 9771 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
9773 // We have to use EAGER deoptimization here because Deoptimizer::SOFT 9772 // We have to use EAGER deoptimization here because Deoptimizer::SOFT
9774 // gets ignored by the always-opt flag, which leads to incorrect code. 9773 // gets ignored by the always-opt flag, which leads to incorrect code.
9775 Add<HDeoptimize>( 9774 Add<HDeoptimize>(
9776 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, 9775 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments,
9777 Deoptimizer::EAGER); 9776 Deoptimizer::EAGER);
9778 arguments_flag = ARGUMENTS_FAKED; 9777 arguments_flag = ARGUMENTS_FAKED;
9779 } 9778 }
9780 9779
9781 // Push the function under the receiver. 9780 // Push the function under the receiver.
9782 environment()->SetExpressionStackAt(0, function); 9781 environment()->SetExpressionStackAt(0, function);
9783 Push(receiver); 9782 Push(receiver);
9784 9783
9785 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); 9784 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
9786 call = New<HCallFunction>(function, argument_count, 9785 call = New<HCallFunction>(function, argument_count,
9787 ConvertReceiverMode::kNotNullOrUndefined, 9786 ConvertReceiverMode::kNotNullOrUndefined);
9788 expr->tail_call_mode());
9789 } 9787 }
9790 PushArgumentsFromEnvironment(argument_count); 9788 PushArgumentsFromEnvironment(argument_count);
9791 9789
9792 } else { 9790 } else {
9793 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 9791 VariableProxy* proxy = expr->expression()->AsVariableProxy();
9794 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 9792 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
9795 return Bailout(kPossibleDirectCallToEval); 9793 return Bailout(kPossibleDirectCallToEval);
9796 } 9794 }
9797 9795
9798 // The function is on the stack in the unoptimized code during 9796 // The function is on the stack in the unoptimized code during
(...skipping 30 matching lines...) Expand all
9829 } 9827 }
9830 if (TryInlineApiFunctionCall(expr, receiver)) return; 9828 if (TryInlineApiFunctionCall(expr, receiver)) return;
9831 if (TryHandleArrayCall(expr, function)) return; 9829 if (TryHandleArrayCall(expr, function)) return;
9832 if (TryInlineCall(expr)) return; 9830 if (TryInlineCall(expr)) return;
9833 9831
9834 PushArgumentsFromEnvironment(argument_count); 9832 PushArgumentsFromEnvironment(argument_count);
9835 call = BuildCallConstantFunction(expr->target(), argument_count); 9833 call = BuildCallConstantFunction(expr->target(), argument_count);
9836 } else { 9834 } else {
9837 PushArgumentsFromEnvironment(argument_count); 9835 PushArgumentsFromEnvironment(argument_count);
9838 HCallFunction* call_function = New<HCallFunction>( 9836 HCallFunction* call_function = New<HCallFunction>(
9839 function, argument_count, ConvertReceiverMode::kNullOrUndefined, 9837 function, argument_count, ConvertReceiverMode::kNullOrUndefined);
9840 expr->tail_call_mode());
9841 call = call_function; 9838 call = call_function;
9842 if (expr->is_uninitialized() && 9839 if (expr->is_uninitialized() &&
9843 expr->IsUsingCallFeedbackICSlot(isolate())) { 9840 expr->IsUsingCallFeedbackICSlot(isolate())) {
9844 // We've never seen this call before, so let's have Crankshaft learn 9841 // We've never seen this call before, so let's have Crankshaft learn
9845 // through the type vector. 9842 // through the type vector.
9846 Handle<TypeFeedbackVector> vector = 9843 Handle<TypeFeedbackVector> vector =
9847 handle(current_feedback_vector(), isolate()); 9844 handle(current_feedback_vector(), isolate());
9848 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); 9845 FeedbackVectorSlot slot = expr->CallFeedbackICSlot();
9849 call_function->SetVectorAndSlot(vector, slot); 9846 call_function->SetVectorAndSlot(vector, slot);
9850 } 9847 }
(...skipping 3806 matching lines...) Expand 10 before | Expand all | Expand 10 after
13657 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13654 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13658 } 13655 }
13659 13656
13660 #ifdef DEBUG 13657 #ifdef DEBUG
13661 graph_->Verify(false); // No full verify. 13658 graph_->Verify(false); // No full verify.
13662 #endif 13659 #endif
13663 } 13660 }
13664 13661
13665 } // namespace internal 13662 } // namespace internal
13666 } // namespace v8 13663 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/arm64/lithium-codegen-arm64.cc ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698