Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Unified Diff: src/crankshaft/hydrogen.cc

Issue 1782743003: [crankshaft] Support inlining of function calls in tail position (in ES6 sense). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@tco-crank-4
Patch Set: Other ports Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698