Mark the simulate before EnterInlined with BailoutId::None(), and set ReturnId on EnterInlined. When merging simulates into the simulate before enter-inlined, adopt the last AST id that gets merged into it.

BUG=v8:3282
LOG=n
R=titzer@chromium.org

Review URL: https://codereview.chromium.org/257583004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20949 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2014-04-24 15:20:53 +00:00
parent 2e0c29654c
commit a55821eef2
9 changed files with 52 additions and 8 deletions

View File

@ -2521,6 +2521,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
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(),

View File

@ -1454,6 +1454,7 @@ LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
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(),

View File

@ -2595,6 +2595,9 @@ void HPhi::AddIndirectUsesTo(int* dest) {
void HSimulate::MergeWith(ZoneList<HSimulate*>* list) {
if (!list->is_empty() && !HasAstId()) {
set_ast_id(list->last()->ast_id());
}
while (!list->is_empty()) {
HSimulate* from = list->RemoveLast();
ZoneList<HValue*>* from_values = &from->values_;
@ -4504,7 +4507,7 @@ void HPhi::Verify() {
void HSimulate::Verify() {
HInstruction::Verify();
ASSERT(HasAstId());
ASSERT(HasAstId() || next()->IsEnterInlined());
}

View File

@ -2085,14 +2085,15 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
public:
static HEnterInlined* New(Zone* zone,
HValue* context,
BailoutId return_id,
Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
InliningKind inlining_kind,
Variable* arguments_var,
HArgumentsObject* arguments_object) {
return new(zone) HEnterInlined(closure, arguments_count, function,
inlining_kind, arguments_var,
return new(zone) HEnterInlined(return_id, closure, arguments_count,
function, inlining_kind, arguments_var,
arguments_object, zone);
}
@ -2107,6 +2108,7 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
void set_arguments_pushed() { arguments_pushed_ = true; }
FunctionLiteral* function() const { return function_; }
InliningKind inlining_kind() const { return inlining_kind_; }
BailoutId ReturnId() const { return return_id_; }
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
return Representation::None();
@ -2118,14 +2120,16 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
private:
HEnterInlined(Handle<JSFunction> closure,
HEnterInlined(BailoutId return_id,
Handle<JSFunction> closure,
int arguments_count,
FunctionLiteral* function,
InliningKind inlining_kind,
Variable* arguments_var,
HArgumentsObject* arguments_object,
Zone* zone)
: closure_(closure),
: return_id_(return_id),
closure_(closure),
arguments_count_(arguments_count),
arguments_pushed_(false),
function_(function),
@ -2135,6 +2139,7 @@ class HEnterInlined V8_FINAL : public HTemplateInstruction<0> {
return_targets_(2, zone) {
}
BailoutId return_id_;
Handle<JSFunction> closure_;
int arguments_count_;
bool arguments_pushed_;

View File

@ -7383,8 +7383,6 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
inner_env->BindContext(context);
Add<HSimulate>(return_id);
current_block()->UpdateEnvironment(inner_env);
HArgumentsObject* arguments_object = NULL;
// If the function uses arguments object create and bind one, also copy
@ -7400,8 +7398,17 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
}
}
// Capture the state before invoking the inlined function for deopt in the
// inlined function. This simulate has no bailout-id since it's not directly
// reachable for deopt, and is only used to capture the state. If the simulate
// becomes reachable by merging, the ast id of the simulate merged into it is
// adopted.
Add<HSimulate>(BailoutId::None());
current_block()->UpdateEnvironment(inner_env);
HEnterInlined* enter_inlined =
Add<HEnterInlined>(target, arguments_count, function,
Add<HEnterInlined>(return_id, target, arguments_count, function,
function_state()->inlining_kind(),
function->scope()->arguments(),
arguments_object);

View File

@ -2658,6 +2658,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
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(),

View File

@ -2472,6 +2472,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
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(),

View File

@ -2546,6 +2546,7 @@ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
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(),

View File

@ -0,0 +1,24 @@
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
"use strict";
function f1(d) {
return 1 + f2(f3(d));
}
function f2(v) { return v; }
function f3(d) {
if (d) %DeoptimizeFunction(f1);
return 2;
}
%NeverOptimizeFunction(f3);
f1(false);
f1(false);
%OptimizeFunctionOnNextCall(f1);
assertEquals(3, f1(true));