| 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 6603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |