Chromium Code Reviews| Index: src/crankshaft/hydrogen.cc |
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc |
| index 0b1dacec1a8caf6cb46325554f8a98d78e78ed22..0d0fe0c6a76b848fb41b0155bcfe94a7211bd17c 100644 |
| --- a/src/crankshaft/hydrogen.cc |
| +++ b/src/crankshaft/hydrogen.cc |
| @@ -4111,7 +4111,7 @@ AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
| typeof_mode_(NOT_INSIDE_TYPEOF) { |
| owner->set_ast_context(this); // Push. |
| #ifdef DEBUG |
| - DCHECK(owner->environment()->frame_type() == JS_FUNCTION); |
| + DCHECK_EQ(JS_FUNCTION, owner->environment()->frame_type()); |
| original_length_ = owner->environment()->length(); |
| #endif |
| } |
| @@ -4123,18 +4123,18 @@ AstContext::~AstContext() { |
| EffectContext::~EffectContext() { |
| - DCHECK(owner()->HasStackOverflow() || |
| - owner()->current_block() == NULL || |
| + DCHECK(owner()->HasStackOverflow() || owner()->current_block() == NULL || |
| (owner()->environment()->length() == original_length_ && |
| - owner()->environment()->frame_type() == JS_FUNCTION)); |
| + (owner()->environment()->frame_type() == JS_FUNCTION || |
| + owner()->environment()->frame_type() == TAIL_CALLER_FUNCTION))); |
| } |
| ValueContext::~ValueContext() { |
| - DCHECK(owner()->HasStackOverflow() || |
| - owner()->current_block() == NULL || |
| + DCHECK(owner()->HasStackOverflow() || owner()->current_block() == NULL || |
| (owner()->environment()->length() == original_length_ + 1 && |
| - owner()->environment()->frame_type() == JS_FUNCTION)); |
| + (owner()->environment()->frame_type() == JS_FUNCTION || |
| + owner()->environment()->frame_type() == TAIL_CALLER_FUNCTION))); |
| } |
| @@ -8339,11 +8339,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
| if (nodes_added == kNotInlinable) return false; |
| Handle<JSFunction> caller = current_info()->closure(); |
| - if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
| - TraceInline(target, caller, "call is at tail position"); |
| - return false; |
| - } |
| - |
| if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
| TraceInline(target, caller, "target AST is too large [early]"); |
| return false; |
| @@ -8510,12 +8505,9 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
| HConstant* undefined = graph()->GetConstantUndefined(); |
| - HEnvironment* inner_env = |
| - environment()->CopyForInlining(target, |
| - arguments_count, |
| - function, |
| - undefined, |
| - function_state()->inlining_kind()); |
| + HEnvironment* inner_env = environment()->CopyForInlining( |
| + target, arguments_count, function, undefined, |
| + function_state()->inlining_kind(), syntactic_tail_call_mode); |
| HConstant* context = Add<HConstant>(Handle<Context>(target->context())); |
| inner_env->BindContext(context); |
| @@ -8545,10 +8537,10 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
| current_block()->UpdateEnvironment(inner_env); |
| Scope* saved_scope = scope(); |
| set_scope(target_info.scope()); |
| - HEnterInlined* enter_inlined = |
| - Add<HEnterInlined>(return_id, target, context, arguments_count, function, |
| - function_state()->inlining_kind(), |
| - function->scope()->arguments(), arguments_object); |
| + HEnterInlined* enter_inlined = Add<HEnterInlined>( |
| + return_id, target, context, arguments_count, function, |
| + function_state()->inlining_kind(), function->scope()->arguments(), |
| + arguments_object, syntactic_tail_call_mode); |
| if (top_info()->is_tracking_positions()) { |
| enter_inlined->set_inlining_id(inlining_id); |
| } |
| @@ -9234,9 +9226,6 @@ bool HOptimizedGraphBuilder::TryInlineApiCall( |
| top_info()->closure()->context()->native_context()) { |
| return false; |
| } |
| - if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
| - return false; |
| - } |
| if (argc > CallApiCallbackStub::kArgMax) { |
| return false; |
| } |
| @@ -9344,14 +9333,16 @@ bool HOptimizedGraphBuilder::TryInlineApiCall( |
| HConstant* code_value = Add<HConstant>(code); |
| call = New<HCallWithDescriptor>( |
| code_value, argc + 1, stub.GetCallInterfaceDescriptor(), |
| - Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); |
| + Vector<HValue*>(op_vals, arraysize(op_vals) - 1), |
| + syntactic_tail_call_mode); |
| } else { |
| CallApiCallbackStub stub(isolate(), argc, call_data_undefined); |
| Handle<Code> code = stub.GetCode(); |
| HConstant* code_value = Add<HConstant>(code); |
| call = New<HCallWithDescriptor>( |
| code_value, argc + 1, stub.GetCallInterfaceDescriptor(), |
| - Vector<HValue*>(op_vals, arraysize(op_vals) - 1)); |
| + Vector<HValue*>(op_vals, arraysize(op_vals) - 1), |
| + syntactic_tail_call_mode); |
| Drop(1); // Drop function. |
| } |
| @@ -13122,14 +13113,20 @@ HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
| return new_env; |
| } |
| +void HEnvironment::MarkAsTailCaller() { |
| + DCHECK_EQ(JS_FUNCTION, frame_type()); |
| + // Drop potential outer arguments adaptor frame and update frame type. |
| + if (outer() != nullptr && outer()->frame_type() == ARGUMENTS_ADAPTOR) { |
| + outer_ = outer()->outer(); |
|
Igor Sheludko
2016/03/22 14:08:37
This was the source of try-bot redness. I'll drop
|
| + } |
| + frame_type_ = TAIL_CALLER_FUNCTION; |
| +} |
| HEnvironment* HEnvironment::CopyForInlining( |
| - Handle<JSFunction> target, |
| - int arguments, |
| - FunctionLiteral* function, |
| - HConstant* undefined, |
| - InliningKind inlining_kind) const { |
| - DCHECK(frame_type() == JS_FUNCTION); |
| + Handle<JSFunction> target, int arguments, FunctionLiteral* function, |
| + HConstant* undefined, InliningKind inlining_kind, |
| + TailCallMode syntactic_tail_call_mode) const { |
| + DCHECK_EQ(JS_FUNCTION, frame_type()); |
| // Outer environment is a copy of this one without the arguments. |
| int arity = function->scope()->num_parameters(); |
| @@ -13151,6 +13148,11 @@ HEnvironment* HEnvironment::CopyForInlining( |
| // We need an additional StackFrame::INTERNAL frame for temporarily saving |
| // the argument of the setter, see StoreStubCompiler::CompileStoreViaSetter. |
| outer = CreateStubEnvironment(outer, target, JS_SETTER, arguments); |
| + } else { |
| + DCHECK_EQ(NORMAL_RETURN, inlining_kind); |
| + if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
|
Michael Starzinger
2016/03/21 14:06:50
Can we either add a DCHECK to the other {inlining_
Igor Sheludko
2016/03/22 14:08:37
Done.
|
| + outer->MarkAsTailCaller(); |
| + } |
| } |
| if (arity != arguments) { |