[crankshaft] Support inlining of function calls in tail position (in ES6 sense).
BUG=v8:4698 LOG=N TBR=bmeurer@chromium.org Review URL: https://codereview.chromium.org/1782743003 Cr-Commit-Position: refs/heads/master@{#34992}
This commit is contained in:
parent
9383d14b9f
commit
df694d5524
@ -2498,11 +2498,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -1425,11 +1425,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if ((instr->arguments_var() != NULL) &&
|
||||
instr->arguments_object()->IsLinked()) {
|
||||
|
@ -1939,10 +1939,12 @@ class HEnterInlined final : public HTemplateInstruction<0> {
|
||||
HConstant* closure_context, int arguments_count,
|
||||
FunctionLiteral* function,
|
||||
InliningKind inlining_kind, Variable* arguments_var,
|
||||
HArgumentsObject* arguments_object) {
|
||||
return new (zone) HEnterInlined(return_id, closure, closure_context,
|
||||
arguments_count, function, inlining_kind,
|
||||
arguments_var, arguments_object, zone);
|
||||
HArgumentsObject* arguments_object,
|
||||
TailCallMode syntactic_tail_call_mode) {
|
||||
return new (zone)
|
||||
HEnterInlined(return_id, closure, closure_context, arguments_count,
|
||||
function, inlining_kind, arguments_var, arguments_object,
|
||||
syntactic_tail_call_mode, zone);
|
||||
}
|
||||
|
||||
void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
|
||||
@ -1958,6 +1960,9 @@ class HEnterInlined final : public HTemplateInstruction<0> {
|
||||
void set_arguments_pushed() { arguments_pushed_ = true; }
|
||||
FunctionLiteral* function() const { return function_; }
|
||||
InliningKind inlining_kind() const { return inlining_kind_; }
|
||||
TailCallMode syntactic_tail_call_mode() const {
|
||||
return syntactic_tail_call_mode_;
|
||||
}
|
||||
BailoutId ReturnId() const { return return_id_; }
|
||||
int inlining_id() const { return inlining_id_; }
|
||||
void set_inlining_id(int inlining_id) { inlining_id_ = inlining_id; }
|
||||
@ -1976,7 +1981,7 @@ class HEnterInlined final : public HTemplateInstruction<0> {
|
||||
HConstant* closure_context, int arguments_count,
|
||||
FunctionLiteral* function, InliningKind inlining_kind,
|
||||
Variable* arguments_var, HArgumentsObject* arguments_object,
|
||||
Zone* zone)
|
||||
TailCallMode syntactic_tail_call_mode, Zone* zone)
|
||||
: return_id_(return_id),
|
||||
shared_(handle(closure->shared())),
|
||||
closure_(closure),
|
||||
@ -1985,6 +1990,7 @@ class HEnterInlined final : public HTemplateInstruction<0> {
|
||||
arguments_pushed_(false),
|
||||
function_(function),
|
||||
inlining_kind_(inlining_kind),
|
||||
syntactic_tail_call_mode_(syntactic_tail_call_mode),
|
||||
inlining_id_(0),
|
||||
arguments_var_(arguments_var),
|
||||
arguments_object_(arguments_object),
|
||||
@ -1998,6 +2004,7 @@ class HEnterInlined final : public HTemplateInstruction<0> {
|
||||
bool arguments_pushed_;
|
||||
FunctionLiteral* function_;
|
||||
InliningKind inlining_kind_;
|
||||
TailCallMode syntactic_tail_call_mode_;
|
||||
int inlining_id_;
|
||||
Variable* arguments_var_;
|
||||
HArgumentsObject* arguments_object_;
|
||||
|
@ -4114,7 +4114,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
|
||||
}
|
||||
@ -4126,18 +4126,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)));
|
||||
}
|
||||
|
||||
|
||||
@ -8368,11 +8368,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;
|
||||
@ -8530,12 +8525,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);
|
||||
@ -8565,10 +8557,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);
|
||||
}
|
||||
@ -9254,9 +9246,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;
|
||||
}
|
||||
@ -9364,14 +9353,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.
|
||||
}
|
||||
|
||||
@ -13197,14 +13188,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();
|
||||
@ -13213,6 +13206,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
|
||||
|
@ -501,10 +501,10 @@ enum FrameType {
|
||||
JS_GETTER,
|
||||
JS_SETTER,
|
||||
ARGUMENTS_ADAPTOR,
|
||||
TAIL_CALLER_FUNCTION,
|
||||
STUB
|
||||
};
|
||||
|
||||
|
||||
class HEnvironment final : public ZoneObject {
|
||||
public:
|
||||
HEnvironment(HEnvironment* outer,
|
||||
@ -613,15 +613,17 @@ class HEnvironment final : public ZoneObject {
|
||||
// Create an "inlined version" of this environment, where the original
|
||||
// environment is the outer environment but the top expression stack
|
||||
// elements are moved to an inner environment as parameters.
|
||||
HEnvironment* CopyForInlining(Handle<JSFunction> target,
|
||||
int arguments,
|
||||
FunctionLiteral* function,
|
||||
HConstant* undefined,
|
||||
InliningKind inlining_kind) const;
|
||||
HEnvironment* CopyForInlining(Handle<JSFunction> target, int arguments,
|
||||
FunctionLiteral* function, HConstant* undefined,
|
||||
InliningKind inlining_kind,
|
||||
TailCallMode syntactic_tail_call_mode) const;
|
||||
|
||||
HEnvironment* DiscardInlined(bool drop_extra) {
|
||||
HEnvironment* outer = outer_;
|
||||
while (outer->frame_type() != JS_FUNCTION) outer = outer->outer_;
|
||||
while (outer->frame_type() != JS_FUNCTION &&
|
||||
outer->frame_type() != TAIL_CALLER_FUNCTION) {
|
||||
outer = outer->outer_;
|
||||
}
|
||||
if (drop_extra) outer->Drop(1);
|
||||
return outer;
|
||||
}
|
||||
@ -680,6 +682,10 @@ class HEnvironment final : public ZoneObject {
|
||||
FrameType frame_type,
|
||||
int arguments) const;
|
||||
|
||||
// Marks current environment as tail caller by setting frame type to
|
||||
// TAIL_CALLER_FUNCTION.
|
||||
void MarkAsTailCaller();
|
||||
|
||||
// True if index is included in the expression stack part of the environment.
|
||||
bool HasExpressionAt(int index) const;
|
||||
|
||||
@ -1278,6 +1284,26 @@ class HGraphBuilder {
|
||||
return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8));
|
||||
}
|
||||
|
||||
template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
|
||||
class P7, class P8, class P9>
|
||||
I* New(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
|
||||
return I::New(isolate(), zone(), context(), p1, p2, p3, p4, p5, p6, p7, p8,
|
||||
p9);
|
||||
}
|
||||
|
||||
template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
|
||||
class P7, class P8, class P9>
|
||||
HInstruction* AddUncasted(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7,
|
||||
P8 p8, P9 p9) {
|
||||
return AddInstruction(NewUncasted<I>(p1, p2, p3, p4, p5, p6, p7, p8, p8));
|
||||
}
|
||||
|
||||
template <class I, class P1, class P2, class P3, class P4, class P5, class P6,
|
||||
class P7, class P8, class P9>
|
||||
I* Add(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
|
||||
return AddInstructionTyped(New<I>(p1, p2, p3, p4, p5, p6, p7, p8, p9));
|
||||
}
|
||||
|
||||
void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
|
||||
|
||||
// When initializing arrays, we'll unfold the loop if the number of elements
|
||||
|
@ -2551,11 +2551,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -240,8 +240,8 @@ void LCodeGenBase::WriteTranslationFrame(LEnvironment* environment,
|
||||
break;
|
||||
}
|
||||
case JS_GETTER: {
|
||||
DCHECK(translation_size == 1);
|
||||
DCHECK(height == 0);
|
||||
DCHECK_EQ(1, translation_size);
|
||||
DCHECK_EQ(0, height);
|
||||
int shared_id = DefineDeoptimizationLiteral(
|
||||
environment->entry() ? environment->entry()->shared()
|
||||
: info()->shared_info());
|
||||
@ -255,8 +255,8 @@ void LCodeGenBase::WriteTranslationFrame(LEnvironment* environment,
|
||||
break;
|
||||
}
|
||||
case JS_SETTER: {
|
||||
DCHECK(translation_size == 2);
|
||||
DCHECK(height == 0);
|
||||
DCHECK_EQ(2, translation_size);
|
||||
DCHECK_EQ(0, height);
|
||||
int shared_id = DefineDeoptimizationLiteral(
|
||||
environment->entry() ? environment->entry()->shared()
|
||||
: info()->shared_info());
|
||||
@ -269,6 +269,20 @@ void LCodeGenBase::WriteTranslationFrame(LEnvironment* environment,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TAIL_CALLER_FUNCTION: {
|
||||
DCHECK_EQ(0, translation_size);
|
||||
int shared_id = DefineDeoptimizationLiteral(
|
||||
environment->entry() ? environment->entry()->shared()
|
||||
: info()->shared_info());
|
||||
translation->BeginTailCallerFrame(shared_id);
|
||||
if (info()->closure().is_identical_to(environment->closure())) {
|
||||
translation->StoreJSFrameFunction();
|
||||
} else {
|
||||
int closure_id = DefineDeoptimizationLiteral(environment->closure());
|
||||
translation->StoreLiteral(closure_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARGUMENTS_ADAPTOR: {
|
||||
int shared_id = DefineDeoptimizationLiteral(
|
||||
environment->entry() ? environment->entry()->shared()
|
||||
|
@ -522,12 +522,28 @@ LEnvironment* LChunkBuilderBase::CreateEnvironment(
|
||||
ZoneList<HValue*>* objects_to_materialize) {
|
||||
if (hydrogen_env == NULL) return NULL;
|
||||
|
||||
BailoutId ast_id = hydrogen_env->ast_id();
|
||||
DCHECK(!ast_id.IsNone() ||
|
||||
(hydrogen_env->frame_type() != JS_FUNCTION &&
|
||||
hydrogen_env->frame_type() != TAIL_CALLER_FUNCTION));
|
||||
|
||||
if (hydrogen_env->frame_type() == TAIL_CALLER_FUNCTION) {
|
||||
// Skip potential outer arguments adaptor frame.
|
||||
HEnvironment* outer_hydrogen_env = hydrogen_env->outer();
|
||||
if (outer_hydrogen_env != nullptr &&
|
||||
outer_hydrogen_env->frame_type() == ARGUMENTS_ADAPTOR) {
|
||||
outer_hydrogen_env = outer_hydrogen_env->outer();
|
||||
}
|
||||
LEnvironment* outer = CreateEnvironment(
|
||||
outer_hydrogen_env, argument_index_accumulator, objects_to_materialize);
|
||||
return new (zone())
|
||||
LEnvironment(hydrogen_env->closure(), hydrogen_env->frame_type(),
|
||||
ast_id, 0, 0, 0, outer, hydrogen_env->entry(), zone());
|
||||
}
|
||||
|
||||
LEnvironment* outer =
|
||||
CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator,
|
||||
objects_to_materialize);
|
||||
BailoutId ast_id = hydrogen_env->ast_id();
|
||||
DCHECK(!ast_id.IsNone() ||
|
||||
hydrogen_env->frame_type() != JS_FUNCTION);
|
||||
|
||||
int omitted_count = (hydrogen_env->frame_type() == JS_FUNCTION)
|
||||
? 0
|
||||
|
@ -2445,11 +2445,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -2450,11 +2450,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -2430,7 +2430,7 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind());
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -2236,7 +2236,7 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind());
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -2553,11 +2553,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
@ -2556,11 +2556,9 @@ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
|
||||
HEnvironment* outer = current_block_->last_environment();
|
||||
outer->set_ast_id(instr->ReturnId());
|
||||
HConstant* undefined = graph()->GetConstantUndefined();
|
||||
HEnvironment* inner = outer->CopyForInlining(instr->closure(),
|
||||
instr->arguments_count(),
|
||||
instr->function(),
|
||||
undefined,
|
||||
instr->inlining_kind());
|
||||
HEnvironment* inner = outer->CopyForInlining(
|
||||
instr->closure(), instr->arguments_count(), instr->function(), undefined,
|
||||
instr->inlining_kind(), instr->syntactic_tail_call_mode());
|
||||
// Only replay binding of arguments object if it wasn't removed from graph.
|
||||
if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
|
||||
inner->Bind(instr->arguments_var(), instr->arguments_object());
|
||||
|
Loading…
Reference in New Issue
Block a user