| 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, WRAP_AND_CALL); | 6592 return New<HCallFunction>(function, argument_count); |
| 6593 } else if (FLAG_inline_accessors && can_inline_accessor) { | 6593 } else if (FLAG_inline_accessors && can_inline_accessor) { |
| 6594 bool success = info->IsLoad() | 6594 bool success = info->IsLoad() |
| 6595 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) | 6595 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) |
| 6596 : TryInlineSetter( | 6596 : TryInlineSetter( |
| 6597 info->accessor(), info->map(), ast_id, return_id, value); | 6597 info->accessor(), info->map(), ast_id, return_id, value); |
| 6598 if (success || HasStackOverflow()) return NULL; | 6598 if (success || HasStackOverflow()) return NULL; |
| 6599 } | 6599 } |
| 6600 | 6600 |
| 6601 PushArgumentsFromEnvironment(argument_count); | 6601 PushArgumentsFromEnvironment(argument_count); |
| 6602 return BuildCallConstantFunction(info->accessor(), argument_count); | 6602 return BuildCallConstantFunction(info->accessor(), argument_count); |
| (...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8162 } | 8162 } |
| 8163 if (try_inline && TryInlineCall(expr)) { | 8163 if (try_inline && TryInlineCall(expr)) { |
| 8164 // Trying to inline will signal that we should bailout from the | 8164 // Trying to inline will signal that we should bailout from the |
| 8165 // entire compilation by setting stack overflow on the visitor. | 8165 // entire compilation by setting stack overflow on the visitor. |
| 8166 if (HasStackOverflow()) return; | 8166 if (HasStackOverflow()) return; |
| 8167 } else { | 8167 } else { |
| 8168 // Since HWrapReceiver currently cannot actually wrap numbers and strings, | 8168 // Since HWrapReceiver currently cannot actually wrap numbers and strings, |
| 8169 // use the regular CallFunctionStub for method calls to wrap the receiver. | 8169 // use the regular CallFunctionStub for method calls to wrap the receiver. |
| 8170 // TODO(verwaest): Support creation of value wrappers directly in | 8170 // TODO(verwaest): Support creation of value wrappers directly in |
| 8171 // HWrapReceiver. | 8171 // HWrapReceiver. |
| 8172 HInstruction* call = needs_wrapping | 8172 HInstruction* call = |
| 8173 ? NewUncasted<HCallFunction>( | 8173 needs_wrapping ? NewUncasted<HCallFunction>(function, argument_count) |
| 8174 function, argument_count, WRAP_AND_CALL) | 8174 : BuildCallConstantFunction(target, argument_count); |
| 8175 : BuildCallConstantFunction(target, argument_count); | |
| 8176 PushArgumentsFromEnvironment(argument_count); | 8175 PushArgumentsFromEnvironment(argument_count); |
| 8177 AddInstruction(call); | 8176 AddInstruction(call); |
| 8178 Drop(1); // Drop the function. | 8177 Drop(1); // Drop the function. |
| 8179 if (!ast_context()->IsEffect()) Push(call); | 8178 if (!ast_context()->IsEffect()) Push(call); |
| 8180 } | 8179 } |
| 8181 | 8180 |
| 8182 if (current_block() != NULL) Goto(join); | 8181 if (current_block() != NULL) Goto(join); |
| 8183 set_current_block(if_false); | 8182 set_current_block(if_false); |
| 8184 } | 8183 } |
| 8185 | 8184 |
| 8186 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 8185 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 8187 // know about and do not want to handle ones we've never seen. Otherwise | 8186 // know about and do not want to handle ones we've never seen. Otherwise |
| 8188 // use a generic IC. | 8187 // use a generic IC. |
| 8189 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { | 8188 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { |
| 8190 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); | 8189 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); |
| 8191 } else { | 8190 } else { |
| 8192 Property* prop = expr->expression()->AsProperty(); | 8191 Property* prop = expr->expression()->AsProperty(); |
| 8193 HInstruction* function = | 8192 HInstruction* function = |
| 8194 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, | 8193 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, |
| 8195 name, NULL, prop->IsUninitialized()); | 8194 name, NULL, prop->IsUninitialized()); |
| 8196 AddInstruction(function); | 8195 AddInstruction(function); |
| 8197 Push(function); | 8196 Push(function); |
| 8198 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 8197 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 8199 | 8198 |
| 8200 environment()->SetExpressionStackAt(1, function); | 8199 environment()->SetExpressionStackAt(1, function); |
| 8201 environment()->SetExpressionStackAt(0, receiver); | 8200 environment()->SetExpressionStackAt(0, receiver); |
| 8202 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8201 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8203 | 8202 |
| 8204 CallFunctionFlags flags = receiver->type().IsJSObject() | 8203 HInstruction* call = New<HCallFunction>(function, argument_count); |
| 8205 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | |
| 8206 HInstruction* call = New<HCallFunction>( | |
| 8207 function, argument_count, flags); | |
| 8208 | 8204 |
| 8209 PushArgumentsFromEnvironment(argument_count); | 8205 PushArgumentsFromEnvironment(argument_count); |
| 8210 | 8206 |
| 8211 Drop(1); // Function. | 8207 Drop(1); // Function. |
| 8212 | 8208 |
| 8213 if (join != NULL) { | 8209 if (join != NULL) { |
| 8214 AddInstruction(call); | 8210 AddInstruction(call); |
| 8215 if (!ast_context()->IsEffect()) Push(call); | 8211 if (!ast_context()->IsEffect()) Push(call); |
| 8216 Goto(join); | 8212 Goto(join); |
| 8217 } else { | 8213 } else { |
| (...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9700 } | 9696 } |
| 9701 if (TryInlineApiMethodCall(expr, receiver, maps)) return; | 9697 if (TryInlineApiMethodCall(expr, receiver, maps)) return; |
| 9702 | 9698 |
| 9703 // Wrap the receiver if necessary. | 9699 // Wrap the receiver if necessary. |
| 9704 if (NeedsWrapping(maps->first(), known_function)) { | 9700 if (NeedsWrapping(maps->first(), known_function)) { |
| 9705 // Since HWrapReceiver currently cannot actually wrap numbers and | 9701 // Since HWrapReceiver currently cannot actually wrap numbers and |
| 9706 // strings, use the regular CallFunctionStub for method calls to wrap | 9702 // strings, use the regular CallFunctionStub for method calls to wrap |
| 9707 // the receiver. | 9703 // the receiver. |
| 9708 // TODO(verwaest): Support creation of value wrappers directly in | 9704 // TODO(verwaest): Support creation of value wrappers directly in |
| 9709 // HWrapReceiver. | 9705 // HWrapReceiver. |
| 9710 call = New<HCallFunction>( | 9706 call = New<HCallFunction>(function, argument_count); |
| 9711 function, argument_count, WRAP_AND_CALL); | |
| 9712 } else if (TryInlineCall(expr)) { | 9707 } else if (TryInlineCall(expr)) { |
| 9713 return; | 9708 return; |
| 9714 } else { | 9709 } else { |
| 9715 call = BuildCallConstantFunction(known_function, argument_count); | 9710 call = BuildCallConstantFunction(known_function, argument_count); |
| 9716 } | 9711 } |
| 9717 | 9712 |
| 9718 } else { | 9713 } else { |
| 9719 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; | 9714 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| 9720 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { | 9715 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { |
| 9721 // We have to use EAGER deoptimization here because Deoptimizer::SOFT | 9716 // We have to use EAGER deoptimization here because Deoptimizer::SOFT |
| 9722 // gets ignored by the always-opt flag, which leads to incorrect code. | 9717 // gets ignored by the always-opt flag, which leads to incorrect code. |
| 9723 Add<HDeoptimize>( | 9718 Add<HDeoptimize>( |
| 9724 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, | 9719 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, |
| 9725 Deoptimizer::EAGER); | 9720 Deoptimizer::EAGER); |
| 9726 arguments_flag = ARGUMENTS_FAKED; | 9721 arguments_flag = ARGUMENTS_FAKED; |
| 9727 } | 9722 } |
| 9728 | 9723 |
| 9729 // Push the function under the receiver. | 9724 // Push the function under the receiver. |
| 9730 environment()->SetExpressionStackAt(0, function); | 9725 environment()->SetExpressionStackAt(0, function); |
| 9731 Push(receiver); | 9726 Push(receiver); |
| 9732 | 9727 |
| 9733 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); | 9728 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
| 9734 CallFunctionFlags flags = receiver->type().IsJSObject() | 9729 call = New<HCallFunction>(function, argument_count); |
| 9735 ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; | |
| 9736 call = New<HCallFunction>(function, argument_count, flags); | |
| 9737 } | 9730 } |
| 9738 PushArgumentsFromEnvironment(argument_count); | 9731 PushArgumentsFromEnvironment(argument_count); |
| 9739 | 9732 |
| 9740 } else { | 9733 } else { |
| 9741 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 9734 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 9742 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 9735 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
| 9743 return Bailout(kPossibleDirectCallToEval); | 9736 return Bailout(kPossibleDirectCallToEval); |
| 9744 } | 9737 } |
| 9745 | 9738 |
| 9746 // The function is on the stack in the unoptimized code during | 9739 // The function is on the stack in the unoptimized code during |
| (...skipping 3954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13701 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13694 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13702 } | 13695 } |
| 13703 | 13696 |
| 13704 #ifdef DEBUG | 13697 #ifdef DEBUG |
| 13705 graph_->Verify(false); // No full verify. | 13698 graph_->Verify(false); // No full verify. |
| 13706 #endif | 13699 #endif |
| 13707 } | 13700 } |
| 13708 | 13701 |
| 13709 } // namespace internal | 13702 } // namespace internal |
| 13710 } // namespace v8 | 13703 } // namespace v8 |
| OLD | NEW |