MIPS: Fix deoptimization entry table when branch cannot reach.
This fixes failures when table has more than 8192 entries, and preserves optimization to have 2 instructions per entry. TEST=mozilla/regress-398085-01 BUG= R=paul.lind@imgtec.com Review URL: https://codereview.chromium.org/477623002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
5c7edb7e2b
commit
6dee88849a
@ -324,22 +324,59 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
|
|||||||
|
|
||||||
// Create a sequence of deoptimization entries.
|
// Create a sequence of deoptimization entries.
|
||||||
// Note that registers are still live when jumping to an entry.
|
// Note that registers are still live when jumping to an entry.
|
||||||
Label table_start, done;
|
Label table_start, done, done_special, trampoline_jump;
|
||||||
__ bind(&table_start);
|
__ bind(&table_start);
|
||||||
for (int i = 0; i < count(); i++) {
|
int kMaxEntriesBranchReach = (1 << (kImm16Bits - 2))/
|
||||||
Label start;
|
(table_entry_size_ / Assembler::kInstrSize);
|
||||||
__ bind(&start);
|
|
||||||
DCHECK(is_int16(i));
|
|
||||||
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot.
|
|
||||||
__ li(at, i); // In the delay slot.
|
|
||||||
|
|
||||||
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start));
|
if (count() <= kMaxEntriesBranchReach) {
|
||||||
|
// Common case.
|
||||||
|
for (int i = 0; i < count(); i++) {
|
||||||
|
Label start;
|
||||||
|
__ bind(&start);
|
||||||
|
DCHECK(is_int16(i));
|
||||||
|
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot.
|
||||||
|
__ li(at, i); // In the delay slot.
|
||||||
|
|
||||||
|
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start));
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
|
||||||
|
count() * table_entry_size_);
|
||||||
|
__ bind(&done);
|
||||||
|
__ Push(at);
|
||||||
|
} else {
|
||||||
|
// Uncommon case, the branch cannot reach.
|
||||||
|
// Create mini trampoline and adjust id constants to get proper value at
|
||||||
|
// the end of table.
|
||||||
|
for (int i = kMaxEntriesBranchReach; i > 1; i--) {
|
||||||
|
Label start;
|
||||||
|
__ bind(&start);
|
||||||
|
DCHECK(is_int16(i));
|
||||||
|
__ Branch(USE_DELAY_SLOT, &trampoline_jump); // Expose delay slot.
|
||||||
|
__ li(at, - i); // In the delay slot.
|
||||||
|
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start));
|
||||||
|
}
|
||||||
|
// Entry with id == kMaxEntriesBranchReach - 1.
|
||||||
|
__ bind(&trampoline_jump);
|
||||||
|
__ Branch(USE_DELAY_SLOT, &done_special);
|
||||||
|
__ li(at, -1);
|
||||||
|
|
||||||
|
for (int i = kMaxEntriesBranchReach ; i < count(); i++) {
|
||||||
|
Label start;
|
||||||
|
__ bind(&start);
|
||||||
|
DCHECK(is_int16(i));
|
||||||
|
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot.
|
||||||
|
__ li(at, i); // In the delay slot.
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
|
||||||
|
count() * table_entry_size_);
|
||||||
|
__ bind(&done_special);
|
||||||
|
__ addiu(at, at, kMaxEntriesBranchReach);
|
||||||
|
__ bind(&done);
|
||||||
|
__ Push(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
|
|
||||||
count() * table_entry_size_);
|
|
||||||
__ bind(&done);
|
|
||||||
__ Push(at);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user