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-numbering.h" | 10 #include "src/ast-numbering.h" |
(...skipping 6571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6582 Push(checked_object); | 6582 Push(checked_object); |
6583 int argument_count = 1; | 6583 int argument_count = 1; |
6584 if (!info->IsLoad()) { | 6584 if (!info->IsLoad()) { |
6585 argument_count = 2; | 6585 argument_count = 2; |
6586 Push(value); | 6586 Push(value); |
6587 } | 6587 } |
6588 | 6588 |
6589 if (info->NeedsWrappingFor(info->accessor())) { | 6589 if (info->NeedsWrappingFor(info->accessor())) { |
6590 HValue* function = Add<HConstant>(info->accessor()); | 6590 HValue* function = Add<HConstant>(info->accessor()); |
6591 PushArgumentsFromEnvironment(argument_count); | 6591 PushArgumentsFromEnvironment(argument_count); |
6592 return New<HCallFunction>(function, argument_count); | 6592 return New<HCallFunction>(function, argument_count, |
| 6593 ConvertReceiverMode::kNotNullOrUndefined); |
6593 } else if (FLAG_inline_accessors && can_inline_accessor) { | 6594 } else if (FLAG_inline_accessors && can_inline_accessor) { |
6594 bool success = info->IsLoad() | 6595 bool success = info->IsLoad() |
6595 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) | 6596 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) |
6596 : TryInlineSetter( | 6597 : TryInlineSetter( |
6597 info->accessor(), info->map(), ast_id, return_id, value); | 6598 info->accessor(), info->map(), ast_id, return_id, value); |
6598 if (success || HasStackOverflow()) return NULL; | 6599 if (success || HasStackOverflow()) return NULL; |
6599 } | 6600 } |
6600 | 6601 |
6601 PushArgumentsFromEnvironment(argument_count); | 6602 PushArgumentsFromEnvironment(argument_count); |
6602 return BuildCallConstantFunction(info->accessor(), argument_count); | 6603 return BuildCallConstantFunction(info->accessor(), argument_count); |
(...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8163 if (try_inline && TryInlineCall(expr)) { | 8164 if (try_inline && TryInlineCall(expr)) { |
8164 // Trying to inline will signal that we should bailout from the | 8165 // Trying to inline will signal that we should bailout from the |
8165 // entire compilation by setting stack overflow on the visitor. | 8166 // entire compilation by setting stack overflow on the visitor. |
8166 if (HasStackOverflow()) return; | 8167 if (HasStackOverflow()) return; |
8167 } else { | 8168 } else { |
8168 // Since HWrapReceiver currently cannot actually wrap numbers and strings, | 8169 // Since HWrapReceiver currently cannot actually wrap numbers and strings, |
8169 // use the regular CallFunctionStub for method calls to wrap the receiver. | 8170 // use the regular CallFunctionStub for method calls to wrap the receiver. |
8170 // TODO(verwaest): Support creation of value wrappers directly in | 8171 // TODO(verwaest): Support creation of value wrappers directly in |
8171 // HWrapReceiver. | 8172 // HWrapReceiver. |
8172 HInstruction* call = | 8173 HInstruction* call = |
8173 needs_wrapping ? NewUncasted<HCallFunction>(function, argument_count) | 8174 needs_wrapping ? NewUncasted<HCallFunction>( |
| 8175 function, argument_count, |
| 8176 ConvertReceiverMode::kNotNullOrUndefined) |
8174 : BuildCallConstantFunction(target, argument_count); | 8177 : BuildCallConstantFunction(target, argument_count); |
8175 PushArgumentsFromEnvironment(argument_count); | 8178 PushArgumentsFromEnvironment(argument_count); |
8176 AddInstruction(call); | 8179 AddInstruction(call); |
8177 Drop(1); // Drop the function. | 8180 Drop(1); // Drop the function. |
8178 if (!ast_context()->IsEffect()) Push(call); | 8181 if (!ast_context()->IsEffect()) Push(call); |
8179 } | 8182 } |
8180 | 8183 |
8181 if (current_block() != NULL) Goto(join); | 8184 if (current_block() != NULL) Goto(join); |
8182 set_current_block(if_false); | 8185 set_current_block(if_false); |
8183 } | 8186 } |
8184 | 8187 |
8185 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 8188 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
8186 // know about and do not want to handle ones we've never seen. Otherwise | 8189 // know about and do not want to handle ones we've never seen. Otherwise |
8187 // use a generic IC. | 8190 // use a generic IC. |
8188 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { | 8191 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { |
8189 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); | 8192 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); |
8190 } else { | 8193 } else { |
8191 Property* prop = expr->expression()->AsProperty(); | 8194 Property* prop = expr->expression()->AsProperty(); |
8192 HInstruction* function = | 8195 HInstruction* function = |
8193 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, | 8196 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, |
8194 name, NULL, prop->IsUninitialized()); | 8197 name, NULL, prop->IsUninitialized()); |
8195 AddInstruction(function); | 8198 AddInstruction(function); |
8196 Push(function); | 8199 Push(function); |
8197 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 8200 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
8198 | 8201 |
8199 environment()->SetExpressionStackAt(1, function); | 8202 environment()->SetExpressionStackAt(1, function); |
8200 environment()->SetExpressionStackAt(0, receiver); | 8203 environment()->SetExpressionStackAt(0, receiver); |
8201 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8204 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
8202 | 8205 |
8203 HInstruction* call = New<HCallFunction>(function, argument_count); | 8206 HInstruction* call = New<HCallFunction>( |
| 8207 function, argument_count, ConvertReceiverMode::kNotNullOrUndefined); |
8204 | 8208 |
8205 PushArgumentsFromEnvironment(argument_count); | 8209 PushArgumentsFromEnvironment(argument_count); |
8206 | 8210 |
8207 Drop(1); // Function. | 8211 Drop(1); // Function. |
8208 | 8212 |
8209 if (join != NULL) { | 8213 if (join != NULL) { |
8210 AddInstruction(call); | 8214 AddInstruction(call); |
8211 if (!ast_context()->IsEffect()) Push(call); | 8215 if (!ast_context()->IsEffect()) Push(call); |
8212 Goto(join); | 8216 Goto(join); |
8213 } else { | 8217 } else { |
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9702 } | 9706 } |
9703 if (TryInlineApiMethodCall(expr, receiver, maps)) return; | 9707 if (TryInlineApiMethodCall(expr, receiver, maps)) return; |
9704 | 9708 |
9705 // Wrap the receiver if necessary. | 9709 // Wrap the receiver if necessary. |
9706 if (NeedsWrapping(maps->first(), known_function)) { | 9710 if (NeedsWrapping(maps->first(), known_function)) { |
9707 // Since HWrapReceiver currently cannot actually wrap numbers and | 9711 // Since HWrapReceiver currently cannot actually wrap numbers and |
9708 // strings, use the regular CallFunctionStub for method calls to wrap | 9712 // strings, use the regular CallFunctionStub for method calls to wrap |
9709 // the receiver. | 9713 // the receiver. |
9710 // TODO(verwaest): Support creation of value wrappers directly in | 9714 // TODO(verwaest): Support creation of value wrappers directly in |
9711 // HWrapReceiver. | 9715 // HWrapReceiver. |
9712 call = New<HCallFunction>(function, argument_count); | 9716 call = New<HCallFunction>(function, argument_count, |
| 9717 ConvertReceiverMode::kNotNullOrUndefined); |
9713 } else if (TryInlineCall(expr)) { | 9718 } else if (TryInlineCall(expr)) { |
9714 return; | 9719 return; |
9715 } else { | 9720 } else { |
9716 call = BuildCallConstantFunction(known_function, argument_count); | 9721 call = BuildCallConstantFunction(known_function, argument_count); |
9717 } | 9722 } |
9718 | 9723 |
9719 } else { | 9724 } else { |
9720 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; | 9725 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
9721 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { | 9726 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { |
9722 // We have to use EAGER deoptimization here because Deoptimizer::SOFT | 9727 // We have to use EAGER deoptimization here because Deoptimizer::SOFT |
9723 // gets ignored by the always-opt flag, which leads to incorrect code. | 9728 // gets ignored by the always-opt flag, which leads to incorrect code. |
9724 Add<HDeoptimize>( | 9729 Add<HDeoptimize>( |
9725 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, | 9730 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, |
9726 Deoptimizer::EAGER); | 9731 Deoptimizer::EAGER); |
9727 arguments_flag = ARGUMENTS_FAKED; | 9732 arguments_flag = ARGUMENTS_FAKED; |
9728 } | 9733 } |
9729 | 9734 |
9730 // Push the function under the receiver. | 9735 // Push the function under the receiver. |
9731 environment()->SetExpressionStackAt(0, function); | 9736 environment()->SetExpressionStackAt(0, function); |
9732 Push(receiver); | 9737 Push(receiver); |
9733 | 9738 |
9734 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); | 9739 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
9735 call = New<HCallFunction>(function, argument_count); | 9740 call = New<HCallFunction>(function, argument_count, |
| 9741 ConvertReceiverMode::kNotNullOrUndefined); |
9736 } | 9742 } |
9737 PushArgumentsFromEnvironment(argument_count); | 9743 PushArgumentsFromEnvironment(argument_count); |
9738 | 9744 |
9739 } else { | 9745 } else { |
9740 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9746 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
9741 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9747 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
9742 return Bailout(kPossibleDirectCallToEval); | 9748 return Bailout(kPossibleDirectCallToEval); |
9743 } | 9749 } |
9744 | 9750 |
9745 // The function is on the stack in the unoptimized code during | 9751 // The function is on the stack in the unoptimized code during |
(...skipping 29 matching lines...) Expand all Loading... |
9775 return; | 9781 return; |
9776 } | 9782 } |
9777 if (TryInlineApiFunctionCall(expr, receiver)) return; | 9783 if (TryInlineApiFunctionCall(expr, receiver)) return; |
9778 if (TryHandleArrayCall(expr, function)) return; | 9784 if (TryHandleArrayCall(expr, function)) return; |
9779 if (TryInlineCall(expr)) return; | 9785 if (TryInlineCall(expr)) return; |
9780 | 9786 |
9781 PushArgumentsFromEnvironment(argument_count); | 9787 PushArgumentsFromEnvironment(argument_count); |
9782 call = BuildCallConstantFunction(expr->target(), argument_count); | 9788 call = BuildCallConstantFunction(expr->target(), argument_count); |
9783 } else { | 9789 } else { |
9784 PushArgumentsFromEnvironment(argument_count); | 9790 PushArgumentsFromEnvironment(argument_count); |
9785 HCallFunction* call_function = | 9791 HCallFunction* call_function = New<HCallFunction>( |
9786 New<HCallFunction>(function, argument_count); | 9792 function, argument_count, ConvertReceiverMode::kNullOrUndefined); |
9787 call = call_function; | 9793 call = call_function; |
9788 if (expr->is_uninitialized() && | 9794 if (expr->is_uninitialized() && |
9789 expr->IsUsingCallFeedbackICSlot(isolate())) { | 9795 expr->IsUsingCallFeedbackICSlot(isolate())) { |
9790 // We've never seen this call before, so let's have Crankshaft learn | 9796 // We've never seen this call before, so let's have Crankshaft learn |
9791 // through the type vector. | 9797 // through the type vector. |
9792 Handle<TypeFeedbackVector> vector = | 9798 Handle<TypeFeedbackVector> vector = |
9793 handle(current_feedback_vector(), isolate()); | 9799 handle(current_feedback_vector(), isolate()); |
9794 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); | 9800 FeedbackVectorSlot slot = expr->CallFeedbackICSlot(); |
9795 call_function->SetVectorAndSlot(vector, slot); | 9801 call_function->SetVectorAndSlot(vector, slot); |
9796 } | 9802 } |
(...skipping 3835 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 |