| 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 6577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6588 int argument_count = 1; | 6588 int argument_count = 1; |
| 6589 if (!info->IsLoad()) { | 6589 if (!info->IsLoad()) { |
| 6590 argument_count = 2; | 6590 argument_count = 2; |
| 6591 Push(value); | 6591 Push(value); |
| 6592 } | 6592 } |
| 6593 | 6593 |
| 6594 if (info->NeedsWrappingFor(info->accessor())) { | 6594 if (info->NeedsWrappingFor(info->accessor())) { |
| 6595 HValue* function = Add<HConstant>(info->accessor()); | 6595 HValue* function = Add<HConstant>(info->accessor()); |
| 6596 PushArgumentsFromEnvironment(argument_count); | 6596 PushArgumentsFromEnvironment(argument_count); |
| 6597 return New<HCallFunction>(function, argument_count, | 6597 return New<HCallFunction>(function, argument_count, |
| 6598 ConvertReceiverMode::kNotNullOrUndefined); | 6598 ConvertReceiverMode::kNotNullOrUndefined, |
| 6599 TailCallMode::kDisallow); |
| 6599 } else if (FLAG_inline_accessors && can_inline_accessor) { | 6600 } else if (FLAG_inline_accessors && can_inline_accessor) { |
| 6600 bool success = info->IsLoad() | 6601 bool success = info->IsLoad() |
| 6601 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) | 6602 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) |
| 6602 : TryInlineSetter( | 6603 : TryInlineSetter( |
| 6603 info->accessor(), info->map(), ast_id, return_id, value); | 6604 info->accessor(), info->map(), ast_id, return_id, value); |
| 6604 if (success || HasStackOverflow()) return NULL; | 6605 if (success || HasStackOverflow()) return NULL; |
| 6605 } | 6606 } |
| 6606 | 6607 |
| 6607 PushArgumentsFromEnvironment(argument_count); | 6608 PushArgumentsFromEnvironment(argument_count); |
| 6608 return BuildCallConstantFunction(info->accessor(), argument_count); | 6609 return BuildCallConstantFunction(info->accessor(), argument_count); |
| (...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8163 // entire compilation by setting stack overflow on the visitor. | 8164 // entire compilation by setting stack overflow on the visitor. |
| 8164 if (HasStackOverflow()) return; | 8165 if (HasStackOverflow()) return; |
| 8165 } else { | 8166 } else { |
| 8166 // Since HWrapReceiver currently cannot actually wrap numbers and strings, | 8167 // Since HWrapReceiver currently cannot actually wrap numbers and strings, |
| 8167 // use the regular CallFunctionStub for method calls to wrap the receiver. | 8168 // use the regular CallFunctionStub for method calls to wrap the receiver. |
| 8168 // TODO(verwaest): Support creation of value wrappers directly in | 8169 // TODO(verwaest): Support creation of value wrappers directly in |
| 8169 // HWrapReceiver. | 8170 // HWrapReceiver. |
| 8170 HInstruction* call = | 8171 HInstruction* call = |
| 8171 needs_wrapping ? NewUncasted<HCallFunction>( | 8172 needs_wrapping ? NewUncasted<HCallFunction>( |
| 8172 function, argument_count, | 8173 function, argument_count, |
| 8173 ConvertReceiverMode::kNotNullOrUndefined) | 8174 ConvertReceiverMode::kNotNullOrUndefined, |
| 8175 expr->tail_call_mode()) |
| 8174 : BuildCallConstantFunction(target, argument_count); | 8176 : BuildCallConstantFunction(target, argument_count); |
| 8175 PushArgumentsFromEnvironment(argument_count); | 8177 PushArgumentsFromEnvironment(argument_count); |
| 8176 AddInstruction(call); | 8178 AddInstruction(call); |
| 8177 Drop(1); // Drop the function. | 8179 Drop(1); // Drop the function. |
| 8178 if (!ast_context()->IsEffect()) Push(call); | 8180 if (!ast_context()->IsEffect()) Push(call); |
| 8179 } | 8181 } |
| 8180 | 8182 |
| 8181 if (current_block() != NULL) Goto(join); | 8183 if (current_block() != NULL) Goto(join); |
| 8182 set_current_block(if_false); | 8184 set_current_block(if_false); |
| 8183 } | 8185 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8194 name, NULL, prop->IsUninitialized()); | 8196 name, NULL, prop->IsUninitialized()); |
| 8195 AddInstruction(function); | 8197 AddInstruction(function); |
| 8196 Push(function); | 8198 Push(function); |
| 8197 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 8199 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 8198 | 8200 |
| 8199 environment()->SetExpressionStackAt(1, function); | 8201 environment()->SetExpressionStackAt(1, function); |
| 8200 environment()->SetExpressionStackAt(0, receiver); | 8202 environment()->SetExpressionStackAt(0, receiver); |
| 8201 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8203 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8202 | 8204 |
| 8203 HInstruction* call = New<HCallFunction>( | 8205 HInstruction* call = New<HCallFunction>( |
| 8204 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined); | 8206 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined, |
| 8207 expr->tail_call_mode()); |
| 8205 | 8208 |
| 8206 PushArgumentsFromEnvironment(argument_count); | 8209 PushArgumentsFromEnvironment(argument_count); |
| 8207 | 8210 |
| 8208 Drop(1); // Function. | 8211 Drop(1); // Function. |
| 8209 | 8212 |
| 8210 if (join != NULL) { | 8213 if (join != NULL) { |
| 8211 AddInstruction(call); | 8214 AddInstruction(call); |
| 8212 if (!ast_context()->IsEffect()) Push(call); | 8215 if (!ast_context()->IsEffect()) Push(call); |
| 8213 Goto(join); | 8216 Goto(join); |
| 8214 } else { | 8217 } else { |
| (...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9721 if (TryInlineApiMethodCall(expr, receiver, maps)) return; | 9724 if (TryInlineApiMethodCall(expr, receiver, maps)) return; |
| 9722 | 9725 |
| 9723 // Wrap the receiver if necessary. | 9726 // Wrap the receiver if necessary. |
| 9724 if (NeedsWrapping(maps->first(), known_function)) { | 9727 if (NeedsWrapping(maps->first(), known_function)) { |
| 9725 // Since HWrapReceiver currently cannot actually wrap numbers and | 9728 // Since HWrapReceiver currently cannot actually wrap numbers and |
| 9726 // strings, use the regular CallFunctionStub for method calls to wrap | 9729 // strings, use the regular CallFunctionStub for method calls to wrap |
| 9727 // the receiver. | 9730 // the receiver. |
| 9728 // TODO(verwaest): Support creation of value wrappers directly in | 9731 // TODO(verwaest): Support creation of value wrappers directly in |
| 9729 // HWrapReceiver. | 9732 // HWrapReceiver. |
| 9730 call = New<HCallFunction>(function, argument_count, | 9733 call = New<HCallFunction>(function, argument_count, |
| 9731 ConvertReceiverMode::kNotNullOrUndefined); | 9734 ConvertReceiverMode::kNotNullOrUndefined, |
| 9735 expr->tail_call_mode()); |
| 9732 } else if (TryInlineCall(expr)) { | 9736 } else if (TryInlineCall(expr)) { |
| 9733 return; | 9737 return; |
| 9734 } else { | 9738 } else { |
| 9735 call = BuildCallConstantFunction(known_function, argument_count); | 9739 call = BuildCallConstantFunction(known_function, argument_count); |
| 9736 } | 9740 } |
| 9737 | 9741 |
| 9738 } else { | 9742 } else { |
| 9739 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; | 9743 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| 9740 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { | 9744 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { |
| 9741 // We have to use EAGER deoptimization here because Deoptimizer::SOFT | 9745 // We have to use EAGER deoptimization here because Deoptimizer::SOFT |
| 9742 // gets ignored by the always-opt flag, which leads to incorrect code. | 9746 // gets ignored by the always-opt flag, which leads to incorrect code. |
| 9743 Add<HDeoptimize>( | 9747 Add<HDeoptimize>( |
| 9744 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, | 9748 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, |
| 9745 Deoptimizer::EAGER); | 9749 Deoptimizer::EAGER); |
| 9746 arguments_flag = ARGUMENTS_FAKED; | 9750 arguments_flag = ARGUMENTS_FAKED; |
| 9747 } | 9751 } |
| 9748 | 9752 |
| 9749 // Push the function under the receiver. | 9753 // Push the function under the receiver. |
| 9750 environment()->SetExpressionStackAt(0, function); | 9754 environment()->SetExpressionStackAt(0, function); |
| 9751 Push(receiver); | 9755 Push(receiver); |
| 9752 | 9756 |
| 9753 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); | 9757 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
| 9754 call = New<HCallFunction>(function, argument_count, | 9758 call = New<HCallFunction>(function, argument_count, |
| 9755 ConvertReceiverMode::kNotNullOrUndefined); | 9759 ConvertReceiverMode::kNotNullOrUndefined, |
| 9760 expr->tail_call_mode()); |
| 9756 } | 9761 } |
| 9757 PushArgumentsFromEnvironment(argument_count); | 9762 PushArgumentsFromEnvironment(argument_count); |
| 9758 | 9763 |
| 9759 } else { | 9764 } else { |
| 9760 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9765 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9761 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9766 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 9762 return Bailout(kPossibleDirectCallToEval); | 9767 return Bailout(kPossibleDirectCallToEval); |
| 9763 } | 9768 } |
| 9764 | 9769 |
| 9765 // The function is on the stack in the unoptimized code during | 9770 // The function is on the stack in the unoptimized code during |
| (...skipping 30 matching lines...) Expand all Loading... |
| 9796 } | 9801 } |
| 9797 if (TryInlineApiFunctionCall(expr, receiver)) return; | 9802 if (TryInlineApiFunctionCall(expr, receiver)) return; |
| 9798 if (TryHandleArrayCall(expr, function)) return; | 9803 if (TryHandleArrayCall(expr, function)) return; |
| 9799 if (TryInlineCall(expr)) return; | 9804 if (TryInlineCall(expr)) return; |
| 9800 | 9805 |
| 9801 PushArgumentsFromEnvironment(argument_count); | 9806 PushArgumentsFromEnvironment(argument_count); |
| 9802 call = BuildCallConstantFunction(expr->target(), argument_count); | 9807 call = BuildCallConstantFunction(expr->target(), argument_count); |
| 9803 } else { | 9808 } else { |
| 9804 PushArgumentsFromEnvironment(argument_count); | 9809 PushArgumentsFromEnvironment(argument_count); |
| 9805 HCallFunction* call_function = New<HCallFunction>( | 9810 HCallFunction* call_function = New<HCallFunction>( |
| 9806 function, argument_count, ConvertReceiverMode::kNullOrUndefined); | 9811 function, argument_count, ConvertReceiverMode::kNullOrUndefined, |
| 9812 expr->tail_call_mode()); |
| 9807 call = call_function; | 9813 call = call_function; |
| 9808 if (expr->is_uninitialized() && | 9814 if (expr->is_uninitialized() && |
| 9809 expr->IsUsingCallFeedbackICSlot(isolate())) { | 9815 expr->IsUsingCallFeedbackICSlot(isolate())) { |
| 9810 // We've never seen this call before, so let's have Crankshaft learn | 9816 // We've never seen this call before, so let's have Crankshaft learn |
| 9811 // through the type vector. | 9817 // through the type vector. |
| 9812 Handle<TypeFeedbackVector> vector = | 9818 Handle<TypeFeedbackVector> vector = |
| 9813 handle(current_feedback_vector(), isolate()); | 9819 handle(current_feedback_vector(), isolate()); |
| 9814 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); | 9820 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); |
| 9815 call_function->SetVectorAndSlot(vector, slot); | 9821 call_function->SetVectorAndSlot(vector, slot); |
| 9816 } | 9822 } |
| (...skipping 3815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13632 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13638 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13633 } | 13639 } |
| 13634 | 13640 |
| 13635 #ifdef DEBUG | 13641 #ifdef DEBUG |
| 13636 graph_->Verify(false); // No full verify. | 13642 graph_->Verify(false); // No full verify. |
| 13637 #endif | 13643 #endif |
| 13638 } | 13644 } |
| 13639 | 13645 |
| 13640 } // namespace internal | 13646 } // namespace internal |
| 13641 } // namespace v8 | 13647 } // namespace v8 |
| OLD | NEW |