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

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: ppc, s390 and x87 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
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/crankshaft/hydrogen.cc
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
index 0b1dacec1a8caf6cb46325554f8a98d78e78ed22..306b6a72883f3d0111b1e9a8f6e34490a9936129 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,16 @@ HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer,
return new_env;
}
+void HEnvironment::MarkAsTailCaller() {
+ DCHECK_EQ(JS_FUNCTION, frame_type());
+ 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();
@@ -13138,6 +13131,11 @@ HEnvironment* HEnvironment::CopyForInlining(
outer->Drop(arguments + 1); // Including receiver.
outer->ClearHistory();
+ if (syntactic_tail_call_mode == TailCallMode::kAllow) {
+ DCHECK_EQ(NORMAL_RETURN, inlining_kind);
+ outer->MarkAsTailCaller();
+ }
+
if (inlining_kind == CONSTRUCT_CALL_RETURN) {
// Create artificial constructor stub environment. The receiver should
// actually be the constructor function, but we pass the newly allocated
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/crankshaft/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698