Fix bugs in DeoptimizeIf when lazy deopt is requested.

This also implements --trap-on-deopt on x64 and simplifies the
implementation of this flag on all architectures.

R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13633 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a77daae9
......@@ -821,7 +821,7 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
ASSERT(environment->HasBeenRegistered());
int id = environment->deoptimization_index();
ASSERT(info()->IsOptimizing() || info()->IsStub());
Deoptimizer::BailoutType bailout_type = info()->IsStub()
? Deoptimizer::LAZY
: Deoptimizer::EAGER;
......@@ -832,18 +832,23 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
}
ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM.
if (FLAG_deopt_every_n_times == 1 && info_->opt_count() == id) {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
return;
}
if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc);
if (FLAG_trap_on_deopt) {
__ stop("trap_on_deopt", cc);
}
bool needs_lazy_deopt = info()->IsStub();
ASSERT(info()->IsStub() || frame_is_built_);
if (cc == al && !needs_lazy_deopt) {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
bool needs_lazy_deopt = info()->IsStub();
if (cc == al && frame_is_built_) {
if (needs_lazy_deopt) {
__ Call(entry, RelocInfo::RUNTIME_ENTRY);
} else {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
}
} else {
// We often have several deopts to the same entry, reuse the last
// jump entry if this is the case.
......
......@@ -860,44 +860,38 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
__ popfd();
}
if (FLAG_trap_on_deopt) {
Label done;
if (cc != no_condition) {
__ j(NegateCondition(cc), &done, Label::kNear);
}
__ int3();
__ bind(&done);
}
ASSERT(info()->IsStub() || frame_is_built_);
bool lazy_deopt_needed = info()->IsStub();
if (cc == no_condition) {
if (FLAG_trap_on_deopt) __ int3();
if (lazy_deopt_needed) {
bool needs_lazy_deopt = info()->IsStub();
if (cc == no_condition && frame_is_built_) {
if (needs_lazy_deopt) {
__ call(entry, RelocInfo::RUNTIME_ENTRY);
} else {
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
}
} else {
Label done;
if (FLAG_trap_on_deopt) {
__ j(NegateCondition(cc), &done, Label::kNear);
__ int3();
// We often have several deopts to the same entry, reuse the last
// jump entry if this is the case.
if (jump_table_.is_empty() ||
jump_table_.last().address != entry ||
jump_table_.last().needs_frame != !frame_is_built_ ||
jump_table_.last().is_lazy_deopt != needs_lazy_deopt) {
JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt);
jump_table_.Add(table_entry, zone());
}
if (!lazy_deopt_needed && frame_is_built_) {
if (FLAG_trap_on_deopt) {
__ jmp(entry, RelocInfo::RUNTIME_ENTRY);
} else {
__ j(cc, entry, RelocInfo::RUNTIME_ENTRY);
}
if (cc == no_condition) {
__ jmp(&jump_table_.last().label);
} else {
// We often have several deopts to the same entry, reuse the last
// jump entry if this is the case.
if (jump_table_.is_empty() ||
jump_table_.last().address != entry ||
jump_table_.last().needs_frame != !frame_is_built_ ||
jump_table_.last().is_lazy_deopt != lazy_deopt_needed) {
JumpTableEntry table_entry(entry, !frame_is_built_, lazy_deopt_needed);
jump_table_.Add(table_entry, zone());
}
if (FLAG_trap_on_deopt) {
__ jmp(&jump_table_.last().label);
} else {
__ j(cc, &jump_table_.last().label);
}
__ j(cc, &jump_table_.last().label);
}
__ bind(&done);
}
}
......
......@@ -719,10 +719,21 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
return;
}
ASSERT(FLAG_deopt_every_n_times == 0); // Not yet implemented on x64.
if (FLAG_trap_on_deopt) {
Label done;
if (cc != no_condition) {
__ j(NegateCondition(cc), &done, Label::kNear);
}
__ int3();
__ bind(&done);
}
ASSERT(info()->IsStub() || frame_is_built_);
bool lazy_deopt = info()->IsStub();
if (cc == no_condition) {
if (lazy_deopt) {
bool needs_lazy_deopt = info()->IsStub();
if (cc == no_condition && frame_is_built_) {
if (needs_lazy_deopt) {
__ Call(entry, RelocInfo::RUNTIME_ENTRY);
} else {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY);
......@@ -733,11 +744,15 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
if (jump_table_.is_empty() ||
jump_table_.last().address != entry ||
jump_table_.last().needs_frame != !frame_is_built_ ||
jump_table_.last().is_lazy_deopt != lazy_deopt) {
JumpTableEntry table_entry(entry, !frame_is_built_, lazy_deopt);
jump_table_.last().is_lazy_deopt != needs_lazy_deopt) {
JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt);
jump_table_.Add(table_entry, zone());
}
__ j(cc, &jump_table_.last().label);
if (cc == no_condition) {
__ jmp(&jump_table_.last().label);
} else {
__ j(cc, &jump_table_.last().label);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment