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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |