Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 003f4aefeee384ae8847cb3ece5576d56adce4ec..942b3a80859de92e8db71c7e8c535951df2e1993 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -4074,8 +4074,12 @@ void EffectContext::ReturnValue(HValue* value) { |
| void ValueContext::ReturnValue(HValue* value) { |
| // The value is tracked in the bailout environment, and communicated |
| // through the environment as the result of the expression. |
| - if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { |
| - owner()->Bailout(kBadValueContextForArgumentsValue); |
| + if (value->CheckFlag(HValue::kIsArguments)) { |
| + if (flag_ == ARGUMENTS_FAKED) { |
| + value = owner()->graph()->GetConstantUndefined(); |
| + } else if (!arguments_allowed()) { |
| + owner()->Bailout(kBadValueContextForArgumentsValue); |
| + } |
| } |
| owner()->Push(value); |
| } |
| @@ -4301,6 +4305,14 @@ void HOptimizedGraphBuilder::VisitExpressions( |
| } |
| +void HOptimizedGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs, |
| + ArgumentsAllowedFlag flag) { |
| + for (int i = 0; i < exprs->length(); ++i) { |
| + CHECK_ALIVE(VisitForValue(exprs->at(i), flag)); |
| + } |
| +} |
| + |
| + |
| bool HOptimizedGraphBuilder::BuildGraph() { |
| if (current_info()->function()->is_generator()) { |
| Bailout(kFunctionIsAGenerator); |
| @@ -8885,13 +8897,8 @@ bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) { |
| // is supported. |
| if (current_info()->scope()->arguments() == NULL) return false; |
| - ZoneList<Expression*>* args = expr->arguments(); |
| - if (args->length() != 2) return false; |
| + if (!CanBeFunctionApplyArguments(expr, true)) return false; |
| - VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
| - if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
| - HValue* arg_two_value = LookupAndMakeLive(arg_two->var()); |
| - if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
| BuildFunctionApply(expr); |
| return true; |
| } |
| @@ -9178,6 +9185,20 @@ bool HOptimizedGraphBuilder::TryHandleArrayCallNew(CallNew* expr, |
| } |
| +bool HOptimizedGraphBuilder::CanBeFunctionApplyArguments( |
| + Call* expr, bool mark_arguments_as_live) { |
| + ZoneList<Expression*>* args = expr->arguments(); |
| + if (args->length() != 2) return false; |
| + VariableProxy* arg_two = args->at(1)->AsVariableProxy(); |
| + if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; |
| + HValue* arg_two_value = mark_arguments_as_live |
| + ? LookupAndMakeLive(arg_two->var()) |
| + : Lookup(arg_two->var()); |
| + if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; |
| + return true; |
| +} |
| + |
| + |
| void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| DCHECK(!HasStackOverflow()); |
| DCHECK(current_block() != NULL); |
| @@ -9214,13 +9235,14 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| - // Push the function under the receiver. |
| - environment()->SetExpressionStackAt(0, function); |
| - Push(receiver); |
| if (function->IsConstant() && |
| HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| + // Push the function under the receiver. |
| + environment()->SetExpressionStackAt(0, function); |
| + Push(receiver); |
| + |
| Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| HConstant::cast(function)->handle(isolate())); |
| expr->set_target(known_function); |
| @@ -9256,7 +9278,18 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
| } |
| } else { |
| - CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| + ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| + if (CanBeFunctionApplyArguments(expr, false)) { |
|
Jakob Kummerow
2014/11/19 20:46:16
I'm not too happy with this condition. It lacks a
Jakob Kummerow
2014/11/20 09:59:15
I've talked to mvstanton@, he suggested to impleme
ulan
2014/11/20 15:23:29
Done.
ulan
2014/11/20 15:23:29
Acknowledged.
|
| + Add<HDeoptimize>("Insufficient type feedback for call with arguments", |
| + Deoptimizer::EAGER); |
|
Jakob Kummerow
2014/11/19 20:46:16
If we find an appropriate check for "no type feedb
ulan
2014/11/20 15:23:29
Done.
|
| + arguments_flag = ARGUMENTS_FAKED; |
| + } |
| + |
| + // Push the function under the receiver. |
| + environment()->SetExpressionStackAt(0, function); |
| + Push(receiver); |
| + |
| + CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
| CallFunctionFlags flags = receiver->type().IsJSObject() |
| ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD; |
| call = New<HCallFunction>(function, argument_count, flags); |